-
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);} |
😄
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.
Schoolboy error there Sterling.