Created
August 13, 2017 22:03
-
-
Save mfdj/f5c2f4fb55baeefc66c757dfce05ee10 to your computer and use it in GitHub Desktop.
prove how to safely validate precision
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
set_error_handler(function($severity, $message, $filename, $lineno) { | |
throw new \Error($message, $severity); | |
}); | |
function strictAssert($expected, $actual) { | |
if ($actual !== $expected) { | |
echo PHP_EOL . '✋' . PHP_EOL; | |
var_dump($actual, $expected); | |
die; | |
} | |
} | |
function because(string $proposition, callable $test) { | |
echo "$proposition"; | |
try { | |
$test(); | |
} catch (\Throwable $e) { | |
echo PHP_EOL . $e->getMessage() . PHP_EOL; | |
die; | |
} | |
echo " 👍" . PHP_EOL; | |
} | |
echo 'Becasue …' . PHP_EOL; | |
because("commas in strings ruin float conversion", function() { | |
strictAssert( (float) '2000.45', 2000.45 ); | |
strictAssert( (float) '2,000.45', 2.0 ); | |
}); | |
because("weird types and values will actually coerce", function() { | |
strictAssert( (float) '', 0.0 ); | |
strictAssert( (float) '2,000.45', 2.0 ); | |
}); | |
because("floats compact leading and trailing zeros", function() { | |
strictAssert( (string) 1.100, '1.1' ); | |
strictAssert( (string) 00.35, '0.35' ); | |
}); | |
because("number_format coerces to float and will warn about some confusing values/types", function() { | |
// number_format considers bool|null to be safely coercible, though I find this to be an odd excecption | |
strictAssert( number_format(null, 2), '0.00' ); | |
strictAssert( number_format(false, 2), '0.00' ); | |
strictAssert( number_format(true, 2), '1.00' ); | |
// number_format warns about ambigous values | |
try { | |
$result = number_format(''); | |
} catch (\Throwable $e) { | |
strictAssert($e->getmessage(), 'number_format() expects parameter 1 to be float, string given'); | |
} | |
// note: warnings won't evaluate to a result | |
// also-note: typically warnings won't halt execution (tricky) | |
strictAssert(!isset($result), true); | |
try { | |
number_format('2,000.45'); | |
} catch (\Throwable $e) { | |
strictAssert($e->getmessage(), 'A non well formed numeric value encountered'); | |
} | |
try { | |
number_format([0,1,2]); | |
} catch (\Throwable $e) { | |
strictAssert($e->getmessage(), 'number_format() expects parameter 1 to be float, array given'); | |
} | |
}); | |
because("number_format will round based on precision", function() { | |
strictAssert( number_format(0.2349, 2), '0.23' ); | |
strictAssert( number_format(0.235, 2), '0.24' ); | |
}); | |
because("number_format will add commas", function() { | |
strictAssert( number_format(999, 2), '999.00' ); | |
strictAssert( number_format(1000, 2), '1,000.00' ); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment