test: add object field positive typecheck fixture

This commit is contained in:
Hermes Agent
2026-06-16 03:06:10 -06:00
parent 2636d2ab8c
commit 23d65d21f3
7 changed files with 17 additions and 3 deletions
+5
View File
@@ -1,5 +1,10 @@
# Changelog # Changelog
## v1.18.26-dev object field positive validation
- Added a focused positive `claro typecheck` fixture for direct object-field assignment: `NEW Player player` followed by `SET player.score 10` when the class declares `HAS score NUMBER`.
- Wired the positive object-field fixture into both the typecheck diagnostics validator and `claro validate`, complementing the existing wrong-type field diagnostic fixture.
## v1.18.26-dev object field assignment diagnostics ## v1.18.26-dev object field assignment diagnostics
- Added a narrow `claro typecheck` diagnostic for direct wrong-type object field assignment after `NEW Class object`, such as `SET player.score "ten"` when `HAS score NUMBER` is known. - Added a narrow `claro typecheck` diagnostic for direct wrong-type object field assignment after `NEW Class object`, such as `SET player.score "ten"` when `HAS score NUMBER` is known.
+2
View File
@@ -150,6 +150,8 @@ Output:
Type mismatch for field player.score: expected NUMBER, but this value looks like TEXT. Type mismatch for field player.score: expected NUMBER, but this value looks like TEXT.
``` ```
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, and `tests/typecheck_object_field_bad.claro` checks the friendly wrong-type diagnostic.
This slice is intentionally small: it covers direct `NEW Class object` plus `SET object.field value` cases in one file. Broader object flows, aliases, method return checks, and richer object signatures remain future work. This slice is intentionally small: it covers direct `NEW Class object` plus `SET object.field value` cases in one file. Broader object flows, aliases, method return checks, and richer object signatures remain future work.
## Status ## Status
+1 -1
View File
@@ -53,7 +53,7 @@ Ready now:
- `TYPE OF` and `CHECK TYPE` - `TYPE OF` and `CHECK TYPE`
- typed list/map checks through `claro typecheck` - typed list/map checks through `claro typecheck`
- a narrow function/method argument check: `CHECK TYPE parameter IS TYPE` inside a function or simple object method lets `claro typecheck` accept correct checked calls and catch mismatched `DO`, `CALL ... WITH`, and `DO object.method ...` arguments - a narrow function/method argument check: `CHECK TYPE parameter IS TYPE` inside a function or simple object method lets `claro typecheck` accept correct checked calls and catch mismatched `DO`, `CALL ... WITH`, and `DO object.method ...` arguments
- a narrow object-field assignment check for simple `NEW Class object` plus direct `SET object.field value` cases when the class declares `HAS field TYPE` - a narrow object-field assignment check for simple `NEW Class object` plus direct `SET object.field value` cases when the class declares `HAS field TYPE`; validation now covers both a correct direct assignment and a wrong-type diagnostic
Still needed: Still needed:
- richer typed function signatures and return values - richer typed function signatures and return values
+1 -1
View File
@@ -31,7 +31,7 @@ See `CURRENT_STATUS.md` for the detailed feature matrix.
1. Keep beginner-facing docs current and separate from historical release notes. 1. Keep beginner-facing docs current and separate from historical release notes.
2. Keep examples aligned with the modern simple syntax (`END`, `DO`, short `SET`, short `ASK`) while documenting older compatibility forms separately. 2. Keep examples aligned with the modern simple syntax (`END`, `DO`, short `SET`, short `ASK`) while documenting older compatibility forms separately.
3. Expand validation around typecheck diagnostics and package/networking safety. Current object-method parameter validation covers one correct `DO object.method ...` call and one wrong-type diagnostic; object-field validation also covers one simple wrong-type direct assignment after `NEW Class object`. 3. Expand validation around typecheck diagnostics and package/networking safety. Current object-method parameter validation covers one correct `DO object.method ...` call and one wrong-type diagnostic; object-field validation covers one correct direct `SET object.field value` assignment and one wrong-type direct assignment after `NEW Class object`.
4. Add small examples for each foundation feature before adding bigger syntax. 4. Add small examples for each foundation feature before adding bigger syntax.
## Complete-platform milestones ## Complete-platform milestones
+1 -1
View File
@@ -608,6 +608,6 @@ static void print_help(void){
static int show_examples(void){ const char *items[]={"hello.claro","name_input.claro","quiz.claro","calculator.claro","guessing_game.claro","shopping_list.claro","save_and_load_file.claro","simple_functions.claro","text_and_lists.claro","text_polish.claro","practical_scripting.claro","type_hardening.claro","typed_ask.claro","objects_classes.claro","networking.claro",NULL}; int i; printf("Included beginner examples:\n"); for(i=0;items[i];i++) printf(" examples/%s\n",items[i]); printf("\nRun one with: claro examples/hello.claro\n"); return 0; } static int show_examples(void){ const char *items[]={"hello.claro","name_input.claro","quiz.claro","calculator.claro","guessing_game.claro","shopping_list.claro","save_and_load_file.claro","simple_functions.claro","text_and_lists.claro","text_polish.claro","practical_scripting.claro","type_hardening.claro","typed_ask.claro","objects_classes.claro","networking.claro",NULL}; int i; printf("Included beginner examples:\n"); for(i=0;items[i];i++) printf(" examples/%s\n",items[i]); printf("\nRun one with: claro examples/hello.claro\n"); return 0; }
static int file_exists_simple(const char *path){ FILE *f=fopen(path,"rb"); if(f){ fclose(f); return 1; } return 0; } static int file_exists_simple(const char *path){ FILE *f=fopen(path,"rb"); if(f){ fclose(f); return 1; } return 0; }
static int run_doctor(void){ int ok=1; const char *files[]={"src/claro.c","README.md","assets/Claro_Logo.jpg","lessons/01_hello.claro","examples/hello.claro","tests/01_hello.claro",NULL}; int i; printf("%s\n",CLARO_VERSION); printf("Doctor check:\n"); for(i=0;files[i];i++){ int has=file_exists_simple(files[i]); printf(" %s %s\n",has?"OK":"MISSING",files[i]); if(!has) ok=0; } printf("%s\n",ok?"Claro folder looks ready.":"Some Claro files are missing."); return ok?0:1; } static int run_doctor(void){ int ok=1; const char *files[]={"src/claro.c","README.md","assets/Claro_Logo.jpg","lessons/01_hello.claro","examples/hello.claro","tests/01_hello.claro",NULL}; int i; printf("%s\n",CLARO_VERSION); printf("Doctor check:\n"); for(i=0;files[i];i++){ int has=file_exists_simple(files[i]); printf(" %s %s\n",has?"OK":"MISSING",files[i]); if(!has) ok=0; } printf("%s\n",ok?"Claro folder looks ready.":"Some Claro files are missing."); return ok?0:1; }
static int run_validate(void){ int fails=0, i; const char *checks[]={"lessons/01_hello.claro","lessons/02_ask_name.claro","lessons/03_variables.claro","lessons/04_math.claro","lessons/05_if_else.claro","lessons/06_loops.claro","lessons/07_lists.claro","lessons/08_functions.claro","lessons/09_files.claro","lessons/10_final_quiz.claro","examples/hello.claro","examples/name_input.claro","examples/quiz.claro","examples/calculator.claro","examples/guessing_game.claro","examples/shopping_list.claro","examples/save_and_load_file.claro","examples/simple_functions.claro","examples/text_and_lists.claro","examples/text_polish.claro","examples/practical_scripting.claro","examples/type_hardening.claro","examples/objects_classes.claro","examples/networking.claro",NULL}; printf("%s\n",CLARO_VERSION); printf("Stable package validation:\n"); fails+=run_doctor(); fails+=run_tests(); printf("Checking lessons and main examples:\n"); for(i=0;checks[i];i++){ printf(" %s\n",checks[i]); fails+=check_file(checks[i]); } fails+=typecheck_file("tests/typecheck_good.claro"); fails+=typecheck_file("tests/typecheck_container_good.claro"); fails+=typecheck_file("tests/typecheck_function_good.claro"); fails+=typecheck_file("tests/typecheck_function_multi_good.claro"); fails+=typecheck_file("tests/typecheck_method_good.claro"); fails+=typecheck_file("tests/37_object_field_types.claro"); if(typecheck_file("tests/typecheck_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_container_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_function_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_function_multi_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_method_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_object_field_bad.claro")==0) fails++; printf("%s\n",fails?"Validation found problems.":"Validation passed. Claro v1.18.26 foundation checks are ready for use."); return fails?1:0; } static int run_validate(void){ int fails=0, i; const char *checks[]={"lessons/01_hello.claro","lessons/02_ask_name.claro","lessons/03_variables.claro","lessons/04_math.claro","lessons/05_if_else.claro","lessons/06_loops.claro","lessons/07_lists.claro","lessons/08_functions.claro","lessons/09_files.claro","lessons/10_final_quiz.claro","examples/hello.claro","examples/name_input.claro","examples/quiz.claro","examples/calculator.claro","examples/guessing_game.claro","examples/shopping_list.claro","examples/save_and_load_file.claro","examples/simple_functions.claro","examples/text_and_lists.claro","examples/text_polish.claro","examples/practical_scripting.claro","examples/type_hardening.claro","examples/objects_classes.claro","examples/networking.claro",NULL}; printf("%s\n",CLARO_VERSION); printf("Stable package validation:\n"); fails+=run_doctor(); fails+=run_tests(); printf("Checking lessons and main examples:\n"); for(i=0;checks[i];i++){ printf(" %s\n",checks[i]); fails+=check_file(checks[i]); } fails+=typecheck_file("tests/typecheck_good.claro"); fails+=typecheck_file("tests/typecheck_container_good.claro"); fails+=typecheck_file("tests/typecheck_function_good.claro"); fails+=typecheck_file("tests/typecheck_function_multi_good.claro"); fails+=typecheck_file("tests/typecheck_method_good.claro"); fails+=typecheck_file("tests/typecheck_object_field_good.claro"); fails+=typecheck_file("tests/37_object_field_types.claro"); if(typecheck_file("tests/typecheck_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_container_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_function_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_function_multi_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_method_bad.claro")==0) fails++; if(typecheck_file("tests/typecheck_object_field_bad.claro")==0) fails++; printf("%s\n",fails?"Validation found problems.":"Validation passed. Claro v1.18.26 foundation checks are ready for use."); return fails?1:0; }
int main(int argc,char **argv){ int arg=1, trace=0; if(argc<2){ print_help(); return 0;} if(strcmp(argv[arg],"--trace")==0||strcmp(argv[arg],"trace")==0){ trace=1; arg++; } if(arg>=argc) return 0; if(strcmp(argv[arg],"help")==0||strcmp(argv[arg],"--help")==0){ print_help(); return 0; } if(strcmp(argv[arg],"test")==0) return run_tests(); if(strcmp(argv[arg],"repl")==0) return run_repl(); if(strcmp(argv[arg],"examples")==0) return show_examples(); if(strcmp(argv[arg],"doctor")==0) return run_doctor(); if(strcmp(argv[arg],"validate")==0) return run_validate(); if(strcmp(argv[arg],"package")==0) return run_package_cmd(argc,argv,arg+1); if(strcmp(argv[arg],"ide")==0) return print_ide_info(); if(strcmp(argv[arg],"new")==0&&arg+1<argc) return create_new_project(argv[arg+1]); if(strcmp(argv[arg],"fmt")==0&&arg+1<argc) return fmt_file(argv[arg+1]); if(strcmp(argv[arg],"check")==0&&arg+1<argc) return check_file(argv[arg+1]); if(strcmp(argv[arg],"typecheck")==0&&arg+1<argc) return typecheck_file(argv[arg+1]); if(strcmp(argv[arg],"version")==0||strcmp(argv[arg],"--version")==0){ puts(CLARO_VERSION); return 0; } if(strcmp(argv[arg],"run")==0){ arg++; if(arg>=argc){ Runtime rt; int rc; char *mainfile=project_value("main"); if(!mainfile||!*mainfile){ if(mainfile) free(mainfile); mainfile=xstrdup("main.claro"); } rt_init(&rt); rt.trace=trace; rt.script_argc=0; rt.script_argv=NULL; rc=run_file(&rt,mainfile); free(mainfile); return rc; } } { Runtime rt; int rc; rt_init(&rt); rt.trace=trace; rt.script_argc=argc-arg-1; rt.script_argv=argv+arg+1; rc=run_file(&rt,argv[arg]); return rc; } } int main(int argc,char **argv){ int arg=1, trace=0; if(argc<2){ print_help(); return 0;} if(strcmp(argv[arg],"--trace")==0||strcmp(argv[arg],"trace")==0){ trace=1; arg++; } if(arg>=argc) return 0; if(strcmp(argv[arg],"help")==0||strcmp(argv[arg],"--help")==0){ print_help(); return 0; } if(strcmp(argv[arg],"test")==0) return run_tests(); if(strcmp(argv[arg],"repl")==0) return run_repl(); if(strcmp(argv[arg],"examples")==0) return show_examples(); if(strcmp(argv[arg],"doctor")==0) return run_doctor(); if(strcmp(argv[arg],"validate")==0) return run_validate(); if(strcmp(argv[arg],"package")==0) return run_package_cmd(argc,argv,arg+1); if(strcmp(argv[arg],"ide")==0) return print_ide_info(); if(strcmp(argv[arg],"new")==0&&arg+1<argc) return create_new_project(argv[arg+1]); if(strcmp(argv[arg],"fmt")==0&&arg+1<argc) return fmt_file(argv[arg+1]); if(strcmp(argv[arg],"check")==0&&arg+1<argc) return check_file(argv[arg+1]); if(strcmp(argv[arg],"typecheck")==0&&arg+1<argc) return typecheck_file(argv[arg+1]); if(strcmp(argv[arg],"version")==0||strcmp(argv[arg],"--version")==0){ puts(CLARO_VERSION); return 0; } if(strcmp(argv[arg],"run")==0){ arg++; if(arg>=argc){ Runtime rt; int rc; char *mainfile=project_value("main"); if(!mainfile||!*mainfile){ if(mainfile) free(mainfile); mainfile=xstrdup("main.claro"); } rt_init(&rt); rt.trace=trace; rt.script_argc=0; rt.script_argv=NULL; rc=run_file(&rt,mainfile); free(mainfile); return rc; } } { Runtime rt; int rc; rt_init(&rt); rt.trace=trace; rt.script_argc=argc-arg-1; rt.script_argv=argv+arg+1; rc=run_file(&rt,argv[arg]); return rc; } }
+6
View File
@@ -0,0 +1,6 @@
CLASS Player
HAS score NUMBER
END
NEW Player player
SET player.score 10
+1
View File
@@ -35,6 +35,7 @@ EXPECTED_OK = [
"tests/typecheck_function_good.claro", "tests/typecheck_function_good.claro",
"tests/typecheck_function_multi_good.claro", "tests/typecheck_function_multi_good.claro",
"tests/typecheck_method_good.claro", "tests/typecheck_method_good.claro",
"tests/typecheck_object_field_good.claro",
"tests/37_object_field_types.claro", "tests/37_object_field_types.claro",
] ]