diff --git a/.env b/.env new file mode 100644 index 0000000..f9f2bc6 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +COMPOSE_FILE=compose.yaml:compose.dev.yaml +PHP_VERSION=8.3 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7a11f56 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI Pipeline + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + strategy: + matrix: + php_version: + - 8.3 + - 8.4 + runs-on: ubuntu-latest + env: + COMPOSE_FILE: compose.yaml + PHP_VERSION: ${{ matrix.php_version }} + + steps: + - uses: actions/checkout@v4 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + target: ci + push: false + load: true + tags: recruiterphp/byte-units-php:php-${{ matrix.php_version }}-latest + build-args: | + PHP_VERSION=${{ matrix.php_version }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Run test suite + run: make test diff --git a/.gitignore b/.gitignore index 303abbe..2540d6c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -.* +.*.cache +.idea/ composer.phar vendor/ composer.lock diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ccdebfe --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +ARG PHP_VERSION=8.4 + +FROM php:${PHP_VERSION}-cli AS base + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + unzip \ + libssl-dev \ + libcurl4-openssl-dev \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* + +RUN docker-php-ext-install -j$(nproc) \ + bcmath + +# Copy Composer from official image +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +# Set working directory +WORKDIR /app + +# Set environment variable for Composer +ENV COMPOSER_ALLOW_SUPERUSER=1 + +CMD ["tail", "-f", "/dev/null"] + +FROM base AS dev + +# Install XDebug extension +RUN pecl install xdebug \ + && docker-php-ext-enable xdebug + +FROM base AS ci + +# Copy composer files +COPY composer.json composer.lock* ./ + +# Install dependencies including dev dependencies for testing +RUN composer install --optimize-autoloader + +# Copy application code +COPY . . diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b23f6db --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +.PHONY: build up down test test-coverage phpstan rector fix-cs install shell logs clean + +# Build the Docker image +build: + docker compose build + +# Start the services +up: + docker compose up -d + +# Stop the services +down: + docker compose down + +# Install dependencies +install: + docker compose run --rm php composer install + +# Run all tests +test: up + docker compose exec php vendor/bin/phpunit + +# Run unit tests with coverage +test-coverage: up + docker compose exec -e XDEBUG_MODE=coverage php vendor/bin/phpunit --coverage-html var/coverage/ + +phpstan: up + docker compose exec php vendor/bin/phpstan + +rector: up + docker compose exec php vendor/bin/rector + +fix-cs: up + docker compose exec php vendor/bin/php-cs-fixer fix -v + +# Open a shell in the PHP container +shell: + docker compose exec php bash + +# View logs +logs: + docker compose logs -f php + +# Clean up containers and volumes +clean: + docker compose down -v + docker compose rm -f diff --git a/README.md b/README.md index f1494e6..75c06be 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,12 @@ echo ByteUnits\bytes(1322000)->numberOfBytes(); // outputs 1322000 ### Compare There are a few methods that could be used to compare bytes in various units and systems + ```php isLessThan(ByteUnits\Binary::kilobytes(1)); // it's true -ByteUnits\Metric::kilobytes(1)->isEqualTo(ByteUnits\Binary::bytes(1000)); // it's true +ByteUnits\Metric::kilobytes(1)->equals(ByteUnits\Binary::bytes(1000)); // it's true ByteUnits\Metric::kilobytes(1.3)->isGreaterThan(ByteUnits\Binary::kilobytes(1)); // it's true ``` diff --git a/compose.dev.yaml b/compose.dev.yaml new file mode 100644 index 0000000..a2a82a6 --- /dev/null +++ b/compose.dev.yaml @@ -0,0 +1,9 @@ +services: + php: + build: + context: . + args: + - PHP_VERSION=${PHP_VERSION} + target: dev + volumes: + - .:/app diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..9338c3f --- /dev/null +++ b/compose.yaml @@ -0,0 +1,9 @@ +services: + php: + build: + context: . + args: + - PHP_VERSION=${PHP_VERSION} + tags: + - latest + working_dir: /app diff --git a/composer.json b/composer.json index 3138b54..1f9e111 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,38 @@ { - "name": "gabrielelana/byte-units", + "name": "recruiterphp/byte-units", "description": "Library to parse, format and convert byte units", - "type": "library", - "version": "0.5.0", - "keywords": ["byte", "units", "format", "parse", "convert", "size"], - "homepage": "https://github.com/gabrielelana/byte-units", "license": "MIT", - "authors": [{ - "name": "Gabriele Lana", - "email": "gabriele.lana@gmail.com" - }], + "type": "library", + "keywords": [ + "byte", + "units", + "format", + "parse", + "convert", + "size" + ], + "authors": [ + { + "name": "Gabriele Lana", + "email": "gabriele.lana@gmail.com" + }, + { + "name": "Contributors", + "homepage": "https://github.com/recruiterphp/byte-units/graphs/contributors" + } + ], + "homepage": "https://github.com/recruiterphp/byte-units", + "require": { + "php": "^8.3", + "ext-bcmath": "*" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.47", + "phpunit/phpunit": "^12.3" + }, + "replace": { + "gabrielelana/byte-units": "self.version" + }, "autoload": { "psr-4": { "ByteUnits\\": "src/ByteUnits" @@ -18,11 +41,9 @@ "src/ByteUnits/functions.php" ] }, - "require": { - "php": ">=5.4.0", - "ext-bcmath": "*" - }, - "require-dev": { - "phpunit/phpunit": ">=4.0,<6.0" + "config": { + "allow-plugins": { + "ergebnis/composer-normalize": true + } } } diff --git a/phpunit.dist.xml b/phpunit.dist.xml new file mode 100644 index 0000000..c2048ac --- /dev/null +++ b/phpunit.dist.xml @@ -0,0 +1,25 @@ + + + + + tests + + + + + + src + + + diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index ab4a71a..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - tests/ - - - diff --git a/tests/ByteUnits/ArithmeticTest.php b/tests/ByteUnits/ArithmeticTest.php index 2334493..20876b2 100644 --- a/tests/ByteUnits/ArithmeticTest.php +++ b/tests/ByteUnits/ArithmeticTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class ArithmeticTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class ArithmeticTest extends TestCase { public function testAddInSameUnitSystem() { @@ -24,11 +26,9 @@ public function testAutoboxing() $this->assertEquals(Metric::bytes(3), Metric::bytes(5)->remove('2B')); } - /** - * @expectedException ByteUnits\NegativeBytesException - */ public function testCannotRemoveMoreBytesThanYouHave() { + $this->expectException(NegativeBytesException::class); Metric::bytes(5)->remove(Metric::bytes(10)); } diff --git a/tests/ByteUnits/BinarySystemTest.php b/tests/ByteUnits/BinarySystemTest.php index 2c4ef64..95ce9b8 100644 --- a/tests/ByteUnits/BinarySystemTest.php +++ b/tests/ByteUnits/BinarySystemTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class BinarySystemTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class BinarySystemTest extends TestCase { public function testKilobytesConstructor() { @@ -34,11 +36,9 @@ public function testExabytesConstructor() $this->assertEquals(Binary::bytes(1152921504606846976), Binary::exabytes(1)); } - /** - * @expectedException ByteUnits\NegativeBytesException - */ public function testCannotBeNegative() { + $this->expectException(NegativeBytesException::class); Binary::bytes(-1); } } diff --git a/tests/ByteUnits/BoxingTest.php b/tests/ByteUnits/BoxingTest.php index 87b6070..6350a7d 100644 --- a/tests/ByteUnits/BoxingTest.php +++ b/tests/ByteUnits/BoxingTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class BoxingTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class BoxingTest extends TestCase { public function testBoxAnInteger() { @@ -22,11 +24,9 @@ public function testBoxAByteUnit() $this->assertEquals($byteUnitInBinarySystem, box($byteUnitInBinarySystem)); } - /** - * @expectedException ByteUnits\ConversionException - */ public function testBoxAnObjectThatIsNotAByteUnit() { + $this->expectException(ConversionException::class); box(new \StdClass()); } } diff --git a/tests/ByteUnits/CompareTest.php b/tests/ByteUnits/CompareTest.php index fb3a13e..0512116 100644 --- a/tests/ByteUnits/CompareTest.php +++ b/tests/ByteUnits/CompareTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class CompareTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class CompareTest extends TestCase { public function testCompareWithSameUnitSystem() { diff --git a/tests/ByteUnits/ConversionBetweenSystemsTest.php b/tests/ByteUnits/ConversionBetweenSystemsTest.php index b6aaea0..d2ac6ef 100644 --- a/tests/ByteUnits/ConversionBetweenSystemsTest.php +++ b/tests/ByteUnits/ConversionBetweenSystemsTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class ConversionBetweenSystemsTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class ConversionBetweenSystemsTest extends TestCase { public function testBytesAreInMetricStystem() { diff --git a/tests/ByteUnits/FormatInBinarySystemTest.php b/tests/ByteUnits/FormatInBinarySystemTest.php index 18147d0..a674430 100644 --- a/tests/ByteUnits/FormatInBinarySystemTest.php +++ b/tests/ByteUnits/FormatInBinarySystemTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class FormatInBinarySystemTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class FormatInBinarySystemTest extends TestCase { public function testBytesNamedConstructor() { diff --git a/tests/ByteUnits/FormatInMetricSystemTest.php b/tests/ByteUnits/FormatInMetricSystemTest.php index 83aede7..29d3676 100644 --- a/tests/ByteUnits/FormatInMetricSystemTest.php +++ b/tests/ByteUnits/FormatInMetricSystemTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class FormatInMetricSystemTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class FormatInMetricSystemTest extends TestCase { public function testBytesNamedConstructor() { diff --git a/tests/ByteUnits/MetricSystemTest.php b/tests/ByteUnits/MetricSystemTest.php index 36677a4..eb7e0ae 100644 --- a/tests/ByteUnits/MetricSystemTest.php +++ b/tests/ByteUnits/MetricSystemTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class MetricSystemTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class MetricSystemTest extends TestCase { public function testKilobytesConstructor() { @@ -34,11 +36,9 @@ public function testExabytesConstructor() $this->assertEquals(Metric::bytes(1000000000000000000), Metric::exabytes(1)); } - /** - * @expectedException ByteUnits\NegativeBytesException - */ public function testCannotBeNegative() { + $this->expectException(NegativeBytesException::class); Metric::bytes(-1); } } diff --git a/tests/ByteUnits/ParseTest.php b/tests/ByteUnits/ParseTest.php index 3deb8cc..91cf7ec 100644 --- a/tests/ByteUnits/ParseTest.php +++ b/tests/ByteUnits/ParseTest.php @@ -2,7 +2,9 @@ namespace ByteUnits; -class ParseTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class ParseTest extends TestCase { public function testParseInMetricSystem() { @@ -28,27 +30,21 @@ public function testParseWithSeparator() $this->assertEquals(Metric::bytes(1000), parse('1.00~~~kB')); } - /** - * @expectedException ByteUnits\ParseException - */ public function testInvalidByteFormat() { + $this->expectException(ParseException::class); parse('Not a valid byte format'); } - /** - * @expectedException ByteUnits\ParseException - */ public function testInvalidByteFormatForBinarySystem() { + $this->expectException(ParseException::class); Binary::parse('1.00kB'); } - /** - * @expectedException ByteUnits\ParseException - */ public function testInvalidByteFormatForMetricSystem() { + $this->expectException(ParseException::class); Metric::parse('1.00KiB'); } }