Skip to content

Commit 320e5ea

Browse files
committed
Add functional tests and PhpUnit
1 parent 6bb9ead commit 320e5ea

17 files changed

+372
-12
lines changed

.github/workflows/phpunit.yml

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: "PHPUnit tests"
2+
3+
on:
4+
push:
5+
6+
jobs:
7+
phpunit:
8+
name: "PHPUnit tests"
9+
10+
runs-on: ${{ matrix.operating-system }}
11+
12+
strategy:
13+
matrix:
14+
dependencies:
15+
- "lowest"
16+
- "highest"
17+
php-version:
18+
- "7.4"
19+
- "8.0"
20+
operating-system:
21+
- "ubuntu-latest"
22+
23+
steps:
24+
- name: "Checkout"
25+
uses: "actions/checkout@v2"
26+
27+
- name: "Install PHP"
28+
uses: "shivammathur/setup-php@v2"
29+
with:
30+
coverage: "xdebug"
31+
php-version: "${{ matrix.php-version }}"
32+
ini-values: memory_limit=-1
33+
tools: composer:v2, cs2pr
34+
35+
- name: "Cache dependencies"
36+
uses: "actions/cache@v2"
37+
with:
38+
path: |
39+
~/.composer/cache
40+
vendor
41+
key: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}"
42+
restore-keys: "php-${{ matrix.php-version }}-${{ matrix.dependencies }}"
43+
44+
- name: "Install lowest dependencies"
45+
if: ${{ matrix.dependencies == 'lowest' }}
46+
run: "composer update --prefer-lowest --no-interaction --no-progress --no-suggest"
47+
48+
- name: "Install highest dependencies"
49+
if: ${{ matrix.dependencies == 'highest' }}
50+
run: "composer update --no-interaction --no-progress --no-suggest"
51+
52+
- name: "Install locked dependencies"
53+
if: ${{ matrix.dependencies == 'locked' }}
54+
run: "composer install --no-interaction --no-progress --no-suggest"
55+
56+
- name: "Tests"
57+
run: "XDEBUG_MODE=coverage vendor/bin/phpunit"

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
.phpunit.result.cache
2+
composer.lock
3+
/build/
14
/vendor/

LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2021 Lisachenko Alexander <[email protected]>
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ operators of comparison, addition, multiplication, casting and much more!
77

88
This library is first ever userland PHP extension, that implements operator overloading for the `Matrix` class.
99

10-
[![GitHub release](https://img.shields.io/github/release/lisachenko/native-types.svg)](https://github.com/lisachenko/native-types/releases/latest)
10+
[![GitHub release](https://img.shields.io/github/release/lisachenko/native-php-matrix.svg)](https://github.com/lisachenko/native-php-matrix/releases/latest)
1111
[![Minimum PHP Version](http://img.shields.io/badge/php-%3E%3D%207.4-8892BF.svg)](https://php.net/)
12-
[![License](https://img.shields.io/packagist/l/lisachenko/native-types.svg)](https://packagist.org/packages/lisachenko/native-types)
12+
[![License](https://img.shields.io/packagist/l/lisachenko/native-php-matrix.svg)](https://packagist.org/packages/lisachenko/native-php-matrix)
1313

1414

1515
Pre-requisites and initialization
@@ -20,7 +20,7 @@ As this library depends on `FFI`, it requires PHP>=7.4 and `FFI` extension to be
2020

2121
To install this library, simply add it via `composer`:
2222
```bash
23-
composer require lisachenko/native-types
23+
composer require lisachenko/native-php-matrix
2424
```
2525

2626
Now you can test it with following example:
@@ -39,9 +39,9 @@ $value = $first * 2 + $second; // Matrix([[22, 44, 66]])
3939
Supported features:
4040
- [x] Matrices addition (`$matrixA + $matrixB`)
4141
- [x] Matrices subtraction (`$matrixA - $matrixB`)
42+
- [x] Matrix multiplication by number (`$matrixA * 2`)
4243
- [x] Matrices multiplication (`$matrixA * $matrixB`)
43-
- [x] Matrices division (`$matrixA / $matrixB`)
44-
- [x] Matrices division (`$matrixA / $matrixB`)
44+
- [x] Dividing a matrix by a number (`$matrixA / 2`)
4545
- [x] Matrices equality check (`$matrixA == $matrixB`)
4646

4747
For the future versions, I would like to implement native SSE/AVX assembly methods to improve the performance of calculation.

composer.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
}
1111
],
1212
"require": {
13-
"lisachenko/z-engine": "^0.8 || ^0.9",
13+
"lisachenko/z-engine": "^0.8.1 || ^0.9.1",
1414
"php": "^7.4|^8.0"
1515
},
16+
"require-dev": {
17+
"phpunit/phpunit": "^9.5.5"
18+
},
1619
"autoload": {
1720
"psr-4" : {
1821
"Lisachenko\\NativePhpMatrix\\" : "src/"

phpunit.xml.dist

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Native PHP Matrix
4+
~
5+
~ @copyright Copyright 2021, Lisachenko Alexander <[email protected]>
6+
~
7+
~ This source file is subject to the license that is bundled
8+
~ with this source code in the file LICENSE.
9+
~
10+
-->
11+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
12+
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
13+
colors="true"
14+
bootstrap="./vendor/autoload.php">
15+
<coverage>
16+
<include>
17+
<directory>./src/</directory>
18+
</include>
19+
<report>
20+
<clover outputFile="./build/logs/clover.xml"/>
21+
<crap4j outputFile="./build/logs/crap4j.xml"/>
22+
<xml outputDirectory="./build/coverage/xml"/>
23+
</report>
24+
</coverage>
25+
<testsuites>
26+
<testsuite name="Native PHP Matrix Test Suite">
27+
<directory suffix=".phpt">./tests/</directory>
28+
</testsuite>
29+
</testsuites>
30+
<groups>
31+
<exclude>
32+
<group>performance</group>
33+
</exclude>
34+
</groups>
35+
<logging>
36+
<junit outputFile="./build/logs/junit.xml"/>
37+
</logging>
38+
</phpunit>

src/Matrix.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ public function isSquare(): bool
6161
return $this->columns === $this->rows;
6262
}
6363

64+
public function toArray(): array
65+
{
66+
return $this->matrix;
67+
}
68+
6469
/**
6570
* Performs multiplication of two matrices
6671
*
@@ -162,13 +167,14 @@ public function powByScalar($value): self
162167
/**
163168
* Performs addition of two matrices
164169
*
165-
* @param Matrix $value
166-
*
167-
* @return $this Sum of two matrices
170+
* @return self Sum of two matrices
168171
* @todo: Implement SSE/AVX support for addition
169172
*/
170173
public function sum(self $value): self
171174
{
175+
if (($this->columns !== $value->columns) || ($this->rows !== $value->rows)) {
176+
throw new InvalidArgumentException('Inconsistent matrix supplied');
177+
}
172178
$result = [];
173179
for ($i = 0; $i < $this->rows; ++$i) {
174180
for ($k = 0; $k < $this->columns; ++$k) {
@@ -182,14 +188,16 @@ public function sum(self $value): self
182188
/**
183189
* Performs subtraction of two matrices
184190
*
185-
* @param Matrix $value
186-
*
187191
* @todo: Implement SSE/AVX support for addition
188192
*
189-
* @return $this Subtraction of two matrices
193+
* @return self Subtraction of two matrices
190194
*/
191195
public function subtract(self $value): self
192196
{
197+
if (($this->columns !== $value->columns) || ($this->rows !== $value->rows)) {
198+
throw new InvalidArgumentException('Inconsistent matrix supplied');
199+
}
200+
193201
$result = [];
194202
for ($i = 0; $i < $this->rows; ++$i) {
195203
for ($k = 0; $k < $this->columns; ++$k) {
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Matrices can be added with "+" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[1, 2, 3]]);
12+
$matrixB = new Matrix([[4, 5, 6]]);
13+
$result = $matrixA + $matrixB;
14+
var_dump($result->toArray());
15+
?>
16+
--EXPECT--
17+
array(1) {
18+
[0]=>
19+
array(3) {
20+
[0]=>
21+
int(5)
22+
[1]=>
23+
int(7)
24+
[2]=>
25+
int(9)
26+
}
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Matrix can be divided by a number with "/" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[2, 4, 6]]);
12+
$result = $matrixA / 2;
13+
var_dump($result->toArray());
14+
?>
15+
--EXPECT--
16+
array(1) {
17+
[0]=>
18+
array(3) {
19+
[0]=>
20+
int(1)
21+
[1]=>
22+
int(2)
23+
[2]=>
24+
int(3)
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Compatible matrices can be multiplied with "*" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[1, 2, 3]]);
12+
$matrixB = new Matrix([[4], [5], [6]]);
13+
$result = $matrixA * $matrixB;
14+
var_dump($result->toArray());
15+
?>
16+
--EXPECT--
17+
array(1) {
18+
[0]=>
19+
array(1) {
20+
[0]=>
21+
int(32)
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Matrix can be multiplied by a number with "*" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[1, 2, 3]]);
12+
$result = $matrixA * 3;
13+
var_dump($result->toArray());
14+
?>
15+
--EXPECT--
16+
array(1) {
17+
[0]=>
18+
array(3) {
19+
[0]=>
20+
int(3)
21+
[1]=>
22+
int(6)
23+
[2]=>
24+
int(9)
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Number can be multiplied by a matrix with "*" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[1, 2, 3]]);
12+
$result = 3 * $matrixA;
13+
var_dump($result->toArray());
14+
?>
15+
--EXPECT--
16+
array(1) {
17+
[0]=>
18+
array(3) {
19+
[0]=>
20+
int(3)
21+
[1]=>
22+
int(6)
23+
[2]=>
24+
int(9)
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Matrix can be raised to the power with "**" operator
3+
--FILE--
4+
<?php
5+
declare(strict_types=1);
6+
7+
use Lisachenko\NativePhpMatrix\Matrix;
8+
9+
include __DIR__ . '/../../vendor/autoload.php';
10+
11+
$matrixA = new Matrix([[1, 2, 3]]);
12+
$result = $matrixA ** 2;
13+
var_dump($result->toArray());
14+
?>
15+
--EXPECT--
16+
array(1) {
17+
[0]=>
18+
array(3) {
19+
[0]=>
20+
int(1)
21+
[1]=>
22+
int(4)
23+
[2]=>
24+
int(9)
25+
}
26+
}

0 commit comments

Comments
 (0)