mt-lang 0.4.1 → 0.4.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/std/testing.mt DELETED
@@ -1,266 +0,0 @@
1
- # Standard library: testing core (T0 prototype)
2
- #
3
- # Minimal, in-language unit-testing surface — see docs/testing.md (§5, T0).
4
- # A test function returns `Check` and propagates the first failure with `?`:
5
- #
6
- # import std.testing as t
7
- #
8
- # function test_math() -> t.Check:
9
- # t.expect_equal_int(2 + 2, 4)?
10
- # return t.ok()
11
- #
12
- # A hand-written runner (see docs/testing.md §6 for future compiler-driven
13
- # discovery) calls `record` per test and `summarize` at the end:
14
- #
15
- # function main() -> int:
16
- # var stats = t.Stats.create()
17
- # stats = t.record(stats, "math", test_math())
18
- # return t.summarize(stats)
19
-
20
- import std.string as string
21
- import std.fmt as fmt
22
- import std.stdio as stdio
23
- import std.str
24
- import std.hash
25
-
26
- # A test outcome: success carries no meaningful value; failure carries a
27
- # `Failure`. `Result` is used (not a bespoke variant) so `?` propagation works.
28
-
29
- # A failed (or skipped) expectation. `message` is owned and must be released by
30
- # whoever consumes it (the runner does this in `record`). `is_skip` distinguishes
31
- # a skip from a real assertion failure.
32
- public struct Failure:
33
- message: string.String
34
- is_skip: bool
35
-
36
- public type Check = Result[bool, Failure]
37
-
38
-
39
- # Tally of outcomes for a run. Value type; `record` returns an updated copy.
40
- public struct Stats:
41
- passed: int
42
- failed: int
43
- skipped: int
44
-
45
-
46
- extending Stats:
47
- public static function create() -> Stats:
48
- return Stats(passed = 0, failed = 0, skipped = 0)
49
-
50
-
51
- # ── Outcome constructors ──────────────────────────────────────────────────
52
-
53
- public function ok() -> Check:
54
- return Result[bool, Failure].success(value = true)
55
-
56
-
57
- public function fail(message: str) -> Check:
58
- return Result[bool, Failure].failure(error = Failure(message = string.String.from_str(message), is_skip = false))
59
-
60
-
61
- public function skip(reason: str) -> Check:
62
- return Result[bool, Failure].failure(error = Failure(message = string.String.from_str(reason), is_skip = true))
63
-
64
-
65
- # ── Expectations ──────────────────────────────────────────────────────────
66
-
67
- public function expect(condition: bool, message: str) -> Check:
68
- if condition:
69
- return ok()
70
-
71
- return fail(message)
72
-
73
-
74
- public function expect_true(condition: bool) -> Check:
75
- return expect(condition, "expected true")
76
-
77
-
78
- public function expect_false(condition: bool) -> Check:
79
- return expect(not condition, "expected false")
80
-
81
-
82
- public function expect_equal_int(actual: int, expected: int) -> Check:
83
- if actual == expected:
84
- return ok()
85
-
86
- var message = string.String.create()
87
- message.append("expected ")
88
- fmt.append_int(ref_of(message), expected)
89
- message.append(", got ")
90
- fmt.append_int(ref_of(message), actual)
91
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
92
-
93
-
94
- public function expect_equal_str(actual: str, expected: str) -> Check:
95
- var actual_string = string.String.from_str(actual)
96
- var expected_string = string.String.from_str(expected)
97
- let same = actual_string.equal(expected_string)
98
- actual_string.release()
99
- expected_string.release()
100
- if same:
101
- return ok()
102
-
103
- var message = string.String.create()
104
- message.append("expected [")
105
- message.append(expected)
106
- message.append("], got [")
107
- message.append(actual)
108
- message.append("]")
109
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
110
-
111
-
112
- public function expect_equal_bool(actual: bool, expected: bool) -> Check:
113
- if actual == expected:
114
- return ok()
115
-
116
- var message = string.String.create()
117
- message.append("expected ")
118
- fmt.append_bool(ref_of(message), expected)
119
- message.append(", got ")
120
- fmt.append_bool(ref_of(message), actual)
121
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
122
-
123
-
124
- public function expect_not_equal_int(actual: int, expected: int) -> Check:
125
- if actual != expected:
126
- return ok()
127
-
128
- var message = string.String.create()
129
- message.append("expected not ")
130
- fmt.append_int(ref_of(message), expected)
131
- message.append(", got ")
132
- fmt.append_int(ref_of(message), actual)
133
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
134
-
135
-
136
- public function expect_not_equal_str(actual: str, expected: str) -> Check:
137
- var actual_string = string.String.from_str(actual)
138
- var expected_string = string.String.from_str(expected)
139
- let same = actual_string.equal(expected_string)
140
- actual_string.release()
141
- expected_string.release()
142
- if not same:
143
- return ok()
144
-
145
- var message = string.String.create()
146
- message.append("expected not [")
147
- message.append(expected)
148
- message.append("], got [")
149
- message.append(actual)
150
- message.append("]")
151
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
152
-
153
-
154
- public function expect_not_equal_bool(actual: bool, expected: bool) -> Check:
155
- if actual != expected:
156
- return ok()
157
-
158
- var message = string.String.create()
159
- message.append("expected not ")
160
- fmt.append_bool(ref_of(message), expected)
161
- message.append(", got ")
162
- fmt.append_bool(ref_of(message), actual)
163
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
164
-
165
-
166
- # Generic equality over any type with a canonical `T.equal` hook: primitives
167
- # (import std.hash), `str` (import std.str), and user structs that define `equal`
168
- # (or delegate to std.hash.equal_struct). On failure the actual/expected values
169
- # are rendered via `std.fmt.format_value`, so `T` must be a primitive or a struct
170
- # whose fields are themselves `format_value`-renderable.
171
- public function expect_equal[T](actual: T, expected: T) -> Check:
172
- if equal[T](actual, expected):
173
- return ok()
174
-
175
- var message = string.String.create()
176
- message.append("expected ")
177
- fmt.format_value[T](ref_of(message), const_ptr_of(expected))
178
- message.append(", got ")
179
- fmt.format_value[T](ref_of(message), const_ptr_of(actual))
180
- return Result[bool, Failure].failure(error = Failure(message = message, is_skip = false))
181
-
182
-
183
- public function expect_some[T](option: Option[T]) -> Check:
184
- if option.is_some():
185
- return ok()
186
-
187
- return fail("expected Option.some, got Option.none")
188
-
189
-
190
- public function expect_none[T](option: Option[T]) -> Check:
191
- if option.is_none():
192
- return ok()
193
-
194
- return fail("expected Option.none, got Option.some")
195
-
196
-
197
- public function expect_null[T](pointer: const_ptr[T]?) -> Check:
198
- if pointer == null:
199
- return ok()
200
-
201
- return fail("expected null pointer, got non-null")
202
-
203
-
204
- public function expect_not_null[T](pointer: const_ptr[T]?) -> Check:
205
- if pointer != null:
206
- return ok()
207
-
208
- return fail("expected non-null pointer, got null")
209
-
210
-
211
- public function expect_error[T, E](result: Result[T, E]) -> Check:
212
- if result.is_failure():
213
- return ok()
214
-
215
- return fail("expected Result.failure, got Result.success")
216
-
217
-
218
- # ── Runner (hand-written; compiler discovery is a later phase) ─────────────
219
-
220
- public function record(stats: Stats, name: str, outcome: Check) -> Stats:
221
- match outcome:
222
- Result.success:
223
- var line = string.String.create()
224
- line.append("ok - ")
225
- line.append(name)
226
- stdio.print_line(line.as_str())
227
- line.release()
228
- return Stats(passed = stats.passed + 1, failed = stats.failed, skipped = stats.skipped)
229
- Result.failure as payload:
230
- let failure = payload.error
231
- var line = string.String.create()
232
- if failure.is_skip:
233
- line.append("skip - ")
234
- else:
235
- line.append("FAIL - ")
236
-
237
- line.append(name)
238
- line.append(": ")
239
- line.append(failure.message.as_str())
240
- stdio.print_line(line.as_str())
241
- line.release()
242
-
243
- var owned_message = failure.message
244
- owned_message.release()
245
-
246
- if failure.is_skip:
247
- return Stats(passed = stats.passed, failed = stats.failed, skipped = stats.skipped + 1)
248
-
249
- return Stats(passed = stats.passed, failed = stats.failed + 1, skipped = stats.skipped)
250
-
251
-
252
- public function summarize(stats: Stats) -> int:
253
- var line = string.String.create()
254
- line.append("passed=")
255
- fmt.append_int(ref_of(line), stats.passed)
256
- line.append(" failed=")
257
- fmt.append_int(ref_of(line), stats.failed)
258
- line.append(" skipped=")
259
- fmt.append_int(ref_of(line), stats.skipped)
260
- stdio.print_line(line.as_str())
261
- line.release()
262
-
263
- if stats.failed > 0:
264
- return 1
265
-
266
- return 0