1+ /*
2+ * NextFTC: a user-friendly control library for FIRST Tech Challenge
3+ * Copyright (C) 2025 Rowan McAlpin
4+ *
5+ * This program is free software: you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation, either version 3 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17+ */
18+
19+ package dev.nextftc.nextcontrol
20+
21+ import io.kotest.core.spec.style.FunSpec
22+ import io.kotest.matchers.shouldBe
23+ import io.kotest.property.Arb
24+ import io.kotest.property.arbitrary.double
25+ import io.kotest.property.checkAll
26+ import dev.nextftc.nextcontrol.test.kineticStateGen
27+
28+ class KineticStateTest : FunSpec ({
29+
30+ context("KineticState constructor") {
31+ test("default values should be zeros") {
32+ val state = KineticState ()
33+ state.position shouldBe 0.0
34+ state.velocity shouldBe 0.0
35+ state.acceleration shouldBe 0.0
36+ }
37+
38+ test("constructor should set values correctly") {
39+ val state = KineticState (1.0, 2.0, 3.0)
40+ state.position shouldBe 1.0
41+ state.velocity shouldBe 2.0
42+ state.acceleration shouldBe 3.0
43+ }
44+
45+ test("partial constructor should set provided values and default others") {
46+ val state = KineticState (position = 1.0)
47+ state.position shouldBe 1.0
48+ state.velocity shouldBe 0.0
49+ state.acceleration shouldBe 0.0
50+
51+ val state2 = KineticState (position = 1.0, velocity = 2.0)
52+ state2.position shouldBe 1.0
53+ state2.velocity shouldBe 2.0
54+ state2.acceleration shouldBe 0.0
55+ }
56+ }
57+
58+ context("KineticState operators") {
59+ test("plus operator should add components") {
60+ val state1 = KineticState (1.0, 2.0, 3.0)
61+ val state2 = KineticState (4.0, 5.0, 6.0)
62+ val result = state1 + state2
63+
64+ result.position shouldBe 5.0
65+ result.velocity shouldBe 7.0
66+ result.acceleration shouldBe 9.0
67+ }
68+
69+ test("minus operator should subtract components") {
70+ val state1 = KineticState (5.0, 7.0, 9.0)
71+ val state2 = KineticState (1.0, 2.0, 3.0)
72+ val result = state1 - state2
73+
74+ result.position shouldBe 4.0
75+ result.velocity shouldBe 5.0
76+ result.acceleration shouldBe 6.0
77+ }
78+
79+ test("times operator should multiply by scalar") {
80+ val state = KineticState (1.0, 2.0, 3.0)
81+ val scalar = 2.0
82+ val result = state * scalar
83+
84+ result.position shouldBe 2.0
85+ result.velocity shouldBe 4.0
86+ result.acceleration shouldBe 6.0
87+ }
88+ }
89+
90+ context("Property -based testing") {
91+ test("plus is commutative") {
92+ checkAll(kineticStateGen, kineticStateGen) { a, b ->
93+ val result1 = a + b
94+ val result2 = b + a
95+
96+ result1.position shouldBe result2.position
97+ result1.velocity shouldBe result2.velocity
98+ result1.acceleration shouldBe result2.acceleration
99+ }
100+ }
101+
102+ test("plus and minus are inverse operations") {
103+ checkAll(kineticStateGen, kineticStateGen) { a, b ->
104+ val result = (a + b) - b
105+
106+ result.position shouldBe a.position
107+ result.velocity shouldBe a.velocity
108+ result.acceleration shouldBe a.acceleration
109+ }
110+ }
111+
112+ test("multiplying by 1 doesn't change the state") {
113+ checkAll(kineticStateGen) { state ->
114+ val result = state * 1.0
115+
116+ result.position shouldBe state.position
117+ result.velocity shouldBe state.velocity
118+ result.acceleration shouldBe state.acceleration
119+ }
120+ }
121+
122+ test("multiplying by 0 results in all zeros") {
123+ checkAll(kineticStateGen) { state ->
124+ val result = state * 0.0
125+
126+ result.position shouldBe 0.0
127+ result.velocity shouldBe 0.0
128+ result.acceleration shouldBe 0.0
129+ }
130+ }
131+ }
132+ })
0 commit comments