From 283c3dfcb16f7418533f327c9b676c9caf064a39 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 20 Sep 2026 16:57:02 +0000 Subject: [PATCH] test: cover explicitly typed yesno object fields --- CHANGELOG.md | 5 +++++ docs/ADVANCED_STATIC_TYPING.md | 2 +- docs/CURRENT_STATUS.md | 1 + tests/test_validate_typecheck_diagnostics.py | 6 ++++++ tests/typecheck_object_field_typed_yesno_good.claro | 7 +++++++ tools/validate_typecheck_diagnostics.py | 1 + 6 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/typecheck_object_field_typed_yesno_good.claro diff --git a/CHANGELOG.md b/CHANGELOG.md index ff68fb2..12a8034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +### Validate explicitly typed YESNO object-field assignments + +- Added positive typecheck coverage for `SET player.ready YESNO YES` when the class declares `HAS ready YESNO`. +- Added the fixture to the complete typecheck validation matrix and documented the explicit annotation form. + ### Validate explicitly typed TEXT object-field assignments - Added positive typecheck coverage for `SET player.name TEXT "Ada"` when the class declares `HAS name TEXT`. diff --git a/docs/ADVANCED_STATIC_TYPING.md b/docs/ADVANCED_STATIC_TYPING.md index cb3f51f..a065bb4 100644 --- a/docs/ADVANCED_STATIC_TYPING.md +++ b/docs/ADVANCED_STATIC_TYPING.md @@ -945,7 +945,7 @@ Output: Object player is not known yet. Create it with NEW ClassName player before setting player.score. ``` -Both sides of this narrow field foundation are covered by validation: `tests/typecheck_object_field_good.claro` checks that `SET player.score 10` is accepted for a `HAS score NUMBER` field, `tests/typecheck_object_field_typed_good.claro` checks the explicit `NUMBER` annotation, `tests/typecheck_object_field_text_good.claro` checks that `SET player.name "Ada"` is accepted for a `HAS name TEXT` field, `tests/typecheck_object_field_typed_text_good.claro` checks the explicit `TEXT` annotation, `tests/typecheck_object_field_yesno_good.claro` checks that `SET player.ready YES` is accepted for a `HAS ready YESNO` field, `tests/typecheck_object_field_unknown_object_bad.claro` checks that `SET player.score 10` before `NEW Player player` reports the missing-object assignment diagnostic, `tests/typecheck_object_field_check_type_unknown_object_bad.claro` checks the matching missing-object `CHECK TYPE` diagnostic, and the remaining object-field fixtures cover known-field mismatches, unknown NUMBER/TEXT/YESNO fields, and unknown-field assignments whose value type is not inferable yet. +Both sides of this narrow field foundation are covered by validation: `tests/typecheck_object_field_good.claro` checks that `SET player.score 10` is accepted for a `HAS score NUMBER` field, `tests/typecheck_object_field_typed_good.claro` checks the explicit `NUMBER` annotation, `tests/typecheck_object_field_text_good.claro` checks that `SET player.name "Ada"` is accepted for a `HAS name TEXT` field, `tests/typecheck_object_field_typed_text_good.claro` checks the explicit `TEXT` annotation, `tests/typecheck_object_field_yesno_good.claro` checks that `SET player.ready YES` is accepted for a `HAS ready YESNO` field, and `tests/typecheck_object_field_typed_yesno_good.claro` checks the explicit `YESNO` annotation. `tests/typecheck_object_field_unknown_object_bad.claro` checks that `SET player.score 10` before `NEW Player player` reports the missing-object assignment diagnostic, `tests/typecheck_object_field_check_type_unknown_object_bad.claro` checks the matching missing-object `CHECK TYPE` diagnostic, and the remaining object-field fixtures cover known-field mismatches, unknown NUMBER/TEXT/YESNO fields, and unknown-field assignments whose value type is not inferable yet. This slice is intentionally small: it covers direct `NEW Class object` plus `SET object.field value` cases in one file. Field declarations are collected even when a learner writes a simple method before a later `HAS` field, so the type checker can still report the field's declared type. Broader object flows, aliases, method return checks, and richer object signatures remain future work. diff --git a/docs/CURRENT_STATUS.md b/docs/CURRENT_STATUS.md index 86be620..1882fa5 100644 --- a/docs/CURRENT_STATUS.md +++ b/docs/CURRENT_STATUS.md @@ -83,6 +83,7 @@ Ready now: - object creation now rejects repeated object names with a direct repair hint, so two `NEW Player player` statements cannot silently replace one another during type checking; when a script declares at least one class, a misspelled `NEW` class name gets a direct declaration hint without changing the older permissive no-class form; a missing class name or object name gets a direct example repair; extra words after the object name get a direct repair hint instead of being silently ignored - a narrow object-field assignment/check-type check for simple `NEW Class object` plus direct `SET object.field value` and `CHECK TYPE object.field IS TYPE` cases when the class declares `HAS field TYPE`; validation now covers correct NUMBER, TEXT, and YESNO direct assignments, dedicated positive and explicitly typed NUMBER/TEXT field assignments, explicitly typed method-body assignments to undeclared fields with a `HAS field TYPE` repair hint in modern and compatibility method syntax, dedicated positive NUMBER/TEXT/YESNO `CHECK TYPE` metadata fixtures, simple and chained object aliases for both field assignments and `CHECK TYPE` metadata (including a chained TEXT-field check), aliased object-method calls including chained aliases in modern `DO` and compatibility `CALL ... WITH` forms (with a dedicated positive modern `DO` chained-alias fixture), field-to-field, compound arithmetic field expressions, and arithmetic/text expression result types, negative NUMBER/TEXT/YESNO field `CHECK TYPE` metadata mismatches, NUMBER/TEXT/YESNO-expectation unknown-field `CHECK TYPE` diagnostics, missing-object field assignment and `CHECK TYPE` diagnostics, NUMBER/TEXT/YESNO wrong-type diagnostics, field collection when a `HAS` field appears after a simple method, NUMBER/TEXT/YESNO-valued unknown-field diagnostics for direct assignments to undeclared fields including explicitly typed assignments, numeric and text results from simple arithmetic/text expressions in object-field assignments, plus method-body field assignment and `CHECK TYPE` diagnostics for NUMBER, TEXT, and YESNO fields in modern and compatibility syntax, including compatibility YESNO `CHECK TYPE` metadata coverage, direct method assignments to undeclared fields now produce a beginner-facing missing-field diagnostic when the assigned expression has a known type, and a plain beginner-facing unknown-field diagnostic when the assigned expression is not inferable yet in both modern and compatibility method syntax; method-body `CHECK TYPE` now reports an unknown field with a repair hint in both method syntaxes, including compatibility `TAKES` / `LEARNED` methods; explicitly typed assignments to declared method fields now validate the class-declared field type instead of trusting only the inline type annotation, so a wrong value such as `SET score TEXT \"oops\"` reports the method and field in the diagnostic. - inline method-field annotations are checked against the class `HAS` declaration in modern and compatibility methods; conflicting known types and unknown annotation names produce field-specific repair guidance, with positive and negative focused fixtures for both syntaxes. +- Direct object-field validation also has positive coverage for explicit `NUMBER`, `TEXT`, and `YESNO` annotations, such as `SET player.ready YESNO YES`, while the shorter unannotated form remains supported. Still needed: - Keep the focused typecheck validator's fixture list complete as new positive and negative examples are added. `claro validate` now executes the complete focused fixture matrix as well, so release validation cannot silently omit a listed typecheck example. diff --git a/tests/test_validate_typecheck_diagnostics.py b/tests/test_validate_typecheck_diagnostics.py index d8809b3..451237f 100644 --- a/tests/test_validate_typecheck_diagnostics.py +++ b/tests/test_validate_typecheck_diagnostics.py @@ -45,6 +45,12 @@ class ValidateTypecheckDiagnosticsTests(unittest.TestCase): MODULE.EXPECTED_OK, ) + def test_includes_explicitly_typed_yesno_field_success_fixture(self): + self.assertIn( + "tests/typecheck_object_field_typed_yesno_good.claro", + MODULE.EXPECTED_OK, + ) + def test_includes_reverse_text_concatenation_success_fixture(self): self.assertIn( "tests/typecheck_object_field_text_concat_reverse_good.claro", diff --git a/tests/typecheck_object_field_typed_yesno_good.claro b/tests/typecheck_object_field_typed_yesno_good.claro new file mode 100644 index 0000000..51418c8 --- /dev/null +++ b/tests/typecheck_object_field_typed_yesno_good.claro @@ -0,0 +1,7 @@ +CLASS Player + HAS ready YESNO +END + +NEW Player player +SET player.ready YESNO YES +CHECK TYPE player.ready IS YESNO diff --git a/tools/validate_typecheck_diagnostics.py b/tools/validate_typecheck_diagnostics.py index 3714845..10c4fae 100644 --- a/tools/validate_typecheck_diagnostics.py +++ b/tools/validate_typecheck_diagnostics.py @@ -541,6 +541,7 @@ EXPECTED_OK = [ "tests/typecheck_object_field_good.claro", "tests/typecheck_object_field_typed_good.claro", "tests/typecheck_object_field_typed_text_good.claro", + "tests/typecheck_object_field_typed_yesno_good.claro", "tests/typecheck_object_field_expression_good.claro", "tests/typecheck_object_field_compound_good.claro", "tests/typecheck_object_field_subtraction_good.claro",