-
Star
(111)
You must be signed in to star a gist -
Fork
(9)
You must be signed in to fork a gist
-
-
Save mathiasverraes/9046427 to your computer and use it in GitHub Desktop.
<?php | |
require_once 'TestFrameworkInATweet.php'; | |
it("should sum two numbers", 1+1==2); | |
it("should display an X for a failing test", 1+1==3); | |
done(); |
<?php | |
function it($m,$p){echo ($p?'✔︎':'✘')." It $m\n"; if(!$p){$GLOBALS['f']=1;}}function done(){if(@$GLOBALS['f'])die(1);} |
Multiple assertions in one go:
<?php
function all(array $ps){return array_reduce($ps,function($a,$p){return $a&&$p;},true);}
// usage
it("should do a bunch of calculations", all([
1+1 == 2,
1+2 == 1249,
]);
done();
Output:
✘ It should do a bunch of calculations
Process finished with exit code 1
Slightly shorter.
<?php
function all($ps){return $ps===array_filter($ps);}
it('should be shorter than Mathias\' proposal and still work', all([
strlen('function all($ps){return $ps===array_filter($ps);}') < strlen('function all(array $ps){return array_reduce($ps,function($a,$p){return $a&&$p;},true);}'),
1+1 === 2,
]));
done();
Schoolboy error there Sterling.
<?php
function all($a){return $a===array_filter($a);}
it('should be shorter than Sterling\'s proposal by three characters and still work', all([
(strlen('function all($ps){return $ps===array_filter($ps);}') - strlen('function all($a){return $a===array_filter($a);}')) === 3,
1+2 === 3,
]));
done();
😄
In a way, this whole exercise is reminiscent of those C/Perl code obfuscation contests. It's pretty crafty what one can do in 140 chars.
Pretty awesome!
TestFrameworkInATweet, used in the wild: http://stackoverflow.com/questions/24109521/youtube-playlist-all-videos-duration-show-in-php/24214755#24214755
Installation guide with composer
- Remove composer.
- Go to https://gist.github.com/mathiasverraes/9046427
- Copy/paste the entire #TestFrameworkInATweet sourcecode into your own code somewhere.
- Write a test.
- Get a PHP Fatal error: Call to undefined function it()
- Curse. (Or find a more senior developer to teach you some appropriate curses).
- Mess around with require_once and relative paths and directory separators and autoloaders for a bit.
- Oh look it's beer o'clock, maybe try again on Monday.
Rocking the unit testing world: http://php-and-symfony.matthiasnoback.nl/2014/07/descriptive-unit-tests/
Implementation
<?php
function it($m,$p){echo"\033[3",$p?'2m✔︎':'1m✘'.register_shutdown_function(function(){die(1);})," It $m\033[0m\n";}
- Colours
- Auto-exit
- 121 char
Installation guide:
<?php
eval(file_get_contents('https://gist.githubusercontent.com/everzet/8a14043d6a63329cee62/raw/twest.php'));
it('sums up two numbers', 1+1==2);
it('displays an X for a failing test', 1+1==3);
- Framework auto-update built in.
It also covers some minor frameworks like phpspec and phpunit, but of course the focus is mostly about #TestFrameworkInATweet!
Real life usage: http://stackoverflow.com/a/24214755
Soon we will have full stack frameworks in a tweet! Here is a prioritized event dispatcher in a tweet: https://gist.github.com/xsist10/824b559c4effaf43ddb3
framework components in tweets https://github.com/liuggio/sized140
78 chars
function it($m,$p){echo"\033[3",$p?"2m✔":"1m✘"," It $m\033[0m\n";$p||die(1);}
Dependency injection container in a tweet ... https://gist.github.com/jm42/3c32dd50bb9d09f57c4a
We have a glorious 280 characters at our disposal now. https://twitter.com/mathiasverraes/status/928526123297894400
We can bloat this framework with features. Go wild.
I just pushed few moments ago modified one with adjusted to 280 chars tweet and with some colors and dropped a need for done()
function call at end. https://twitter.com/mbrzuchalski/status/928539030035320832
It has also some debug info about last error:
<?php
function it($m,$p){echo($p?"\e[0;32m✔︎":"\e[0;31m✘")."\e[0m It $m\n";if(!$p){$GLOBALS['d']=debug_backtrace();}}
register_shutdown_function(function(){@$d=$GLOBALS['d'][0];if($d){echo "\e[1;37;41mFailed in {$d['file']} at {$d['line']}\e[0m\n";die(1);}echo "\e[1;32mOK\e[0m\n";});
Now there's even more, added error file and line every failed test and short summary at shutdown:
<?php
function it($m,$p){echo"\e[3".($p?"2m✔︎":"1m✘")."\e[0m It $m\n";if(!$p){$GLOBALS['e']=1;$d=debug_backtrace()[0];echo"ERROR {$d['file']}@{$d['line']}\n";}}register_shutdown_function(function(){echo"\e[1;3".(($e=@$GLOBALS['e'])?"7;41mFAIL":"2mOK")."\e[0m\n";die($e);});
Failing example:
it('should pass', true);
it('should fail', false);
it('should also fail', false);
Results:
✔︎ It should pass
✘ It should fail
ERROR /home/brzuchal/test-oneliner.php@6
✘ It should also fail
ERROR /home/brzuchal/test-oneliner.php@7
FAIL
Passing example:
it('should pass', true);
Results:
✔︎ It should pass
OK
And here is a link to my fork of this gist https://gist.github.com/brzuchal/5aeec672207bc9df4898ba99d6f7b369#file-testframeworkinatweet-php
So if someone would wanan use it can just:
<?php
include 'https://gist.githubusercontent.com/brzuchal/5aeec672207bc9df4898ba99d6f7b369/raw/22ce43d813007323e7cf1cee6a101f1ce7674466/TestFrameworkInATweet.php'
it('should pass', true);
it('should fail', false);
it('should also fail', false);
nice one :)
I gave up to colors, but
- use standard output/error for the success/failure output
- add some mimimum formatting
- add possibility to pass a callback as predicate
<?php
function it($m,$p){ $d=debug_backtrace(0)[0];
is_callable($p) and $p=$p();
global $e;$e=$e||!$p;
$o=($p?"✔":"✘")." It $m";
fwrite($p?STDOUT:STDERR,$p?"$o\n":"$o FAIL: {$d['file']} #{$d['line']}\n");
}
register_shutdown_function(function(){global $e; $e and die(1);});
Example:
it('should display an X for a failing test.', 1+1===3);
it('should append to an ArrayIterator.', function() {
$iterator = new ArrayIterator();
$iterator->append('test');
return count($iterator) === 1 && $iterator->current() === 'test';
});
it('should pass test for InvalidArgumentException exception.', function() {
try {
throw new InvalidArgumentException();
} catch(InvalidArgumentException $e) {
return true;
}
});
with output:
✘ It should display an X for a failing test. FAIL: /path/to/file.php #11
✔ It should append to an ArrayIterator.
✔ It should pass test for InvalidArgumentException exception.
Code-coverage support in 144 characters!
Usage:
Some cavats: PHP 5.5+ only, not much use on its own needs as it needs an output function too, and it includes code coverage in test and vendor files.
Here's an example text report function in 116 chars:
Usage:
Output:
I reality, you need to filter out test and vendor files, and would like to output in a single function, but I couldn't fit that in a tweet, here's a slightly longer version (185 chars) that does that:
Usage: