Skip to content

Instantly share code, notes, and snippets.

@turanct
Created February 11, 2015 14:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turanct/129a6ed97ec3543ebafd to your computer and use it in GitHub Desktop.
Save turanct/129a6ed97ec3543ebafd to your computer and use it in GitHub Desktop.
Simple test framework, functional programming style
<?php
function within($topic, ...$features)
{
return function($do = 'getFailedAssertions') use ($topic, $features) {
if ($do === 'getName') {
return $topic;
} elseif ($do === 'getFailedAssertions') {
return array_reduce(
$features,
function($failedAssertions, $feature) {
return array_merge(
$failedAssertions,
array_map(
function($assertion) use ($feature) {
return array($assertion, $feature);
},
$feature('getFailedAssertions')
)
);
},
array()
);
} elseif ($do === 'numberOfFeatures') {
return count($features);
} elseif ($do === 'numberOfAssertions') {
return array_reduce(
$features,
function($number, $feature) {
return $number + $feature('numberOfAssertions');
},
0
);
} else {
throw new InvalidArgumentException('Invalid argument ' . $do);
}
};
}
function describe($feature, ...$assertions)
{
return function($do = 'getFailedAssertions') use ($feature, $assertions) {
if ($do === 'getName') {
return $feature;
} elseif ($do === 'getFailedAssertions') {
return array_filter(
$assertions,
function($assertion) {
return !$assertion('assert');
}
);
} elseif ($do === 'numberOfAssertions') {
return count($assertions);
} else {
throw new InvalidArgumentException('Invalid argument ' . $do);
}
};
}
function it($doesThis, $correctly)
{
return function($do = 'assert') use ($doesThis, $correctly) {
if ($do === 'assert') {
return (bool) $correctly;
} elseif ($do === 'getDescription') {
return (string) $doesThis;
} else {
throw new InvalidArgumentException('Invalid argument ' . $do);
}
};
}
function testResults(array $topics)
{
return function($do = '') use ($topics) {
if ($do === 'numberOfTopics') {
return count($topics);
} elseif ($do === 'numberOfFeatures') {
return array_reduce(
$topics,
function($number, $topic) {
return $number + $topic('numberOfFeatures');
},
0
);
} elseif ($do === 'numberOfAssertions') {
return array_reduce(
$topics,
function($number, $topic) {
return $number + $topic('numberOfAssertions');
},
0
);
} elseif ($do === 'failedAssertions') {
return array_reduce(
$topics,
function($failedAssertions, $topic) {
$assertions = $topic('getFailedAssertions');
$assertions = array_map(
function($assertion) use ($topic) {
$assertion[] = $topic;
return $assertion;
},
$assertions
);
return array_merge($failedAssertions, $assertions);
},
array()
);
} else {
throw new InvalidArgumentException('Invalid argument ' . $do);
}
};
}
function displayTestResults($testResults)
{
$output = '';
$output .= 'topics: ' . $testResults('numberOfTopics') . "\n";
$output .= 'features: ' . $testResults('numberOfFeatures') . "\n";
$output .= 'assertions: ' . $testResults('numberOfAssertions') . "\n";
$output .= "\n";
$output .= implode(
"\n",
array_map(
function($assertion) {
return failedOutput($assertion[2], $assertion[1], $assertion[0]);
},
$testResults('failedAssertions')
)
);
$output .= "\n";
echo $output;
}
function failedOutput($topic, $feature, $assertion)
{
return 'FAILED: '
. $topic('getName')
. ': ' . $feature('getName')
. ' ' . $assertion('getDescription')
;
}
function getTopics()
{
$files = glob('topic*.php');
return array_map(
function($file) {
return include($file);
},
$files
);
}
<?php
require_once 'functional-tests.php';
displayTestResults(testResults(getTopics()));
<?php
return within("calculus",
describe("addition",
it("adds two numbers", (1 + 1 == 3)),
it("is difficult", false),
it("adds three numbers", (1 + 1 + 1 == 3))
),
describe("subtraction",
it("looks strange", true),
it("subtracts two numbers", (3 - 2 == 1))
)
);
@turanct
Copy link
Author

turanct commented Feb 11, 2015

running php run-tests.php will produce this output:

topics: 1
features: 2
assertions: 5

FAILED: calculus: addition adds two numbers
FAILED: calculus: addition is difficult

It will also work with multiple topic-* files

@mathiasverraes
Copy link

@turanct
Copy link
Author

turanct commented Feb 15, 2015

you're right about those 3 things. Also, i didn't see the dispatch method yet, it's really quite elegant!

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