My attempts at exercism.org
1<?php
2
3use PHPUnit\Framework\TestCase;
4use PHPUnit\Framework\Attributes\TestDox;
5
6class ProgramWindowTest extends TestCase
7{
8 public static function setUpBeforeClass(): void
9 {
10 require_once 'ProgramWindow.php';
11 require_once 'Size.php';
12 require_once 'Position.php';
13 }
14
15 /**
16 * @task_id 1
17 */
18 #[TestDox('assert ProgramWindow has a $y property')]
19 public function testHasPropertyY()
20 {
21 $reflector = new ReflectionClass(ProgramWindow::class);
22 $this->assertHasProperty($reflector, 'y', [
23 'has_type' => false,
24 'has_default' => false
25 ]);
26 }
27
28 /**
29 * @task_id 1
30 */
31 #[TestDox('assert ProgramWindow has a $x property')]
32 public function testHasPropertyX()
33 {
34 $reflector = new ReflectionClass(ProgramWindow::class);
35 $this->assertHasProperty($reflector, 'x', [
36 'has_type' => false,
37 'has_default' => false
38 ]);
39 }
40
41 /**
42 * @task_id 1
43 */
44 #[TestDox('assert ProgramWindow has a $height property')]
45 public function testHasPropertyHeight()
46 {
47 $reflector = new ReflectionClass(ProgramWindow::class);
48 $this->assertHasProperty($reflector, 'height', [
49 'has_type' => false,
50 'has_default' => false
51 ]);
52 }
53
54 /**
55 * @task_id 1
56 */
57 #[TestDox('assert ProgramWindow has a $width property')]
58 public function testHasPropertyWidth()
59 {
60 $reflector = new ReflectionClass(ProgramWindow::class);
61 $this->assertHasProperty($reflector, 'width', [
62 'has_type' => false,
63 'has_default' => false
64 ]);
65 }
66
67 /**
68 * @task_id 2
69 */
70 #[TestDox('assert ProgramWindow has a constructor initial values')]
71 public function testHasConstructorSettingInitialValues()
72 {
73 $window = new ProgramWindow();
74 $this->assertEquals(0, $window->y);
75 $this->assertEquals(0, $window->x);
76 $this->assertEquals(600, $window->height);
77 $this->assertEquals(800, $window->width);
78 }
79
80 /**
81 * @task_id 3
82 */
83 #[TestDox('assert Position class exists, with constructor, properties')]
84 public function testSizeHasConstructorSettingInitialValues()
85 {
86 $size = new Size(300, 700);
87 $this->assertEquals(300, $size->height);
88 $this->assertEquals(700, $size->width);
89 }
90
91 /**
92 * @task_id 3
93 */
94 #[TestDox('assert ProgramWindow::resize function exists')]
95 public function testProgramWindowResize()
96 {
97 $window = new ProgramWindow();
98 $size = new Size(430, 2135);
99 $window->resize($size);
100 $this->assertEquals(430, $window->height);
101 $this->assertEquals(2135, $window->width);
102 }
103
104 /**
105 * @task_id 4
106 */
107 #[TestDox('assert Position class exists, with constructor, properties')]
108 public function testPositionHasConstructorSettingInitialValues()
109 {
110 $position = new Position(30, 70);
111 $this->assertEquals(30, $position->y);
112 $this->assertEquals(70, $position->x);
113 }
114
115 /**
116 * @task_id 4
117 */
118 #[TestDox('assert ProgramWindow::move function exists')]
119 public function testProgramWindowMove()
120 {
121 $window = new ProgramWindow();
122 $position = new Position(40, 235);
123 $window->move($position);
124 $this->assertEquals(40, $window->y);
125 $this->assertEquals(235, $window->x);
126 }
127
128 private function assertHasProperty(
129 ReflectionClass $class,
130 string $name,
131 array $assertions = []
132 ) {
133 $assertions = array_merge([
134 'has_type' => false,
135 'has_default_value' => false
136 ], $assertions);
137
138 try {
139 $property = $class->getProperty($name);
140 } catch (ReflectionException) {
141 $this->fail(
142 "Property '$name' missing from class '{$class->getName()}'"
143 );
144 };
145
146 if ($assertions['has_type']) {
147 $this->assertTrue($property->hasType());
148 } else {
149 $this->assertFalse(
150 $property->hasType(),
151 "Property '$name' should not have a type declared"
152 );
153 }
154
155 if ($assertions['has_default_value']) {
156 $this->assertTrue($property->hasDefaultValue());
157 } else {
158 if ($assertions['has_type'] === false) {
159 $this->assertTrue($property->hasDefaultValue());
160 $this->assertNull($property->getDefaultValue());
161 } else {
162 $this->assertFalse(
163 $property->hasDefaultValue(),
164 "Property '$name' should not have a default value declared"
165 );
166 }
167 }
168 }
169}