From 799cefa198cfd141afa79a35ad821f7deacb64ee Mon Sep 17 00:00:00 2001 From: "Ben Scholzen (DASPRiD)" Date: Sat, 15 Nov 2025 13:05:47 +0100 Subject: [PATCH] test: use specific snapshot matchers to avoid platform discrepancies --- .github/workflows/ci.yml | 12 +++++-- .github/workflows/pull-request.yml | 12 +++++-- .gitignore | 1 + Dockerfile | 8 ----- LICENSE | 2 +- README.md | 5 +++ composer.json | 1 + package-lock.json | 34 ++++++++++++++++++ package.json | 7 ++++ test/Integration/GDLibRenderingTest.php | 12 ++----- test/Integration/ImagickRenderingTest.php | 9 ++--- test/Integration/SVGRenderingTest.php | 20 +++++------ ...ringTest__testDifferentColorsQrCode__1.png | Bin 0 -> 1682 bytes ...LibRenderingTest__testGenericQrCode__1.png | Bin 0 -> 1648 bytes ...ickRenderingTest__testGenericQrCode__1.png | Bin .../ImagickRenderingTest__testIssue105__1.png | Bin .../ImagickRenderingTest__testIssue105__2.png | Bin .../ImagickRenderingTest__testIssue79__1.png | Bin ...SVGRenderingTest__testGenericQrCode__1.xml | 9 +++++ ...esDifferentIdsForDifferentGradients__1.xml | 15 ++++++++ ...esDifferentIdsForDifferentGradients__2.xml | 15 ++++++++ ...SVGRenderingTest__testGenericQrCode__1.svg | 2 -- ...ntIdsForDifferentGradients__horizontal.svg | 2 -- ...rentIdsForDifferentGradients__vertical.svg | 2 -- 24 files changed, 123 insertions(+), 45 deletions(-) delete mode 100644 Dockerfile create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 test/Integration/__snapshots__/GDLibRenderingTest__testDifferentColorsQrCode__1.png create mode 100644 test/Integration/__snapshots__/GDLibRenderingTest__testGenericQrCode__1.png rename test/Integration/__snapshots__/{files => }/ImagickRenderingTest__testGenericQrCode__1.png (100%) rename test/Integration/__snapshots__/{files => }/ImagickRenderingTest__testIssue105__1.png (100%) rename test/Integration/__snapshots__/{files => }/ImagickRenderingTest__testIssue105__2.png (100%) rename test/Integration/__snapshots__/{files => }/ImagickRenderingTest__testIssue79__1.png (100%) create mode 100644 test/Integration/__snapshots__/SVGRenderingTest__testGenericQrCode__1.xml create mode 100644 test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__1.xml create mode 100644 test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__2.xml delete mode 100644 test/Integration/__snapshots__/files/SVGRenderingTest__testGenericQrCode__1.svg delete mode 100644 test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__horizontal.svg delete mode 100644 test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__vertical.svg diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67fc091..09e51f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,11 @@ jobs: extensions: iconv, imagick, gd coverage: xdebug + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT @@ -47,9 +52,12 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies + - name: Install PHP dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader + - name: Install Node dependencies + run: npm install + - name: Test with phpunit run: vendor/bin/phpunit --coverage-clover clover.xml @@ -58,7 +66,7 @@ jobs: with: token: ${{ secrets.CODECOV_TOKEN }} files: ./clover.xml - + release: needs: [lint, test] runs-on: ubuntu-latest diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 870931b..f7071a6 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: operating-system: [ubuntu-latest] - php-versions: ['8.1', '8.2', '8.3'] + php-versions: ['8.1', '8.2', '8.3', '8.4'] runs-on: ${{ matrix.operating-system }} steps: - uses: actions/checkout@v4 @@ -36,6 +36,11 @@ jobs: extensions: iconv, imagick coverage: xdebug + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: 24 + - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT @@ -47,9 +52,12 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - - name: Install dependencies + - name: Install PHP dependencies run: composer install --no-progress --prefer-dist --optimize-autoloader + - name: Install Node dependencies + run: npm install + - name: Test with phpunit run: vendor/bin/phpunit --coverage-clover clover.xml diff --git a/.gitignore b/.gitignore index 9d5cbb4..3edc4a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /composer.lock /vendor +/node_modules /.phpunit.result.cache /.phpunit.cache diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 4bafbf4..0000000 --- a/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM php:8.1-cli - -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer -RUN apt-get update && apt-get install -y libmagickwand-dev libzip-dev zip --no-install-recommends && rm -rf /var/lib/apt/lists/* -RUN pecl install imagick && docker-php-ext-enable imagick && docker-php-ext-install zip -RUN alias composer='php /usr/bin/composer' - -WORKDIR /app diff --git a/LICENSE b/LICENSE index d45a356..aa22018 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017, Ben Scholzen 'DASPRiD' +Copyright (c) 2017-present, Ben Scholzen 'DASPRiD' All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index e429889..8291c26 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,8 @@ $renderer = new GDLibRenderer(400); $writer = new Writer($renderer); $writer->writeFile('Hello World!', 'qrcode.png'); ``` + +## Development + +To run unit tests, you need to have [Node.js](https://nodejs.org/en) and the pixelmatch library installed. Running +`npm install` will install this for you. diff --git a/composer.json b/composer.json index d086357..37e8c75 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,7 @@ "require-dev": { "phpunit/phpunit": "^10.5.11 || ^11.0.4", "spatie/phpunit-snapshot-assertions": "^5.1.5", + "spatie/pixelmatch-php": "^1.2.0", "squizlabs/php_codesniffer": "^3.9", "phly/keep-a-changelog": "^2.12" }, diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..810fd07 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,34 @@ +{ + "name": "baconqrcode", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "baconqrcode", + "dependencies": { + "pixelmatch": "^7.1.0" + } + }, + "node_modules/pixelmatch": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-7.1.0.tgz", + "integrity": "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng==", + "license": "ISC", + "dependencies": { + "pngjs": "^7.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1bc4886 --- /dev/null +++ b/package.json @@ -0,0 +1,7 @@ +{ + "name": "baconqrcode", + "private": true, + "dependencies": { + "pixelmatch": "^7.1.0" + } +} diff --git a/test/Integration/GDLibRenderingTest.php b/test/Integration/GDLibRenderingTest.php index 47b1e28..8e78e6d 100644 --- a/test/Integration/GDLibRenderingTest.php +++ b/test/Integration/GDLibRenderingTest.php @@ -5,22 +5,14 @@ namespace BaconQrCodeTest\Integration; use BaconQrCode\Exception\InvalidArgumentException; -use BaconQrCode\Exception\RuntimeException; use BaconQrCode\Renderer\Color\Alpha; use BaconQrCode\Renderer\Color\Rgb; -use BaconQrCode\Renderer\Eye\EyeInterface; -use BaconQrCode\Renderer\Eye\SimpleCircleEye; -use BaconQrCode\Renderer\Eye\SquareEye; use BaconQrCode\Renderer\GDLibRenderer; -use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\GDImageBackEnd; -use BaconQrCode\Renderer\Module\DotsModule; -use BaconQrCode\Renderer\Module\RoundnessModule; use BaconQrCode\Renderer\RendererStyle\EyeFill; use BaconQrCode\Renderer\RendererStyle\Fill; use BaconQrCode\Renderer\RendererStyle\Gradient; use BaconQrCode\Renderer\RendererStyle\GradientType; -use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RequiresPhpExtension; @@ -40,7 +32,7 @@ public function testGenericQrCode(): void $tempName = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer->writeFile('Hello World!', $tempName); - $this->assertMatchesFileSnapshot($tempName); + $this->assertMatchesImageSnapshot($tempName); unlink($tempName); } @@ -64,7 +56,7 @@ public function testDifferentColorsQrCode(): void $tempName = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer->writeFile('Hello World!', $tempName); - $this->assertMatchesFileSnapshot($tempName); + $this->assertMatchesImageSnapshot($tempName); unlink($tempName); } diff --git a/test/Integration/ImagickRenderingTest.php b/test/Integration/ImagickRenderingTest.php index a523839..f51e7eb 100644 --- a/test/Integration/ImagickRenderingTest.php +++ b/test/Integration/ImagickRenderingTest.php @@ -36,7 +36,7 @@ public function testGenericQrCode() : void $tempName = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer->writeFile('Hello World!', $tempName); - $this->assertMatchesFileSnapshot($tempName); + $this->assertMatchesImageSnapshot($tempName); unlink($tempName); } @@ -63,10 +63,11 @@ public function testIssue79() : void $tempName = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer->writeFile('https://apiroad.net/very-long-url', $tempName); - $this->assertMatchesFileSnapshot($tempName); + $this->assertMatchesImageSnapshot($tempName); unlink($tempName); } + #[RequiresPhpExtension('imagick')] public function testIssue105() : void { $squareModule = SquareModule::instance(); @@ -86,7 +87,7 @@ public function testIssue105() : void $tempName1 = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer1->writeFile('rotation without eye color', $tempName1); - $this->assertMatchesFileSnapshot($tempName1); + $this->assertMatchesImageSnapshot($tempName1); unlink($tempName1); $eyeFill = new EyeFill(new Rgb(255, 0, 0), new Rgb(0, 255, 0)); @@ -105,7 +106,7 @@ public function testIssue105() : void $tempName2 = tempnam(sys_get_temp_dir(), 'test') . '.png'; $writer2->writeFile('rotation with eye color', $tempName2); - $this->assertMatchesFileSnapshot($tempName2); + $this->assertMatchesImageSnapshot($tempName2); unlink($tempName2); } } diff --git a/test/Integration/SVGRenderingTest.php b/test/Integration/SVGRenderingTest.php index 2eb71d9..1655950 100644 --- a/test/Integration/SVGRenderingTest.php +++ b/test/Integration/SVGRenderingTest.php @@ -15,10 +15,13 @@ use BaconQrCode\Writer; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; +use Spatie\Snapshots\MatchesSnapshots; #[Group('integration')] final class SVGRenderingTest extends TestCase { + use MatchesSnapshots; + public function testGenericQrCode(): void { $renderer = new ImageRenderer( @@ -26,18 +29,15 @@ public function testGenericQrCode(): void new SvgImageBackEnd() ); $writer = new Writer($renderer); + $svg = $writer->writeString('Hello World!'); - $svgCode = $writer->writeString('Hello World!'); - $expected = file_get_contents(__DIR__.'/__snapshots__/files/SVGRenderingTest__testGenericQrCode__1.svg'); - - $this->assertEquals($expected, $svgCode); + $this->assertMatchesXmlSnapshot($svg); } - // SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients_horizontal - //SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients_vertical public function testQrWithGradientGeneratesDifferentIdsForDifferentGradients() { $types = ['HORIZONTAL', 'VERTICAL']; + foreach ($types as $type) { $gradient = new Gradient( new Rgb(0, 0, 0), @@ -58,13 +58,9 @@ public function testQrWithGradientGeneratesDifferentIdsForDifferentGradients() new SvgImageBackEnd() ); $writer = new Writer($renderer); - $qr = $writer->writeString('Hello World!'); - $expectedFile = __DIR__ . '/__snapshots__/files/'; - $expectedFile .= 'SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__'; - $expectedFile .= strtolower($type) . '.svg'; - $expected = file_get_contents($expectedFile); + $svg = $writer->writeString('Hello World!'); - $this->assertEquals($expected, $qr); + $this->assertMatchesXmlSnapshot($svg); } } } diff --git a/test/Integration/__snapshots__/GDLibRenderingTest__testDifferentColorsQrCode__1.png b/test/Integration/__snapshots__/GDLibRenderingTest__testDifferentColorsQrCode__1.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d6ae6f12de327e0de5632c69b0898d14a403fb GIT binary patch literal 1682 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~teM`SSr1K$x4W}K?cC(XdX z=Hlt%7*cWT?cI&Nx4lH#E>7IIR3qRFmkIBN_O(8?D;Ucb%wX&;)R1lyzw&6^v!Z8n zemF+;ef^NwByTe{XdNp<+?UgW3loi>+AA1sGUZ7#JCW$iaa@0Lp8q z<>BOi(pnfBWp6O!PO;kIo)1+LHza*`HG;wv=4nU>LwKAKi^^Zr?X21N+xmIwUel^O z8?GOl_P6`%;q`m8_ zpAC0$0W-2o;qK-;JYj?L=Uw;Ms$v%J%a3@zuugdg*tOumLW`gEn_TQC0d5CGjEc{m3jmogm~?=VzUz8d+wWD84gFVur%zeRIieoc|SE)+9tjG zd!K&i|GU}j`?qg-Kj}CxD4-!8hXpi{_hP1^Vzmq3?nUmkU(e1LthmJs zJ}{4Dw-QD&AE*Vci;*#bXL-=6tAh5`USWw1&acS8Kx9;DnKcBx1Z2rIP)&oo3+jmi%jpT`j#T#7SUwB&dzvg@Sy4N+Y zAH0ZKvp3q-ncJKFd;@li3M|@MWbV!@j9T58@N7RXQsAHk{{PJ`=`28VE+lQtQ|-rY z7|;(rr-b%8zqYzR=TQ72@e31AzYf#>dE)!l>qqLPVS$5QK3Om^>^m&<*I`*^^c*Hf zrRjGrzIWMfR1Qw+NYMlFCr63a(imB023&?Q4Dq55DFFbP#Pe!in(wVHnYqSCYB8{q OVeoYIb6Mw<&;$SmnWa7e literal 0 HcmV?d00001 diff --git a/test/Integration/__snapshots__/GDLibRenderingTest__testGenericQrCode__1.png b/test/Integration/__snapshots__/GDLibRenderingTest__testGenericQrCode__1.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1faa8cb96b29674e434e493e3ddcb4bfff1581 GIT binary patch literal 1648 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~teM`SSr1K$x4W}K?cC(XdX zrsV137*cWT?VXKzj~xVD9J?RZw4v-8;Z)4VJU zjEoKr3_v6xz`%l)_ke%5a)oK7?dCt;iz}~g{luelzKUIKFLNH)r!db#+=0Pk-+Zh( zrI-1dRd86Cc6#LB{h{+`AB}q7Ak6^}CZJB3Cm_+r9hFZi0o(j1W(uszK#(B=vrGxE48g>GNkhcQz6cRWVac@0Ew%EiwHl z88SU#_4(bOKko|9+snM85!v-PqWrPVwJ87N2Rh=N&vI|N%f0gf8z_CCd%O>rB$0jE z0FJiVw~xP5z40nC?Ekq_&r9pVPL*3et)BGZ-4YvSb7+(yYhy(Ae1r83S;vf@v)k_q zvAy8ooA)~s=v*9bL`t$Tw_cdun=)J)kIuMGhACL*>K` zt9s2-E4O_r53|=!T{xq7e)OT;w`$dx)f)_iQeKr36T1!a@s)x1;%Da+juZ+T`QcPVLVz+n?L_qpyVDr>t&zuk@}) zs0%StDcJ82pVd6sc&(~$?PAyKmsNG<`^C-sYI_itOMvzuSp`p%U}roy{*EIqlCAc$ zw{imSw%_?a7L#9<@2p<9y-NC4*-v;FOL-ja!H{#ZLtggFs!IU>LD zSha%o{O?x(&zatsvh?9OSn za@cV^>h((r2Es)EBx0}^4;08D#W#?N!R!0P+ZV#|Ym$tHCa?-&@O1TaS?83{1OV+t Blr8`O literal 0 HcmV?d00001 diff --git a/test/Integration/__snapshots__/files/ImagickRenderingTest__testGenericQrCode__1.png b/test/Integration/__snapshots__/ImagickRenderingTest__testGenericQrCode__1.png similarity index 100% rename from test/Integration/__snapshots__/files/ImagickRenderingTest__testGenericQrCode__1.png rename to test/Integration/__snapshots__/ImagickRenderingTest__testGenericQrCode__1.png diff --git a/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue105__1.png b/test/Integration/__snapshots__/ImagickRenderingTest__testIssue105__1.png similarity index 100% rename from test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue105__1.png rename to test/Integration/__snapshots__/ImagickRenderingTest__testIssue105__1.png diff --git a/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue105__2.png b/test/Integration/__snapshots__/ImagickRenderingTest__testIssue105__2.png similarity index 100% rename from test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue105__2.png rename to test/Integration/__snapshots__/ImagickRenderingTest__testIssue105__2.png diff --git a/test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue79__1.png b/test/Integration/__snapshots__/ImagickRenderingTest__testIssue79__1.png similarity index 100% rename from test/Integration/__snapshots__/files/ImagickRenderingTest__testIssue79__1.png rename to test/Integration/__snapshots__/ImagickRenderingTest__testIssue79__1.png diff --git a/test/Integration/__snapshots__/SVGRenderingTest__testGenericQrCode__1.xml b/test/Integration/__snapshots__/SVGRenderingTest__testGenericQrCode__1.xml new file mode 100644 index 0000000..b602bbb --- /dev/null +++ b/test/Integration/__snapshots__/SVGRenderingTest__testGenericQrCode__1.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__1.xml b/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__1.xml new file mode 100644 index 0000000..5ebaedd --- /dev/null +++ b/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__1.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__2.xml b/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__2.xml new file mode 100644 index 0000000..466151f --- /dev/null +++ b/test/Integration/__snapshots__/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__2.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/test/Integration/__snapshots__/files/SVGRenderingTest__testGenericQrCode__1.svg b/test/Integration/__snapshots__/files/SVGRenderingTest__testGenericQrCode__1.svg deleted file mode 100644 index 8c8607e..0000000 --- a/test/Integration/__snapshots__/files/SVGRenderingTest__testGenericQrCode__1.svg +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__horizontal.svg b/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__horizontal.svg deleted file mode 100644 index aa79f5d..0000000 --- a/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__horizontal.svg +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__vertical.svg b/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__vertical.svg deleted file mode 100644 index 60c25da..0000000 --- a/test/Integration/__snapshots__/files/SVGRenderingTest__testQrWithGradientGeneratesDifferentIdsForDifferentGradients__vertical.svg +++ /dev/null @@ -1,2 +0,0 @@ - -