Skip to content

Commit 947a9bf

Browse files
author
nejc
committed
test: add tests for IntArray, Json, Struct, Union, Dictionary, and ListData
1 parent 85895f8 commit 947a9bf

File tree

3 files changed

+233
-51
lines changed

3 files changed

+233
-51
lines changed

Tests/IntArrayTest.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nejcc\PhpDatatypes\Composite\Arrays\IntArray;
6+
use PHPUnit\Framework\TestCase;
7+
8+
class IntArrayTest extends TestCase
9+
{
10+
public function testConstructionAndGet(): void
11+
{
12+
$arr = new IntArray([1, 2, 3, 4]);
13+
$this->assertSame(1, $arr->get(0));
14+
$this->assertSame(4, $arr->get(3));
15+
}
16+
17+
public function testSetAndGet(): void
18+
{
19+
$arr = new IntArray([1, 2, 3]);
20+
$arr->set(1, 42);
21+
$this->assertSame(42, $arr->get(1));
22+
}
23+
24+
public function testCount(): void
25+
{
26+
$arr = new IntArray([1, 2, 3, 4, 5]);
27+
$this->assertCount(5, $arr);
28+
}
29+
30+
public function testIteration(): void
31+
{
32+
$arr = new IntArray([10, 20, 30]);
33+
$result = [];
34+
foreach ($arr as $value) {
35+
$result[] = $value;
36+
}
37+
$this->assertSame([10, 20, 30], $result);
38+
}
39+
40+
public function testToArray(): void
41+
{
42+
$arr = new IntArray([7, 8, 9]);
43+
$this->assertSame([7, 8, 9], $arr->toArray());
44+
}
45+
46+
public function testInvalidIndexGet(): void
47+
{
48+
$arr = new IntArray([1, 2, 3]);
49+
$this->expectException(\OutOfRangeException::class);
50+
$arr->get(10);
51+
}
52+
53+
public function testInvalidIndexSet(): void
54+
{
55+
$arr = new IntArray([1, 2, 3]);
56+
$this->expectException(\OutOfRangeException::class);
57+
$arr->set(10, 5);
58+
}
59+
60+
public function testInvalidValueType(): void
61+
{
62+
$arr = new IntArray([1, 2, 3]);
63+
$this->expectException(\TypeError::class);
64+
$arr->set(0, 'not an int');
65+
}
66+
67+
public function testAppend(): void
68+
{
69+
$arr = new IntArray([1, 2]);
70+
$arr->append(3);
71+
$this->assertSame([1, 2, 3], $arr->toArray());
72+
}
73+
74+
public function testAppendInvalidType(): void
75+
{
76+
$arr = new IntArray([1, 2, 3]);
77+
$this->expectException(\TypeError::class);
78+
$arr->append('not an int');
79+
}
80+
}

Tests/JsonTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nejcc\PhpDatatypes\Composite\Json;
6+
use Nejcc\PhpDatatypes\Interfaces\EncoderInterface;
7+
use Nejcc\PhpDatatypes\Interfaces\DecoderInterface;
8+
use PHPUnit\Framework\TestCase;
9+
10+
class JsonTest extends TestCase
11+
{
12+
public function testValidJsonConstruction(): void
13+
{
14+
$json = new Json('{"a":1,"b":2}');
15+
$this->assertSame('{"a":1,"b":2}', $json->getJson());
16+
}
17+
18+
public function testInvalidJsonThrows(): void
19+
{
20+
$this->expectException(InvalidArgumentException::class);
21+
new Json('{invalid json}');
22+
}
23+
24+
public function testToArrayAndToObject(): void
25+
{
26+
$json = new Json('{"a":1,"b":2}');
27+
$this->assertSame(['a' => 1, 'b' => 2], $json->toArray());
28+
$obj = $json->toObject();
29+
$this->assertIsObject($obj);
30+
$this->assertEquals(1, $obj->a);
31+
$this->assertEquals(2, $obj->b);
32+
}
33+
34+
public function testFromArrayAndFromObject(): void
35+
{
36+
$arr = ['x' => 10, 'y' => 20];
37+
$json = Json::fromArray($arr);
38+
$this->assertSame($arr, $json->toArray());
39+
40+
$obj = (object)['foo' => 'bar'];
41+
$json2 = Json::fromObject($obj);
42+
$this->assertSame(['foo' => 'bar'], $json2->toArray());
43+
}
44+
45+
public function testCompressAndDecompress(): void
46+
{
47+
$json = new Json('{"a":1}');
48+
$encoder = new class implements EncoderInterface {
49+
public function encode(string $data): string { return base64_encode($data); }
50+
};
51+
$decoder = new class implements DecoderInterface {
52+
public function decode(string $data): string { return base64_decode($data); }
53+
};
54+
$compressed = $json->compress($encoder);
55+
$this->assertSame(base64_encode('{"a":1}'), $compressed);
56+
$decompressed = Json::decompress($decoder, $compressed);
57+
$this->assertSame(['a' => 1], $decompressed->toArray());
58+
}
59+
60+
public function testMerge(): void
61+
{
62+
$json1 = new Json('{"a":1,"b":2}');
63+
$json2 = new Json('{"b":3,"c":4}');
64+
$merged = $json1->merge($json2);
65+
$this->assertSame(['a' => 1, 'b' => [2, 3], 'c' => 4], $merged->toArray());
66+
}
67+
68+
public function testUpdateAndRemove(): void
69+
{
70+
$json = new Json('{"a":1,"b":2}');
71+
$updated = $json->update('b', 99);
72+
$this->assertSame(['a' => 1, 'b' => 99], $updated->toArray());
73+
$removed = $updated->remove('a');
74+
$this->assertSame(['b' => 99], $removed->toArray());
75+
}
76+
77+
public function testFromArrayInvalid(): void
78+
{
79+
$this->expectException(JsonException::class);
80+
Json::fromArray(["bad" => fopen('php://memory', 'r')]);
81+
}
82+
}

Tests/StructTest.php

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,87 +10,107 @@
1010

1111
class StructTest extends TestCase
1212
{
13-
public function testStructSetAndGet()
13+
public function testConstructionAndFieldRegistration(): void
1414
{
15-
// Example 1
1615
$struct = new Struct([
16+
'id' => 'int',
1717
'name' => 'string',
18-
'age' => '?int',
19-
'balance' => 'float',
2018
]);
21-
22-
// Test setting and getting field values using set/get methods
23-
$struct->set('name', 'Nejc');
24-
$struct->set('age', null); // Nullable type
25-
$struct->set('balance', 100.50);
26-
27-
// Assertions
28-
$this->assertEquals('Nejc', $struct->get('name'));
29-
$this->assertNull($struct->get('age'));
30-
$this->assertEquals(100.50, $struct->get('balance'));
19+
$fields = $struct->getFields();
20+
$this->assertArrayHasKey('id', $fields);
21+
$this->assertArrayHasKey('name', $fields);
22+
$this->assertSame('int', $fields['id']['type']);
23+
$this->assertSame('string', $fields['name']['type']);
24+
$this->assertNull($fields['id']['value']);
25+
$this->assertNull($fields['name']['value']);
3126
}
3227

33-
public function testMagicMethods()
28+
public function testSetAndGet(): void
3429
{
35-
// Example 1 with magic methods
3630
$struct = new Struct([
31+
'id' => 'int',
3732
'name' => 'string',
38-
'age' => '?int',
39-
'balance' => 'float',
4033
]);
41-
42-
// Test setting and getting field values using magic methods
43-
$struct->name = 'John';
44-
$struct->age = null;
45-
$struct->balance = 200.75;
46-
47-
// Assertions
48-
$this->assertEquals('John', $struct->name);
49-
$this->assertNull($struct->age);
50-
$this->assertEquals(200.75, $struct->balance);
34+
$struct->set('id', 42);
35+
$struct->set('name', 'Alice');
36+
$this->assertSame(42, $struct->get('id'));
37+
$this->assertSame('Alice', $struct->get('name'));
5138
}
5239

53-
public function testStructHelperFunction()
40+
public function testSetWrongTypeThrows(): void
5441
{
55-
// Example 2: using the `struct()` helper function (assuming it is defined)
56-
$struct = struct([
57-
'name' => 'string',
58-
'age' => '?int',
59-
'balance' => 'float',
42+
$struct = new Struct([
43+
'id' => 'int',
6044
]);
45+
$this->expectException(InvalidArgumentException::class);
46+
$struct->set('id', 'not an int');
47+
}
6148

62-
// Test setting and getting field values using set/get methods
63-
$struct->set('name', 'Test');
64-
$struct->set('age', null);
65-
$struct->set('balance', 100.50);
49+
public function testSetNullableField(): void
50+
{
51+
$struct = new Struct([
52+
'desc' => '?string',
53+
]);
54+
$struct->set('desc', null);
55+
$this->assertNull($struct->get('desc'));
56+
$struct->set('desc', 'hello');
57+
$this->assertSame('hello', $struct->get('desc'));
58+
}
6659

67-
// Assertions
68-
$this->assertEquals('Test', $struct->get('name'));
69-
$this->assertNull($struct->get('age'));
70-
$this->assertEquals(100.50, $struct->get('balance'));
60+
public function testSetNonNullableFieldNullThrows(): void
61+
{
62+
$struct = new Struct([
63+
'id' => 'int',
64+
]);
65+
$this->expectException(InvalidArgumentException::class);
66+
$struct->set('id', null);
7167
}
7268

73-
public function testInvalidFieldThrowsException()
69+
public function testSetSubclass(): void
7470
{
7571
$struct = new Struct([
76-
'name' => 'string',
72+
'obj' => 'stdClass',
7773
]);
74+
$obj = new class extends \stdClass {};
75+
$struct->set('obj', $obj);
76+
$this->assertSame($obj, $struct->get('obj'));
77+
}
7878

79+
public function testGetNonexistentFieldThrows(): void
80+
{
81+
$struct = new Struct([
82+
'id' => 'int',
83+
]);
7984
$this->expectException(InvalidArgumentException::class);
80-
$this->expectExceptionMessage("Field 'age' does not exist in the struct.");
81-
82-
$struct->set('age', 25); // This should throw an exception
85+
$struct->get('missing');
8386
}
8487

85-
public function testInvalidTypeThrowsException()
88+
public function testSetNonexistentFieldThrows(): void
8689
{
8790
$struct = new Struct([
88-
'name' => 'string',
91+
'id' => 'int',
8992
]);
93+
$this->expectException(InvalidArgumentException::class);
94+
$struct->set('missing', 123);
95+
}
9096

97+
public function testDuplicateFieldThrows(): void
98+
{
9199
$this->expectException(InvalidArgumentException::class);
92-
$this->expectExceptionMessage("Field 'name' expects type 'string', but got 'int'.");
100+
// Simulate duplicate by calling addField directly via reflection
101+
$struct = new Struct(['id' => 'int']);
102+
$ref = new \ReflectionClass($struct);
103+
$method = $ref->getMethod('addField');
104+
$method->setAccessible(true);
105+
$method->invoke($struct, 'id', 'int');
106+
}
93107

94-
$struct->set('name', 123); // Invalid type
108+
public function testMagicGetSet(): void
109+
{
110+
$struct = new Struct([
111+
'foo' => 'int',
112+
]);
113+
$struct->foo = 123;
114+
$this->assertSame(123, $struct->foo);
95115
}
96116
}

0 commit comments

Comments
 (0)