Skip to content

Instantly share code, notes, and snippets.

@mathiasverraes
Last active May 23, 2022 12:28
  • Star 112 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mathiasverraes/9046427 to your computer and use it in GitHub Desktop.
A unit testing framework in a tweet.
<?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);}
@samdbeckham
Copy link

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();

@anthonysterling
Copy link

😄

@marcaube
Copy link

marcaube commented Jun 6, 2014

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!

@mathiasverraes
Copy link
Author

@mathiasverraes
Copy link
Author

Installation guide with composer

  1. Remove composer.
  2. Go to https://gist.github.com/mathiasverraes/9046427
  3. Copy/paste the entire #TestFrameworkInATweet sourcecode into your own code somewhere.
  4. Write a test.
  5. Get a PHP Fatal error: Call to undefined function it()
  6. Curse. (Or find a more senior developer to teach you some appropriate curses).
  7. Mess around with require_once and relative paths and directory separators and autoloaders for a bit.
  8. Oh look it's beer o'clock, maybe try again on Monday.

@mathiasverraes
Copy link
Author

@everzet
Copy link

everzet commented Jul 8, 2014

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.

@mathiasverraes
Copy link
Author

Another article

It also covers some minor frameworks like phpspec and phpunit, but of course the focus is mostly about #TestFrameworkInATweet!

@mathiasverraes
Copy link
Author

@mathiasverraes
Copy link
Author

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

@turanct
Copy link

turanct commented Oct 7, 2014

And a REPL in a tweet: gist / tweet

@liuggio
Copy link

liuggio commented Oct 22, 2014

framework components in tweets https://github.com/liuggio/sized140

@lastguest
Copy link

78 chars

function it($m,$p){echo"\033[3",$p?"2m✔":"1m✘"," It $m\033[0m\n";$p||die(1);}

@jm42
Copy link

jm42 commented Oct 31, 2014

Dependency injection container in a tweet ... https://gist.github.com/jm42/3c32dd50bb9d09f57c4a

@mathiasverraes
Copy link
Author

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.

@brzuchal
Copy link

brzuchal commented Nov 9, 2017

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";});

@brzuchal
Copy link

brzuchal commented Nov 9, 2017

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);

@mathiasverraes
Copy link
Author

nice one :)

@gmazzap
Copy link

gmazzap commented Nov 29, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment