1
0
mirror of https://github.com/mosbth/cimage.git synced 2025-08-01 14:00:08 +02:00

adding behat for feature testing

This commit is contained in:
Mikael Roos
2016-06-03 11:44:27 +02:00
parent 3d2c74e9df
commit fbaf05d0d4
14 changed files with 2963 additions and 86 deletions

3
.gitignore vendored
View File

@@ -7,8 +7,7 @@ coverage/
coverage.clover
# Composer
composer.lock
vendor
vendor/
# Build and test
build/

137
Makefile
View File

@@ -2,78 +2,114 @@
#
#
# Colors
NO_COLOR = \033[0m
TARGET_COLOR = \033[32;01m
OK_COLOR = \033[32;01m
ERROR_COLOR = \033[31;01m
WARN_COLOR = \033[33;01m
ACTION = $(TARGET_COLOR)-->
#
# Build
#
.PHONY: build
# Add local bin path for test tools
BIN = bin
VENDORBIN = vendor/bin
NPMBIN = node_modules/.bin
build:
[ -d build ] || mkdir build
# target: help - Displays help.
.PHONY: help
help:
@echo "$(ACTION)Displaying help for this Makefile.$(NO_COLOR)"
@echo "Usage:"
@echo " make [target] ..."
@echo "target:"
@egrep "^# target:" Makefile | sed 's/# target: / /g'
# target: clean - Remove all generated files.
.PHONY: clean
clean:
@echo "$(ACTION)Remove all generated files$(NO_COLOR)"
rm -rf build
rm -f npm-debug.log
# target: clean-all - Remove all installed files.
.PHONY: clean-all
clean-all: clean
@echo "$(ACTION)Remove all installed files$(NO_COLOR)"
rm -rf bin
rm -rf node_modules
rm -rf vendor
# target: build-prepare - Prepare the build directory.
.PHONY: build-prepare
build-prepare:
@echo "$(ACTION)Prepare the build directory$(NO_COLOR)"
install -d build
#install -d bin/pip
rm -rf build/*
#
# Various test to pass build
#
# target: test - Various test to pass build.
.PHONY: test
test: build phpunit phpcs
test: build-prepare phpunit behat phpcs
#
# phpcs
#
# target: phpcs - Run phpcs for PHP code style.
.PHONY: phpcs
phpcs:
phpcs --standard=.phpcs.xml | tee build/phpcs
phpcs: build-prepare
@echo "$(ACTION)phpcs$(NO_COLOR)"
$(VENDORBIN)/phpcs --standard=.phpcs.xml | tee build/phpcs
#
# phpcbf
#
# target: phpcbf - Run phpcbf to fix PHP code style.
.PHONY: phpcbf
phpcbf:
phpcbf --standard=.phpcs.xml
@echo "$(ACTION)phpcbf$(NO_COLOR)"
$(VENDORBIN)/phpcbf --standard=.phpcs.xml
#
# phpunit
#
# target: phpunit - Run phpunit for unit testing PHP.
.PHONY: phpunit
phpunit:
phpunit --configuration .phpunit.xml
phpunit: build-prepare
@echo "$(ACTION)phpunit$(NO_COLOR)"
$(VENDORBIN)/phpunit --configuration .phpunit.xml
#
# phpdoc
#
# target: behat - Run behat for feature tests.
.PHONY: behat
behat:
@echo "$(ACTION)behat$(NO_COLOR)"
$(VENDORBIN)/behat
# target: phpdoc - Run phpdoc to create API documentation.
.PHONY: phpdoc
phpdoc:
phpdoc --config=.phpdoc.xml
@echo "$(ACTION)phpdoc$(NO_COLOR)"
$(VENDORBIN)/phpdoc --config=.phpdoc.xml
# target: tag-prepare - Prepare to tag new version.
.PHONY: tag-prepare
tag-prepare:
@echo "$(ACTION)Prepare to tag new version, perform selfcheck$(NO_COLOR)"
# ------------------------- OBSOLETE TO BE REMOVED?
#
# Build and development environment using make
#
COMPOSER_PACKAGES = \
"phpunit/phpunit=4.*" \
"sebastian/phpcpd=2.*" \
"phploc/phploc=2.*" \
"phpdocumentor/phpdocumentor=2.*" \
"squizlabs/php_codesniffer=2.*" \
"phpmd/phpmd=@stable" \
NPM_PACKAGES = \
htmlhint \
csslint \
@@ -121,19 +157,6 @@ tools-update: composer-update npm-update apm-update
#
# composer
#
.PHONY: composer-require composer-update
composer-require:
composer --sort-packages --update-no-dev global require $(COMPOSER_PACKAGES)
composer-update:
composer --no-dev global update
#
# npm
#

View File

@@ -1,5 +1,5 @@
{
"name": "mos/cimage",
"name": "mos/cimage",
"type": "library",
"description": "Serverside image processing with PHP GD. Process, scale, resize, crop and filter images.",
"keywords": ["image", "imageprocessing", "gd", "crop", "resize"],
@@ -8,17 +8,30 @@
"authors": [
{
"name": "Mikael Roos",
"email": "me@mikaelroos.se",
"email": "mos@dbwebb.se",
"homepage": "http://mikaelroos.se",
"role": "Developer"
}
],
"support": {
"source": "https://github.com/mosbth/cimage",
"issues": "https://github.com/mosbth/cimage/issues",
"docs": "http://dbwebb.se/opensource/cimage"
},
"require": {
"php": ">=5.4"
"php": ">=5.4",
"ext-gd": "*"
},
"suggest": {
"ext-exif": "*"
},
"require-dev": {
"phpunit/phpunit": "5.3.*",
"behat/behat": "3.0.*",
"phpmd/phpmd": "2.4.*",
"squizlabs/php_codesniffer": "2.6.*",
"phploc/phploc": "2.*",
"phpdocumentor/phpdocumentor": "2.*"
},
"autoload": {
"classmap": [ "src/CImage/" ]

2452
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,206 @@
<?php
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
/**
* Defines application features from the specific context.
*/
class FeatureContext implements Context, SnippetAcceptingContext
{
private $url = null;
private $headers = [];
private $imageString = null;
private $image = null;
private $imageJSON = null;
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct()
{
}
/**
* @Given Set mode :arg1
*/
public function setMode($arg1 = null)
{
$this->url = "http://localhost/git/cimage/webroot/";
switch ($arg1) {
case "development":
$this->url .= "imgd.php";
break;
case "production":
$this->url .= "imgp.php";
break;
case "strict":
$this->url .= "imgs.php";
break;
default:
$this->url .= "img.php";
}
}
/**
* @Given Set src :arg1
*/
public function setSrc($arg1)
{
if (is_null($this->url)) {
$this->setMode();
}
$this->url .= "?src=$arg1";
}
/**
* @When Get image
*/
public function getImage()
{
//echo $this->url;
$res = file_get_contents($this->url);
PHPUnit_Framework_Assert::assertNotEquals(false, $res);
$this->imageString = $res;
$this->headers = $http_response_header;
if (is_null($this->imageJSON)) {
$this->getImageAsJson();
}
}
/**
* @When Get image as JSON
*/
public function getImageAsJson()
{
$res = file_get_contents($this->url . "&json");
PHPUnit_Framework_Assert::assertNotEquals(false, $res);
$res = json_decode($res, true);
PHPUnit_Framework_Assert::assertNotEquals(null, $res);
$this->imageJSON = $res;
}
/**
* @When Get headers for image
*/
public function getHeadersForImage()
{
//echo $this->url;
$res = get_headers($this->url);
PHPUnit_Framework_Assert::assertNotEquals(false, $res);
$this->headers = $http_response_header;
}
/**
* @Then Returns status code :arg1
*/
public function returnsStatusCode($arg1)
{
PHPUnit_Framework_Assert::assertNotEquals(
false,
strpos($this->headers[0], $arg1)
);
}
/**
*
*/
private function compareImageJsonToHeaders()
{
$contentLength = "Content-Length: " . $this->imageJSON["size"];
PHPUnit_Framework_Assert::assertContains(
$contentLength,
$this->headers
);
$contentType = "Content-Type: " . $this->imageJSON["mimeType"];
PHPUnit_Framework_Assert::assertContains(
$contentType,
$this->headers
);
$lastModified = "Last-Modified: " . $this->imageJSON["cacheGmdate"] . " GMT";
PHPUnit_Framework_Assert::assertContains(
$lastModified,
$this->headers
);
}
/**
*
*/
private function compareImageJsonToSavedJson($file)
{
$res = file_get_contents("$file.json");
PHPUnit_Framework_Assert::assertNotEquals(false, $res);
$res = json_decode($res, true);
PHPUnit_Framework_Assert::assertNotEquals(null, $res);
$keys = [
"mimeType",
"width",
"height",
"size",
"colors",
"pngType",
];
foreach ($keys as $key) {
if (array_key_exists($key, $res)
&& array_key_exists($key, $this->imageJSON)
) {
PHPUnit_Framework_Assert::assertEquals(
$res[$key],
$this->imageJSON[$key]
);
}
}
}
/**
* @Then Compares to image :arg1
*/
public function comparesToImage($arg1)
{
$base = __DIR__ . "/../img";
$res = file_get_contents("$base/$arg1");
PHPUnit_Framework_Assert::assertNotEquals(false, $res);
PHPUnit_Framework_Assert::assertEquals($this->imageString, $res);
$this->compareImageJsonToHeaders();
$this->compareImageJsonToSavedJson("$base/$arg1");
}
}

8
features/dummy.feature Normal file
View File

@@ -0,0 +1,8 @@
Feature: dummy
Display an dummy image without using a existing image on file.
Scenario: Set source to be dummy
Given Set src "dummy"
When Get image
Then Returns status code "200"
And Compares to image "dummy"

BIN
features/img/dummy Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

19
features/img/dummy.json Normal file
View File

@@ -0,0 +1,19 @@
{
"src": "dummy_100_100_q60_co-1",
"srcGmdate": "Fri, 03 Jun 2016 07:38:56",
"cache": "_._dummy_100_100_q60_co-1_q60_co-1",
"cacheGmdate": "Fri, 03 Jun 2016 07:38:56",
"filename": "_._dummy_100_100_q60_co-1_q60_co-1",
"mimeType": "image/png",
"width": 100,
"height": 100,
"aspectRatio": 1,
"size": 334,
"colors": 1,
"includedFiles": 6,
"memoryPeek": "0.341 MB",
"memoryCurrent": "0.316 MB",
"memoryLimit": "128M",
"loadTime": "0.01s",
"pngType": "PNG is type 6, RGB with alpha channel (PNG 32-bit)"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

View File

@@ -0,0 +1,19 @@
{
"src": "test_100x100.png",
"srcGmdate": "Fri, 03 Jun 2016 08:12:39",
"cache": "_._test_100x100.png_q60_co-1",
"cacheGmdate": "Fri, 03 Jun 2016 08:19:37",
"filename": "_._test_100x100.png_q60_co-1",
"mimeType": "image/png",
"width": 100,
"height": 100,
"aspectRatio": 1,
"size": 392,
"colors": 6,
"includedFiles": 6,
"memoryPeek": "0.339 MB",
"memoryCurrent": "0.316 MB",
"memoryLimit": "128M",
"loadTime": "0.012s",
"pngType": "PNG is type 6, RGB with alpha channel (PNG 32-bit)"
}

13
features/src.feature Normal file
View File

@@ -0,0 +1,13 @@
Feature: src
Display an image by selecting its source.
Scenario: Source is not a valid image name
Given Set src "NO_IMAGE"
When Get headers for image
Then Returns status code "404"
Scenario: Get only source image
Given Set src "test_100x100.png"
When Get image
Then Returns status code "200"
And Compares to image "test_100x100.png"

View File

@@ -73,16 +73,23 @@ class CImageResizerStrategyCropToFitTest extends \PHPUnit_Framework_TestCase
return [
// Square
[100, 100, 200, 200, 50, 50, 100, 100],
[100, 100, 400, 100, 150, 0, 100, 100],
[100, 100, 100, 400, 0, 150, 100, 100],
[100, 100, 400, 400, 150, 150, 100, 100],
[491, 323, 600, 400, 55, 39, 491, 323],
array(100,100, 200,200, 0,0,100,100, 50,50,100,100),
array(100,100, 200,100, 0,0,100,100, 50,0,100,100),
array(100,100, 100,200, 0,0,100,100, 0,50,100,100),
// Landscape
array(200,100, 400,200, 0,0,200,100, 100,50,200,100),
array(200,100, 50,50, 50,0,100,100, 0,0,200,100),
/*
array(200, 100, 400, 100, 0, 25, 200, 50),
array(200, 100, 100, 400, round(175/2), 0, 25, 100),
// Portrait
array(100, 200, 50, 100, 0, 0, 100, 200),
array(100, 200, 50, 50, 0, 50, 100, 100),
array(100, 200, 200, 50, 0, round(175/2), 100, 25),
array(100, 200, 50, 200, 25, 0, 50, 200),
/* */
];
}
@@ -91,13 +98,13 @@ class CImageResizerStrategyCropToFitTest extends \PHPUnit_Framework_TestCase
/**
* Test
*
* @dataProvider providerImages
* @dataProvider providerImages2
*
* @return void
*/
public function testResize2($sw, $sh, $tw, $th, $cx, $cy, $cw, $ch)
public function testResize2($sw, $sh, $tw, $th, $cx, $cy, $cw, $ch, $dx, $dy, $dw, $dh)
{
$img = new CImageResizer(/*'logger'/**/);
$img = new CImageResizer(/*'logger'/**/);
$img->setSource($sw, $sh)
->setBaseWidthHeight($tw, $th)
@@ -112,5 +119,10 @@ class CImageResizerStrategyCropToFitTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($cy, $img->getCropY(), "CropY not correct.");
$this->assertEquals($cw, $img->getCropWidth(), "CropWidth not correct.");
$this->assertEquals($ch, $img->getCropHeight(), "CropHeight not correct.");
$this->assertEquals($dx, $img->getDestinationX(), "DestinationX not correct.");
$this->assertEquals($dy, $img->getDestinationY(), "DestinationY not correct.");
$this->assertEquals($dw, $img->getDestinationWidth(), "DestinationWidth not correct.");
$this->assertEquals($dh, $img->getDestinationHeight(), "DestinationHeight not correct.");
}
}

143
webroot/img/drawing.svg Normal file
View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="drawing.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2"
inkscape:cx="76.428572"
inkscape:cy="-22.526694"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1063"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:#e6e6e6;fill-opacity:1;stroke:none;stroke-opacity:1"
id="rect4146"
width="100"
height="100"
x="-7.4924429e-08"
y="952.36218" />
<path
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 0,952.3622 0,20 20,0 0,-20 -20,0 z"
id="rect4136"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4140"
d="m 166,948.8622 0,10 10,0 0,-10 -10,0 z"
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 185.5,949.3622 0,10 10,0 0,-10 -10,0 z"
id="path4142"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4144"
d="m 201.5,949.8622 0,10 10,0 0,-10 -10,0 z"
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4148"
d="m 40,952.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 80,952.3622 0,20 20,0 0,-20 -20,0 z"
id="path4150"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4152"
d="m 20,972.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#00ffff;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#000080;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 60,972.3622 0,20 20,0 0,-20 -20,0 z"
id="path4154"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4156"
d="m 0,992.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 40,992.3622 0,20 20,0 0,-20 -20,0 z"
id="path4158"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4160"
d="m 80,992.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#00ffff;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 20,1012.3622 0,20 20,0 0,-20 -20,0 z"
id="path4162"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4164"
d="m 60,1012.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#000080;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4166"
d="m 0,1032.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#009600;fill-opacity:1;stroke:none;stroke-opacity:1" />
<path
style="fill:#ffff00;fill-opacity:1;stroke:none;stroke-opacity:1"
d="m 40,1032.3622 0,20 20,0 0,-20 -20,0 z"
id="path4168"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path4170"
d="m 80,1032.3622 0,20 20,0 0,-20 -20,0 z"
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B