gloo 7.0.4 → 7.1

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/docs/application.md +14 -2
  4. data/docs/development.md +1 -1
  5. data/docs/language_objects.md +34 -0
  6. data/docs/language_syntax.md +25 -0
  7. data/docs/objects.md +1 -1
  8. data/docs/plugins.md +9 -3
  9. data/docs/testing.md +206 -0
  10. data/docs/verbs.md +7 -0
  11. data/lib/VERSION +1 -1
  12. data/lib/VERSION_NOTES +11 -2
  13. data/lib/gloo/app/engine.rb +19 -9
  14. data/lib/gloo/app/settings.rb +20 -3
  15. data/lib/gloo/core/gloo_system.rb +7 -0
  16. data/lib/gloo/core/obj.rb +22 -1
  17. data/lib/gloo/core/tokens.rb +20 -0
  18. data/lib/gloo/core/verb.rb +20 -0
  19. data/lib/gloo/objs/basic/string_msgs.rb +6 -7
  20. data/lib/gloo/objs/basic/untyped.rb +2 -1
  21. data/lib/gloo/objs/system/file_handle.rb +5 -2
  22. data/lib/gloo/objs/web/json.rb +7 -5
  23. data/lib/gloo/persist/file_loader.rb +10 -0
  24. data/lib/gloo/persist/file_storage.rb +8 -2
  25. data/lib/gloo/persist/persist_man.rb +28 -0
  26. data/lib/gloo/verbs/context.rb +10 -2
  27. data/lib/gloo/verbs/exists.rb +14 -2
  28. data/lib/gloo/verbs/load.rb +16 -2
  29. data/lib/gloo/verbs/save.rb +10 -3
  30. data/test.gloo/ctrl/each.test.gloo +21 -7
  31. data/test.gloo/lang/declaration.test.gloo +7 -2
  32. data/test.gloo/lang/gloo_sys.test.gloo +12 -0
  33. data/test.gloo/lang/naming.test.gloo +7 -2
  34. data/test.gloo/objs/file.test.gloo +18 -2
  35. data/test.gloo/objs/fixtures/source_dir_fixture.gloo +6 -0
  36. data/test.gloo/objs/json.test.gloo +2 -0
  37. data/test.gloo/objs/obj.test.gloo +33 -0
  38. data/test.gloo/objs/string.test.gloo +2 -2
  39. data/test.gloo/verbs/context.test.gloo +12 -0
  40. data/test.gloo/verbs/exists.test.gloo +19 -0
  41. data/test.gloo/verbs/load.test.gloo +101 -2
  42. data/test.gloo/verbs/reload.test.gloo +9 -4
  43. data/test.gloo/verbs/save.test.gloo +41 -16
  44. metadata +5 -6
@@ -15,6 +15,11 @@ tests.objs.obj [can] :
15
15
 
16
16
  no_doc [string] : "value"
17
17
 
18
+ # For source_dir / source_file.
19
+ this_file [string] : /obj.test.gloo
20
+ fixture_path [string] : /fixtures/source_dir_fixture.gloo
21
+ where [string] :
22
+
18
23
  obj_contains [test] :
19
24
  description [string] : Check to see if an object contains children
20
25
  on_test [script] :
@@ -70,3 +75,31 @@ tests.objs.obj [can] :
70
75
  check tests.objs.obj.no_doc for doc
71
76
  eval it = ""
72
77
  assert "expected doc to be blank for an object with no leading comment"
78
+
79
+ source_file_is_this_test_file [test] :
80
+ description [string] : source_file answers with the file the object was declared in.
81
+ on_test [script] :
82
+ check ^^ for source_file
83
+ put it into ^^.where
84
+ check ^^.where for ends_with? ( ^^.this_file )
85
+ assert "expected source_file to be this test file"
86
+
87
+ load_a_fixture_next_to_this_file [test] :
88
+ description [string] : source_dir finds this file's folder, so a fixture beside it can be loaded.
89
+ on_test [script] :
90
+ check ^^ for source_dir
91
+ put it into ^^.where
92
+ load ( ^^.where ^^.fixture_path )
93
+ eval source_dir_fixture.msg = 'found next door'
94
+ assert "expected the fixture next to this file to load"
95
+ tell source_dir_fixture to unload
96
+
97
+ source_dir_of_a_runtime_object_is_blank [test] :
98
+ description [string] : an object not loaded from a file has a blank source_dir.
99
+ on_test [script] :
100
+ create source_dir_runtime_obj as string : made at runtime
101
+ check source_dir_runtime_obj for source_dir
102
+ put it into ^^.where
103
+ check ^^.where for blank?
104
+ assert "expected a blank source_dir for a runtime object"
105
+ tell source_dir_runtime_obj to unload
@@ -125,8 +125,8 @@ tests.objs.string [can] :
125
125
  on_test [script] :
126
126
  put 'one,two,three' into ^^.s
127
127
  tell ^^.s to split_list (',' ^^.dst)
128
- eval it = 3
129
- assert "expected split_list to put the part count into it"
128
+ eval it = true
129
+ assert "expected split_list to put true in it"
130
130
  eval ^^.dst.1 = 'one'
131
131
  assert "expected dst.1 to equal 'one'"
132
132
  eval ^^.dst.2 = 'two'
@@ -4,6 +4,8 @@
4
4
 
5
5
  tests.verbs.context [can] :
6
6
 
7
+ target [string] : tests.verbs.context
8
+
7
9
  set_context [test] :
8
10
  description [string] : context {path} sets the context and puts the path in it.
9
11
  on_test [script] :
@@ -15,3 +17,13 @@ tests.verbs.context [can] :
15
17
  context root
16
18
  eval it = 'root'
17
19
  assert "expected context to be restored to root"
20
+
21
+ set_context_to_a_computed_path [test] :
22
+ description [string] : context ( expr ) sets the context to the path the expression works out to.
23
+ on_test [script] :
24
+ context ( ^^.target )
25
+ eval it = 'tests.verbs.context'
26
+ assert "expected it to be the computed context path"
27
+
28
+ # restore, so later tests run at root
29
+ context root
@@ -4,6 +4,9 @@
4
4
 
5
5
  tests.verbs.exists [can] :
6
6
 
7
+ type_start [string] : cont
8
+ verb_name [string] : show
9
+
7
10
  verb [test] :
8
11
  description [string] : Check on existance of exists verb
9
12
  on_test [script] :
@@ -60,6 +63,22 @@ tests.verbs.exists [can] :
60
63
  exists? object tests.verbs.exists.instance
61
64
  refute "expected object to check for a type, not an instance"
62
65
 
66
+ computed_name [test] :
67
+ description [string] : exists? ( expr ) checks the name the expression works out to.
68
+ on_test [script] :
69
+ exists? ( ^^.verb_name )
70
+ assert "expected show to exist"
71
+
72
+ exists? verb ( ^^.verb_name )
73
+ assert "expected show to exist as a verb"
74
+
75
+ exists? object ( ^^.type_start 'ainer' )
76
+ assert "expected container to exist as an object type"
77
+
78
+ exists? object ( ^^.type_start 'raption' )
79
+ refute "expected contraption to not exist"
80
+
81
+
63
82
  tests.verbs.exists_unknown_kind [can] :
64
83
 
65
84
  err_fired [bool] : false
@@ -1,12 +1,37 @@
1
1
  #
2
2
  # Load verb tests
3
3
  #
4
- # Uses 'load lib' because it is self-contained (no fixture files) and
5
- # its effect is observable through 'exists?'.
4
+ # Mostly uses 'load lib' because it is self-contained (no fixture files) and
5
+ # its effect is observable through 'exists?'. The no-objects and
6
+ # computed-path tests write scratch files to $.gloo_tmp.
6
7
  #
7
8
 
8
9
  tests.verbs.load [can] :
9
10
 
11
+ f [file] :
12
+
13
+ # Scratch files live in the gloo tmp folder ($.gloo_tmp).
14
+ on_load [script] :
15
+ put $.gloo_tmp '/gloo_load_no_objects_test.gloo' into ^.f
16
+
17
+ comments_only [text] : BEGIN
18
+ # This file has comments,
19
+
20
+ # but no objects.
21
+ END
22
+ load_lib_only [text] : BEGIN
23
+ load lib md
24
+ # and nothing else
25
+ END
26
+
27
+ computed_name [string] : /gloo_load_computed_test.gloo
28
+ lib_name [string] : md
29
+ computed_f [file] :
30
+ computed_fixture [text] : BEGIN
31
+ computed_demo [can] :
32
+ s [string] : hi
33
+ END
34
+
10
35
  err_fired [bool] : false
11
36
  on_error [script] :
12
37
  put true into ^.err_fired
@@ -39,3 +64,77 @@ tests.verbs.load [can] :
39
64
  load no_such_file_xyz
40
65
  eval ^^.err_fired = true
41
66
  assert "expected 'load' of a missing file to fire on_error"
67
+
68
+ load_comments_only_file_does_not_error [test] :
69
+ description [string] : a file with only comments loads with a warning, not an error.
70
+ expect_errors [bool] : true
71
+ on_test [script] :
72
+ put false into ^^.err_fired
73
+ tell ^^.f to write ( ^^.comments_only )
74
+ load ( ^^.f )
75
+ tell ^^.f to delete
76
+ eval ^^.err_fired = false
77
+ assert "expected a comments-only file not to fire on_error"
78
+
79
+ load_empty_file_does_not_error [test] :
80
+ description [string] : an empty file loads with a warning, not an error.
81
+ expect_errors [bool] : true
82
+ on_test [script] :
83
+ put false into ^^.err_fired
84
+ tell ^^.f to write ( '' )
85
+ load ( ^^.f )
86
+ tell ^^.f to delete
87
+ eval ^^.err_fired = false
88
+ assert "expected an empty file not to fire on_error"
89
+
90
+ load_lib_only_file_does_not_error [test] :
91
+ description [string] : a file with only a load lib line loads with a warning, not an error.
92
+ expect_errors [bool] : true
93
+ on_test [script] :
94
+ put false into ^^.err_fired
95
+ tell ^^.f to write ( ^^.load_lib_only )
96
+ load ( ^^.f )
97
+ tell ^^.f to delete
98
+ eval ^^.err_fired = false
99
+ assert "expected a file with only 'load lib' not to fire on_error"
100
+
101
+ load_a_computed_path [test] :
102
+ description [string] : load ( expr ) loads the file the expression works out to.
103
+ on_test [script] :
104
+ put $.gloo_tmp ^^.computed_name into ^^.computed_f
105
+ tell ^^.computed_f to write ( ^^.computed_fixture )
106
+ load ( $.gloo_tmp ^^.computed_name )
107
+ eval computed_demo.s = 'hi'
108
+ assert "expected load ( expr ) to load the computed path"
109
+ tell computed_demo to unload
110
+ tell ^^.computed_f to delete
111
+
112
+ load_a_path_held_in_a_file_object [test] :
113
+ description [string] : load ( {file obj} ) loads the path the object holds.
114
+ on_test [script] :
115
+ put $.gloo_tmp ^^.computed_name into ^^.computed_f
116
+ tell ^^.computed_f to write ( ^^.computed_fixture )
117
+ load ( ^^.computed_f )
118
+ eval computed_demo.s = 'hi'
119
+ assert "expected load ( {file obj} ) to load the path it holds"
120
+ tell computed_demo to unload
121
+ tell ^^.computed_f to delete
122
+
123
+ load_a_computed_path_from_an_unknown_object_errors [test] :
124
+ description [string] : load ( expr ) with an expression that can't be worked out fires on_error.
125
+ expect_errors [bool] : true
126
+ on_test [script] :
127
+ put false into ^^.err_fired
128
+ load ( no_such_obj_xyz )
129
+ eval ^^.err_fired = true
130
+ assert "expected a bad expression in load ( ... ) to fire on_error"
131
+
132
+ load_lib_with_a_computed_name [test] :
133
+ description [string] : load lib ( expr ) loads the library the expression names.
134
+ on_test [script] :
135
+ put false into ^^.err_fired
136
+ load lib ( ^^.lib_name )
137
+ eval ^^.err_fired = false
138
+ assert "expected load lib ( expr ) not to fire on_error"
139
+ exists? object markdown
140
+ assert "expected the markdown type to be registered"
@@ -2,13 +2,18 @@
2
2
  # Reload message tests -- 'tell {obj} to reload' re-reads the file.
3
3
  #
4
4
  # The bare 'reload' verb restarts the engine (covered by the unit
5
- # tests). These exercise per-object reload against a /tmp scratch file
5
+ # tests). These exercise per-object reload against a scratch file in $.gloo_tmp
6
6
  # that gets rewritten between load and reload.
7
7
  #
8
8
 
9
9
  tests.verbs.reload [can] :
10
10
 
11
- f [file] : /tmp/gloo_reload_test.gloo
11
+ f [file] :
12
+
13
+ # Scratch files live in the gloo tmp folder ($.gloo_tmp).
14
+ on_load [script] :
15
+ put $.gloo_tmp '/gloo_reload_test.gloo' into ^.f
16
+
12
17
  v1 [text] : BEGIN
13
18
  demo [container] :
14
19
  msg [string] : original
@@ -24,7 +29,7 @@ END
24
29
  description [string] : editing the file on disk then reloading takes effect.
25
30
  on_test [script] :
26
31
  tell ^^.f to write ( ^^.v1 )
27
- load /tmp/gloo_reload_test.gloo
32
+ load ( ^^.f )
28
33
  eval demo.msg = 'original'
29
34
  assert "sanity: loaded the first version"
30
35
 
@@ -44,7 +49,7 @@ END
44
49
  expect_errors [bool] : true
45
50
  on_test [script] :
46
51
  tell ^^.f to write ( ^^.v1 )
47
- load /tmp/gloo_reload_test.gloo
52
+ load ( ^^.f )
48
53
 
49
54
  put 'not saved' into demo.msg
50
55
  tell demo to reload
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # Save verb tests -- real load -> edit -> save round trips.
3
3
  #
4
- # Each test writes a .gloo fixture to /tmp, loads it, does something,
4
+ # Each test writes a .gloo fixture to $.gloo_tmp, loads it, does something,
5
5
  # saves, reads the file back, and asserts on the raw text. Every test
6
6
  # unloads its object and deletes its scratch file at the end so the
7
7
  # next one starts clean.
@@ -9,9 +9,18 @@
9
9
 
10
10
  tests.verbs.save [can] :
11
11
 
12
- f [file] : /tmp/gloo_save_test.gloo
13
- g [file] : /tmp/gloo_save_test_2.gloo
14
- to_target [file] : /tmp/gloo_save_test_to.gloo
12
+ f [file] :
13
+ g [file] :
14
+ to_target [file] :
15
+
16
+ # Scratch files live in the gloo tmp folder ($.gloo_tmp).
17
+ on_load [script] :
18
+ put $.gloo_tmp '/gloo_save_test.gloo' into ^.f
19
+ put $.gloo_tmp '/gloo_save_test_2.gloo' into ^.g
20
+ put $.gloo_tmp '/gloo_save_test_to.gloo' into ^.to_target
21
+
22
+ computed_name [string] : /gloo_save_computed_to
23
+ computed_target [file] :
15
24
  out [string] :
16
25
  err [bool] : false
17
26
 
@@ -58,7 +67,7 @@ END
58
67
  on_test [script] :
59
68
  put false into ^^.err
60
69
  tell ^^.f to write ( ^^.fixture )
61
- load /tmp/gloo_save_test.gloo
70
+ load ( ^^.f )
62
71
  put 'changed' into demo.msg
63
72
  save demo
64
73
  eval ^^.err = false
@@ -79,7 +88,7 @@ END
79
88
  description [string] : load then save with no change reproduces the file exactly.
80
89
  on_test [script] :
81
90
  tell ^^.f to write ( ^^.fixture )
82
- load /tmp/gloo_save_test.gloo
91
+ load ( ^^.f )
83
92
  save demo
84
93
  tell ^^.f to read ( ^^.out )
85
94
  eval ^^.out = ^^.fixture
@@ -91,7 +100,7 @@ END
91
100
  description [string] : An unchanged save reproduces blank lines before a container's first child too.
92
101
  on_test [script] :
93
102
  tell ^^.f to write ( ^^.blank_before_first_child_fixture )
94
- load /tmp/gloo_save_test.gloo
103
+ load ( ^^.f )
95
104
  save app
96
105
  tell ^^.f to read ( ^^.out )
97
106
  eval ^^.out = ^^.blank_before_first_child_fixture
@@ -103,7 +112,7 @@ END
103
112
  description [string] : removing a child and saving drops just that declaration.
104
113
  on_test [script] :
105
114
  tell ^^.f to write ( ^^.fixture )
106
- load /tmp/gloo_save_test.gloo
115
+ load ( ^^.f )
107
116
  tell demo.other to unload
108
117
  save demo
109
118
  tell ^^.f to read ( ^^.out )
@@ -118,8 +127,8 @@ END
118
127
  description [string] : save {obj} to {path} writes a new file and registers it.
119
128
  on_test [script] :
120
129
  tell ^^.f to write ( ^^.fixture )
121
- load /tmp/gloo_save_test.gloo
122
- save demo to /tmp/gloo_save_test_to
130
+ load ( ^^.f )
131
+ save demo to ( ^^.to_target )
123
132
  check ^^.to_target for exists?
124
133
  assert "save ... to should create the target file"
125
134
  tell ^^.to_target to read ( ^^.out )
@@ -129,12 +138,28 @@ END
129
138
  tell ^^.f to delete
130
139
  tell ^^.to_target to delete
131
140
 
141
+ save_to_a_computed_path [test] :
142
+ description [string] : save {obj} to ( expr ) writes the file the expression works out to.
143
+ on_test [script] :
144
+ tell ^^.f to write ( ^^.fixture )
145
+ load ( ^^.f )
146
+ save demo to ( $.gloo_tmp ^^.computed_name )
147
+ put $.gloo_tmp ^^.computed_name '.gloo' into ^^.computed_target
148
+ check ^^.computed_target for exists?
149
+ assert "save ... to ( expr ) should create the computed file"
150
+ tell ^^.computed_target to read ( ^^.out )
151
+ check ^^.out for substring? ( "msg [string] : hello" )
152
+ assert "the computed file should hold the object"
153
+ tell demo to unload
154
+ tell ^^.f to delete
155
+ tell ^^.computed_target to delete
156
+
132
157
  extracting_a_subtree_moves_it_to_the_new_file [test] :
133
158
  description [string] : save {nested obj} to {path} moves its declaration (and its own comment) out of the old file into the new one.
134
159
  on_test [script] :
135
160
  tell ^^.f to write ( ^^.fixture )
136
- load /tmp/gloo_save_test.gloo
137
- save demo.other to /tmp/gloo_save_test_to
161
+ load ( ^^.f )
162
+ save demo.other to ( ^^.to_target )
138
163
  check ^^.to_target for exists?
139
164
  assert "extraction should create the target file"
140
165
 
@@ -167,13 +192,13 @@ END
167
192
  on_test [script] :
168
193
  put false into ^^.err
169
194
  tell ^^.f to write ( ^^.fixture )
170
- load /tmp/gloo_save_test.gloo
195
+ load ( ^^.f )
171
196
  # a second file adds its own child under the same 'demo' container --
172
197
  # a namespace pattern applied inside the subtree we'll try to extract
173
198
  tell ^^.g to write ( "demo [container] :\n extra [string] : too\n" )
174
- load /tmp/gloo_save_test_2.gloo
199
+ load ( ^^.g )
175
200
 
176
- save demo to /tmp/gloo_save_test_to
201
+ save demo to ( ^^.to_target )
177
202
  eval ^^.err = true
178
203
  assert "extraction should refuse a subtree spanning multiple files"
179
204
  check ^^.to_target for exists?
@@ -188,7 +213,7 @@ END
188
213
  expect_errors [bool] : true
189
214
  on_test [script] :
190
215
  tell ^^.f to write ( ^^.fixture )
191
- load /tmp/gloo_save_test.gloo
216
+ load ( ^^.f )
192
217
  put 'not saved' into demo.msg
193
218
  eval demo.msg = 'not saved'
194
219
  assert "sanity: the edit landed"
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gloo
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.4
4
+ version: '7.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Crane
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2026-10-19 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -275,6 +274,7 @@ files:
275
274
  - docs/objects.md
276
275
  - docs/operators.md
277
276
  - docs/plugins.md
277
+ - docs/testing.md
278
278
  - docs/verbs.md
279
279
  - docs/web_app.md
280
280
  - exe/gloo
@@ -472,6 +472,7 @@ files:
472
472
  - test.gloo/objs/decimal.test.gloo
473
473
  - test.gloo/objs/erb.test.gloo
474
474
  - test.gloo/objs/file.test.gloo
475
+ - test.gloo/objs/fixtures/source_dir_fixture.gloo
475
476
  - test.gloo/objs/function.test.gloo
476
477
  - test.gloo/objs/int.test.gloo
477
478
  - test.gloo/objs/json.test.gloo
@@ -512,7 +513,6 @@ licenses:
512
513
  - MIT
513
514
  metadata:
514
515
  documentation_uri: https://github.com/ecrane/gloo
515
- post_install_message:
516
516
  rdoc_options: []
517
517
  require_paths:
518
518
  - lib
@@ -527,8 +527,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
527
527
  - !ruby/object:Gem::Version
528
528
  version: '0'
529
529
  requirements: []
530
- rubygems_version: 3.5.16
531
- signing_key:
530
+ rubygems_version: 4.0.17
532
531
  specification_version: 4
533
532
  summary: Gloo scripting language. A scripting language built on ruby.
534
533
  test_files: []