Skip to content

Commit

Permalink
Merge pull request #498 from savi-lang/fix/trace-data-mutable-bool
Browse files Browse the repository at this point in the history
Fix tracing of `Bool` in `TraceData.Mutable`.
  • Loading branch information
jemc authored Sep 7, 2024
2 parents 32e8caa + 1e4f91a commit fcbb91c
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
2 changes: 1 addition & 1 deletion core/TraceData.savi
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@
:: Set the new value from the yield block (if the mutator decides to call it).
:fun ref replace_bool(value Bool) None
:yields Bool for None // TODO: add a "without interruption" enforcement to the yield signature to ensure that the yield block isn't allowed to jump away.
None
@set_bool -> (v | yield v)

:: Allow the mutator the option to replace a `U64` at the current location,
:: passing it the current value as an argument (to use as a reference).
Expand Down
130 changes: 130 additions & 0 deletions spec/core/TraceData.Mutable.Spec.savi
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,81 @@
age: 0
>>>

:it "can inject every type of primitive value"
example = _ExampleMutableEachPrimitive.new

mut_bool = _TraceMutatorInject(Bool).new("bool", True)
example.trace_data_mutable(mut_bool)
assert: mut_bool.errors == []

mut_u64 = _TraceMutatorInject(U64).new("u64", 0x1234567890ABCDEF)
example.trace_data_mutable(mut_u64)
assert: mut_u64.errors == []

mut_u32 = _TraceMutatorInject(U32).new("u32", 0x12345678)
example.trace_data_mutable(mut_u32)
assert: mut_u32.errors == []

mut_u16 = _TraceMutatorInject(U16).new("u16", 0x1234)
example.trace_data_mutable(mut_u16)
assert: mut_u16.errors == []

mut_u8 = _TraceMutatorInject(U8).new("u8", 0x12)
example.trace_data_mutable(mut_u8)
assert: mut_u8.errors == []

mut_i64 = _TraceMutatorInject(I64).new("i64", -99)
example.trace_data_mutable(mut_i64)
assert: mut_i64.errors == []

mut_i32 = _TraceMutatorInject(I32).new("i32", -98)
example.trace_data_mutable(mut_i32)
assert: mut_i32.errors == []

mut_i16 = _TraceMutatorInject(I16).new("i16", -97)
example.trace_data_mutable(mut_i16)
assert: mut_i16.errors == []

mut_i8 = _TraceMutatorInject(I8).new("i8", -96)
example.trace_data_mutable(mut_i8)
assert: mut_i8.errors == []

mut_f64 = _TraceMutatorInject(F64).new("f64", 3.14159)
example.trace_data_mutable(mut_f64)
assert: mut_f64.errors == []

mut_f32 = _TraceMutatorInject(F32).new("f32", 1.5)
example.trace_data_mutable(mut_f32)
assert: mut_f32.errors == []

mut_bytes = _TraceMutatorInject(Bytes).new("bytes", b"Hello")
example.trace_data_mutable(mut_bytes)
assert: mut_bytes.errors == []

mut_string = _TraceMutatorInject(String).new("string", "World")
example.trace_data_mutable(mut_string)
assert: mut_string.errors == []

// The changes are reflected in the printed trace.
example_printed = String.new
example.trace_data(Inspect.TraceData.Printer.Deterministic.new(example_printed))
assert: example_printed == <<<
#1:
bool: True
u64: 1311768467294899695
u32: 305419896
u16: 4660
u8: 18
i64: -99
i32: -98
i16: -97
i8: -96
f64: 3.14159
f32: 1.5
bytes: b"Hello"
string: "World"
>>>

:: A test class demonstrating a simple data structure that can be mutated
:: by any `TraceData.Mutator` using the `TraceData.Mutable` trait.
:class _ExampleMutablePerson
Expand Down Expand Up @@ -71,6 +146,61 @@
)
)

:: A test class demonstrating a every primitive that can be mutably replaced.
:class _ExampleMutableEachPrimitive
:var bool Bool: False
:var u64 U64: 0
:var u32 U32: 0
:var u16 U16: 0
:var u8 U8: 0
:var i64 I64: 0
:var i32 I32: 0
:var i16 I16: 0
:var i8 I8: 0
:var f64 F64: 0.0
:var f32 F32: 0.0
:var bytes Bytes: b""
:var string String: ""

:is TraceData
:fun trace_data(trace TraceData.Observer)
trace.object(identity_digest_of @) -> (
trace.property("bool", @bool)
trace.property("u64", @u64)
trace.property("u32", @u32)
trace.property("u16", @u16)
trace.property("u8", @u8)
trace.property("i64", @i64)
trace.property("i32", @i32)
trace.property("i16", @i16)
trace.property("i8", @i8)
trace.property("f64", @f64)
trace.property("f32", @f32)
trace.property("bytes", @bytes)
trace.property("string", @string)
)

:is TraceData.Mutable
:fun ref trace_data_mutable(trace TraceData.Mutator)
trace.object(identity_digest_of @) -> (key |
case key == (
| "bool" | trace.replace_bool(@bool) -> (v | @bool = v)
| "u64" | trace.replace_u64(@u64) -> (v | @u64 = v)
| "u32" | trace.replace_u32(@u32) -> (v | @u32 = v)
| "u16" | trace.replace_u16(@u16) -> (v | @u16 = v)
| "u8" | trace.replace_u8(@u8) -> (v | @u8 = v)
| "i64" | trace.replace_i64(@i64) -> (v | @i64 = v)
| "i32" | trace.replace_i32(@i32) -> (v | @i32 = v)
| "i16" | trace.replace_i16(@i16) -> (v | @i16 = v)
| "i8" | trace.replace_i8(@i8) -> (v | @i8 = v)
| "f64" | trace.replace_f64(@f64) -> (v | @f64 = v)
| "f32" | trace.replace_f32(@f32) -> (v | @f32 = v)
| "bytes" | trace.replace_bytes(@bytes) -> (v | @bytes = v)
| "string" | trace.replace_string(@string) -> (v | @string = v)
| trace.object_key_is_invalid
)
)

:: A test class used to demonstrate how a `TraceData.Mutator` implementation
:: can be used to inject a single value into an arbitrary object tree path,
:: as long as all the objects along that path implement `TraceData.Mutable`.
Expand Down

0 comments on commit fcbb91c

Please sign in to comment.