gloo 7.1.1 → 7.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d25bb60fb25bb1b42e44eeac62b0ec3bae86a9f3770c696caf4ab39b7f1c9784
4
- data.tar.gz: 260731b8d5f1cd1c6f3718be0d26f17d39139795e7e5c13ff8908a4fc3f1c453
3
+ metadata.gz: e3e9f9ec23fd38faee18f95a521fe1d21a8e572b2306c814233c3fc67ae6e5f3
4
+ data.tar.gz: a1f2f961d1860473c14faefb6c5f9ffe0556bae36479cf3755b8333a1b0db68c
5
5
  SHA512:
6
- metadata.gz: 3729efcd7dcfa5964a408fb28750bd2ac7caea3af323b1ea8c8b75503446f51805db7f20b05bfd705a9ac020bd06fe6fba5135013137e937f7dd6f499e134f40
7
- data.tar.gz: d69918fdaf8ab491ac5bc21cd7a838048ef4eaf2299d8a867eea017b14c0f5ca3a314e7106e6fc0bf00fad8e949550efaae897121d8ae11de4d964a1a0231218
6
+ metadata.gz: d1665486b345b607c64f98519ac7219ac720ccad75d88d135a88225e3ea527871e6305acc95db9b31a89b7ba5373a6016b7fbcb0a354dfc82ecd04a3f5733bc9
7
+ data.tar.gz: 35f9a3c3013d394ed4be04106f682ef92b14328279b12524d345f5a5a04f4ce31d7c8645d38a48484ac699a0d9d8ccc231340004a90cb0b5acdb98f890809b58
data/Rakefile CHANGED
@@ -2,8 +2,6 @@ require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- ENV[ 'GLOO_ENV' ] = 'TEST'
6
-
7
5
  t.warning = false
8
6
  t.libs << 'test'
9
7
  t.libs << 'lib'
data/docs/application.md CHANGED
@@ -31,6 +31,8 @@ gloo [global option] [file]
31
31
 
32
32
  Running gloo with a file specified will run that file. Once that file is done, gloo will quit. However, by specifying `--cli`, once the file has finished, gloo will remain open in CLI mode.
33
33
 
34
+ Gloo can also be started from another Ruby program; see Development, Running Gloo from Ruby.
35
+
34
36
  If a file named on the command line can't be found (a typo, the wrong folder, a missing `.gloo` extension on a full path), gloo prints `File '{name}' was not found.` to stderr and exits with a non-zero status. Any other load or run error also exits non-zero — including syntax errors in a file that otherwise loaded (gloo keeps loading past them, reporting each with its file and line) — so a shell script calling gloo can tell a failed run from a clean one.
35
37
 
36
38
  When specifying a file there are a couple ways to reference the gloo file to open:
@@ -76,6 +78,11 @@ When specifying a file there are a couple ways to reference the gloo file to ope
76
78
  - Exits with status 1 if any test failed, or errors or warnings
77
79
  were logged that no test expected; 0 otherwise.
78
80
  - See Testing.
81
+ --embed - Run in Embedded mode
82
+ - Start the engine and return, for a Ruby program that drives
83
+ gloo itself.
84
+ - This is the default when gloo is created in code with no file
85
+ or mode. See Development, Running Gloo from Ruby.
79
86
  --version - Show application version
80
87
  --help - Show the help screen
81
88
  ```
data/docs/development.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Development
2
2
 
3
- How the interpreter's source is laid out, how to run its tests, and the conventions to follow when changing it. This page is for working on gloo itself; for using gloo, start with Getting Started.
3
+ How the interpreter's source is laid out, how to run its tests, the conventions to follow when changing it, and how to run gloo from your own Ruby code. This page is for working on gloo itself or driving it from Ruby; for using gloo, start with Getting Started.
4
4
 
5
5
  **Contents**
6
6
 
@@ -8,6 +8,7 @@ How the interpreter's source is laid out, how to run its tests, and the conventi
8
8
  - Tests
9
9
  - Documentation
10
10
  - Reporting Errors
11
+ - Running Gloo from Ruby
11
12
 
12
13
  ## Source Layout
13
14
 
@@ -40,7 +41,7 @@ There are two automated suites. Run both when making a change, and add to both:
40
41
 
41
42
  ### Unit tests — `test/`
42
43
 
43
- Standard Ruby minitest tests. The layout mirrors `lib/gloo/`, one test file per class or verb: `test/<area>/<name>_test.rb`, for example `test/verbs/show_test.rb` for `lib/gloo/verbs/show.rb`. Test classes inherit from `GlooTest` (in `test/base_test.rb`).
44
+ Standard Ruby minitest tests. The layout mirrors `lib/gloo/`, one test file per class or verb: `test/<area>/<name>_test.rb`, for example `test/verbs/show_test.rb` for `lib/gloo/verbs/show.rb`. Test classes inherit from `BaseTest` (in `test/base_test.rb`), or from `BaseEngineTest` (in `test/base_engine_test.rb`) for a test that needs a started engine in `@engine`.
44
45
 
45
46
  ```
46
47
  rake test
@@ -98,3 +99,22 @@ Gloo reports every problem in a way scripts can see (see Language, Syntax, Error
98
99
  - A question whose answer is "no" is just a result, not an error.
99
100
 
100
101
  Don't use `@engine.log.error` or `@engine.log.warn` for these; they only write to the log, and scripts can't see them. Build "not found" messages with `Gloo::Core::NotFound` (for example `NotFound.object( name )`) so they always read the same way.
102
+
103
+ ## Running Gloo from Ruby
104
+
105
+ Gloo can be started from another Ruby program, such as a test harness or an app that runs gloo commands. Create the engine with the params gloo should see — the same words you would type after `gloo` on the command line:
106
+
107
+ ```ruby
108
+ require 'gloo'
109
+
110
+ context = Gloo::App::EngineContext.new( [] )
111
+ engine = Gloo::App::Engine.new( context )
112
+ engine.start
113
+
114
+ engine.process_cmd "create greeting as string : 'hello'"
115
+ engine.process_cmd 'show greeting'
116
+ ```
117
+
118
+ Only those params are used. The Ruby program's own command line (`ARGV`) is never read, so running `ruby harness.rb some_file.gloo` doesn't make gloo load `some_file.gloo`. Pass anything gloo should see explicitly. Only the `gloo` command itself (`Gloo.run`) reads the command line.
119
+
120
+ With no file and no mode switch, the engine runs in Embedded mode (`--embed`): `start` sets the engine up and returns without loading or running anything, and your code drives it from there, for example with `process_cmd`.
data/docs/iterators.md CHANGED
@@ -215,7 +215,7 @@ Iterate for each line in a text block (string).
215
215
  Children:
216
216
 
217
217
  - `line` (string)
218
- - The single line of text.
218
+ - The single line of text, without its line ending (`\n` or `\r\n`). A blank line is still visited, as an empty string.
219
219
  - `in` (text)
220
220
  - The block of text or string.
221
221
  - `do` (script)
data/docs/verbs.md CHANGED
@@ -86,12 +86,13 @@ If the destination doesn't exist, or the expression can't be worked out (eg. it
86
86
 
87
87
  ## Load & Save
88
88
 
89
- `load` reads a `.gloo` file into the heap and runs its `on_load` script. Give a path relative to the project folder (no extension needed) or a full path (extension required); `*` in place of a file name loads every `.gloo` file in a folder.
89
+ `load` reads a `.gloo` file into the heap and runs its `on_load` script. Give a path relative to the project folder, a full path, or one starting with `~` for your home folder; the `.gloo` extension is optional. `*` in place of a file name loads every `.gloo` file in a folder, wherever the folder is. Anything before the `*` is the start of the file names, so `my/app/a*` loads just the files whose names start with `a`.
90
90
 
91
91
  ```gloo
92
92
  > load my/project/config
93
93
  > load my/app/*
94
94
  > load ~/.my_app/settings.gloo
95
+ > load ~/.my_app/plugins/*
95
96
  ```
96
97
 
97
98
  If the name can't be resolved to a file, `load` reports `File '{name}' was not found.` — it fires `on_error` and, when the file was named on the `gloo` command line, prints the message to stderr and exits non-zero. A bad or missing file never fails silently.
data/lib/VERSION CHANGED
@@ -1 +1 @@
1
- 7.1.1
1
+ 7.1.2
data/lib/VERSION_NOTES CHANGED
@@ -1,3 +1,12 @@
1
+ 7.1.2 - 2026.10.28
2
+ - Fixes bug with create verb and ^.here reference.
3
+ - Behaviour change: an each over lines gives each line without its line ending.
4
+ - Load with * now works for a full path or a ~ folder, not just a folder in the project.
5
+ - Load no longer needs the .gloo extension for a full or ~ path.
6
+ - Clean run of gloo from a different ruby process (or test).
7
+ - Fixes looking for each child with a group by.
8
+
9
+
1
10
  7.1.1 - 2026.10.26
2
11
  - Fixes issues with the value in it after a failed command.
3
12
  - Warnings go to stderr, like errors.
data/lib/gloo/app/args.rb CHANGED
@@ -12,7 +12,6 @@ module Gloo
12
12
  class Args
13
13
 
14
14
  QUIET = 'quiet'.freeze
15
- GLOO_ENV = 'GLOO_ENV'.freeze
16
15
 
17
16
  attr_reader :switches, :files, :app_path, :command_tokens
18
17
 
@@ -26,8 +25,9 @@ module Gloo
26
25
  @app_path = nil
27
26
  @command_tokens = []
28
27
 
28
+ # Only the params given; the host process's ARGV is read by
29
+ # Gloo.run, when gloo is run as the command.
29
30
  params.each { |o| process_one_arg( o ) }
30
- ARGV.each { |o| process_one_arg( o ) }
31
31
  end
32
32
 
33
33
  #
@@ -117,9 +117,7 @@ module Gloo
117
117
  # Then finally use the default: embedded mode.
118
118
  #
119
119
  def detect_mode
120
- mode = if ENV[ GLOO_ENV ] == Gloo::App::Mode::TEST.to_s
121
- Mode::TEST
122
- elsif app?
120
+ mode = if app?
123
121
  Mode::APP
124
122
  elsif version?
125
123
  Mode::VERSION
data/lib/gloo/core/pn.rb CHANGED
@@ -172,7 +172,12 @@ module Gloo
172
172
  # returns nil without reporting an error. A caller that needs the
173
173
  # object reports its own error.
174
174
  #
175
+ # A here (^) or context (@) reference is expanded first, as resolve
176
+ # does, so a new object's parent can be given the same way as any
177
+ # other path (eg. create ^.x inside a script).
178
+ #
175
179
  def get_parent
180
+ expand_refs
176
181
  o = @engine.heap.root
177
182
 
178
183
  if self.includes_path?
@@ -134,7 +134,7 @@ module Gloo
134
134
  'One of the following, whose presence determines which kind of loop this is:',
135
135
  'child (alias) — iterate a container\'s children.',
136
136
  'word (string) — iterate the words in a string.',
137
- 'line (string) — iterate the lines in a block of text.',
137
+ 'line (string) — iterate the lines in a block of text. Each line comes without its line ending; a blank line is visited as an empty string.',
138
138
  'file (file) — iterate the files in a folder. Optional children: ext (string) limits to files of that extension, ignoring case; recursive (bool) walks the subfolders too; include_dirs (bool) lists folders as well as files.',
139
139
  'dir (file) — iterate the directories in a folder. Optional child: recursive (bool) walks the subfolders too.'
140
140
  ],
@@ -116,20 +116,24 @@ module Gloo
116
116
 
117
117
  o = Gloo::Objs::Alias.resolve_alias( @engine, o )
118
118
  o.children.each do |child|
119
+ new_group = false
119
120
  if group_mode
120
121
  group_value = group_by_value( child )
121
122
  if last_group != group_value
122
123
  last_group = group_value
124
+ new_group = true
125
+ # The ending group's end runs while child is still its last child.
123
126
  if first_time
124
127
  first_time = false
125
128
  else
126
129
  run_on_group_end
127
130
  end
128
- run_on_group_start
129
131
  end
130
132
  end
131
133
 
132
134
  set_child child
135
+ # The new group's start runs once child is its first child.
136
+ run_on_group_start if new_group
133
137
  break if @iterator_obj.run_do
134
138
  end
135
139
 
@@ -40,13 +40,14 @@ module Gloo
40
40
  # ---------------------------------------------------------------------
41
41
 
42
42
  #
43
- # Run for each line.
43
+ # Run for each line, without its line ending (\n or \r\n). A blank
44
+ # line is still visited, as an empty string.
44
45
  #
45
46
  def run
46
47
  str = @iterator_obj.in_value
47
48
  return unless str
48
49
 
49
- str.each_line do |line|
50
+ str.each_line( chomp: true ) do |line|
50
51
  set_line line
51
52
  break if @iterator_obj.run_do
52
53
  end
@@ -28,22 +28,30 @@ module Gloo
28
28
  end
29
29
 
30
30
  #
31
- # Get all the gloo files in the folder (partial path).
31
+ # Get all the gloo files in the folder (partial path). The folder
32
+ # can end with the start of a file name, as a prefix (folder/a).
32
33
  #
33
34
  def get_all_files_in( folder )
34
- pns = []
35
- dir = File.join( @engine.settings.project_path, folder )
35
+ dir = folder_for_files( folder )
36
+ return Dir.glob( "#{dir}*.gloo" )
37
+ end
36
38
 
37
- unless Dir.exist?( dir )
38
- @log.debug "Folder does not exist in project: #{folder}"
39
- dir = File.join( @engine.settings.user_root, folder )
40
- @log.debug "Looking in gloo home? found == #{Dir.exist?( dir )}"
41
- end
39
+ #
40
+ # Where to look for a folder of files: an absolute or ~ folder as
41
+ # given (~ expanded), anything else in the project folder, or if it
42
+ # isn't there, in the gloo home.
43
+ #
44
+ def folder_for_files( folder )
45
+ return folder.sub( '~', Dir.home ) if folder.start_with?( '~' )
46
+ return folder if File.absolute_path?( folder )
42
47
 
43
- Dir.glob( "#{dir}*.gloo" ).each do |f|
44
- pns << f
45
- end
46
- return pns
48
+ dir = File.join( @engine.settings.project_path, folder )
49
+ return dir if Dir.exist?( dir )
50
+
51
+ @log.debug "Folder does not exist in project: #{folder}"
52
+ dir = File.join( @engine.settings.user_root, folder )
53
+ @log.debug "Looking in gloo home? found == #{Dir.exist?( dir )}"
54
+ return dir
47
55
  end
48
56
 
49
57
  #
@@ -65,23 +73,33 @@ module Gloo
65
73
  return true
66
74
  end
67
75
 
68
- #
69
- # Expand a single file path.
70
- #
76
+ #
77
+ # Expand a single file path. The .gloo extension is optional: it's
78
+ # added when the name doesn't end with it, for a full or ~ path
79
+ # and for a name in the project or gloo home.
80
+ #
71
81
  def expand( name )
72
- # Try full path
82
+ # Try the name as given: a full path, or relative to the working
83
+ # folder (eg. gloo hello_world.gloo).
73
84
  ext_path = File.expand_path( name )
74
85
  return [ ext_path ] if self.valid?( ext_path )
75
86
 
76
- # Try in user root, projects
77
- full_name = "#{name}#{file_ext}"
87
+ full_name = name.end_with?( file_ext ) ? name : "#{name}#{file_ext}"
88
+
89
+ # A full or ~ path without the extension.
90
+ if name.start_with?( '~' ) || File.absolute_path?( name )
91
+ ext_path = File.expand_path( full_name )
92
+ return [ ext_path ] if self.valid?( ext_path )
93
+ end
94
+
95
+ # Try in projects
78
96
  pn = File.join( @engine.settings.project_path, full_name )
79
97
  return [ pn ] if self.valid?( pn )
80
-
98
+
81
99
  # Try in user root
82
100
  pn = File.join( @engine.settings.user_root, full_name )
83
101
  return [ pn ] if self.valid?( pn )
84
-
102
+
85
103
  return nil
86
104
  end
87
105
 
@@ -111,7 +111,9 @@ module Gloo
111
111
  'value. Both type and value are optional when creating an object.',
112
112
  :syntax => [ 'create {new.object.path} as {type} : {value}' ],
113
113
  :parameters => [
114
- '{new.object.path} — The path and name of the new object.',
114
+ '{new.object.path} — The path and name of the new object. ' \
115
+ 'Like any path, it can start from the root, from here in ' \
116
+ 'a script (^.box.new, ^^.new), or from the context (@.new).',
115
117
  '{type} — The type of the new object. Optional; if not provided the object will be untyped.',
116
118
  "{value} — The initial value for the new object. Optional; if not provided the object will have the default value for the type."
117
119
  ],
@@ -123,7 +125,7 @@ module Gloo
123
125
  "to the existing object's current value.",
124
126
  :errors => [
125
127
  "#{NO_NAME_ERR} — The name of the object was not specified and the object cannot be created.",
126
- "Could not create '{path}': Object '{parent.path}' was not found. — The parent container named in the path does not exist. The path is root-relative and every container above the new object must already exist. Nothing is created, and it is false.",
128
+ "Could not create '{path}': Object '{parent.path}' was not found. — The parent container named in the path does not exist. Every container above the new object must already exist. Nothing is created, and it is false.",
127
129
  "#{format( BAD_NAME_ERR, '{name}' )} — The name has parentheses or quotes, or there are extra words between the name and as / : — create takes a name as written. Nothing is created, and it is false."
128
130
  ],
129
131
  :examples => <<~EXAMPLES.strip
@@ -115,7 +115,12 @@ module Gloo
115
115
  'load [ext|lib] ( {expression} )'
116
116
  ],
117
117
  :parameters => [
118
- '{file_name} — Name of the object file that is to be loaded.',
118
+ '{file_name} — Name of the object file that is to be loaded: ' \
119
+ 'relative to the project, a full path, or starting with ~. ' \
120
+ 'The .gloo extension is optional. ' \
121
+ 'End it with * to load every .gloo file in a folder (a ' \
122
+ 'folder in the project, a full path, or one starting with ' \
123
+ '~); anything before the * is the start of the file names.',
119
124
  'reference type — By default, the type is file. File can be ' \
120
125
  'specified, but does not need to be. Use ext to load a ' \
121
126
  'User Extension. Use lib to load a Core Library.',
@@ -154,6 +159,7 @@ module Gloo
154
159
  > load my/project/file
155
160
  > load my/app/*
156
161
  > load ~/.my_app/settings.gloo
162
+ > load ~/.my_app/plugins/*
157
163
 
158
164
  # Load a file whose name is worked out
159
165
  > load ( $.gloo_tmp '/scratch.gloo' )
data/lib/gloo.rb CHANGED
@@ -9,13 +9,27 @@ path = File.dirname( File.absolute_path( __FILE__ ) )
9
9
  require File.join( path, 'dependencies.rb' )
10
10
 
11
11
  module Gloo
12
- def self.run
13
- params = []
14
- ( params << '--cli' ) if ARGV.count.zero?
15
12
 
13
+ #
14
+ # Run gloo as the command, with the command line's arguments.
15
+ # This is the only place that reads ARGV; an engine created
16
+ # in code uses only the params it's given.
17
+ #
18
+ def self.run( argv = ARGV )
16
19
  platform = Gloo::App::Platform.new
17
20
  context = Gloo::App::EngineContext.new(
18
- params, platform, Gloo::App::Log, nil )
21
+ params_for( argv ), platform, Gloo::App::Log, nil )
19
22
  Gloo::App::Engine.new( context ).start
20
23
  end
24
+
25
+ #
26
+ # Get the engine params for the given command line arguments.
27
+ # With no arguments, gloo runs in CLI mode.
28
+ #
29
+ def self.params_for( argv )
30
+ params = argv.dup
31
+ ( params << '--cli' ) if params.empty?
32
+ return params
33
+ end
34
+
21
35
  end
data/lib/run.rb CHANGED
@@ -5,14 +5,8 @@
5
5
  # From the /lib/ directory: ruby run.rb
6
6
  #
7
7
 
8
- # Look for all required dependencies.
8
+ # Load gloo from source, then run it with the command line's arguments.
9
9
  path = File.dirname( File.absolute_path( __FILE__ ) )
10
- require File.join( path, 'dependencies.rb' )
10
+ require File.join( path, 'gloo.rb' )
11
11
 
12
- params = []
13
- ( params << '--cli' ) if ARGV.count.zero?
14
-
15
- platform = Gloo::App::Platform.new
16
- context = Gloo::App::EngineContext.new(
17
- params, platform, Gloo::App::Log, nil )
18
- Gloo::App::Engine.new( context ).start
12
+ Gloo.run
@@ -0,0 +1,31 @@
1
+ #
2
+ # Embedded gloo tests.
3
+ # An engine created in code by another Ruby program uses only the
4
+ # params it's given, never that program's command line (ARGV).
5
+ # The engine running these tests was started as the command, so the
6
+ # check runs a separate Ruby program (a fixture) with [system].
7
+ #
8
+
9
+ tests.app.embed [can] :
10
+
11
+ # The harness, beside this file; found with source_dir.
12
+ harness [string] : /fixtures/embed_harness.rb
13
+ host_arg [string] : host_arg.gloo
14
+ no_files [string] : 0
15
+ where [string] :
16
+
17
+ run_harness [system] :
18
+ command [string] :
19
+ get_output [bool] : true
20
+ result [string] :
21
+
22
+ ignores_host_argv [test] :
23
+ description [string] : An engine created in code ignores the host program's command line.
24
+ on_test [script] :
25
+ check ^^ for source_dir
26
+ put it into ^^.where
27
+ # Paths are quoted in case the folder has spaces.
28
+ put "ruby '" ^^.where ^^.harness "' " ^^.host_arg into ^^.run_harness.command
29
+ tell ^^.run_harness to run
30
+ eval ^^.run_harness.result = ^^.no_files
31
+ assert "expected the embedded engine to be given no files"
@@ -0,0 +1,15 @@
1
+ #
2
+ # A Ruby program that creates a gloo engine in code, as an embedding
3
+ # app would, and prints how many files the engine was given.
4
+ #
5
+ # Run it with words on its own command line: the engine must not
6
+ # take them as files, so this should always print 0. The engine is
7
+ # never started, so nothing is loaded or saved even if it does.
8
+ #
9
+ # Requires this repo's lib/gloo by path, so it checks the source,
10
+ # not an installed gloo gem.
11
+ #
12
+ require_relative '../../../lib/gloo'
13
+
14
+ context = Gloo::App::EngineContext.new( [ '--quiet' ] )
15
+ print Gloo::App::Engine.new( context ).args.files.count
@@ -20,6 +20,27 @@ tests.ctrl.each [can] :
20
20
  eval ^^.count + 1
21
21
  put it into ^^.count
22
22
 
23
+ seen [string] :
24
+ lines [text] : BEGIN
25
+ one
26
+
27
+ two
28
+ END
29
+
30
+ lns [each] :
31
+ line [string] :
32
+ in [alias] : tests.ctrl.each.lines
33
+ do [script] :
34
+ put tests.ctrl.each.seen + '[' + ^.line + ']' into tests.ctrl.each.seen
35
+
36
+ each_line_without_line_endings [test] :
37
+ description [string] : each line gives each line without its line ending; a blank line is empty.
38
+ on_test [script] :
39
+ put '' into ^^.seen
40
+ tell ^^.lns to run
41
+ eval ^^.seen = '[one][][two]'
42
+ assert "expected each line without its line ending"
43
+
23
44
  each_word [test] :
24
45
  description [string] : Count words with each word
25
46
  on_test [script] :
@@ -137,3 +158,54 @@ tests.ctrl.each_folder [can] :
137
158
  eval ^^.count = 2
138
159
  assert "expected a and a/deep"
139
160
  tell ^^.remove_tree to run
161
+
162
+ #
163
+ # Each child with group_by: on_group_start sees the group's first
164
+ # child and on_group_end its last. Each start and end logs the id of
165
+ # the child it sees.
166
+ #
167
+
168
+ tests.ctrl.each_group [can] :
169
+
170
+ starts [string] :
171
+ ends [string] :
172
+
173
+ items [can] :
174
+ a [can] :
175
+ id [string] : a
176
+ kind [string] : x
177
+ b [can] :
178
+ id [string] : b
179
+ kind [string] : x
180
+ c [can] :
181
+ id [string] : c
182
+ kind [string] : y
183
+ d [can] :
184
+ id [string] : d
185
+ kind [string] : y
186
+
187
+ grouped [each] :
188
+ child [alias] :
189
+ in [alias] : tests.ctrl.each_group.items
190
+ group_by [string] : kind
191
+ on_group_start [script] :
192
+ put tests.ctrl.each_group.starts + tests.ctrl.each_group.grouped.child.id into tests.ctrl.each_group.starts
193
+ on_group_end [script] :
194
+ put tests.ctrl.each_group.ends + tests.ctrl.each_group.grouped.child.id into tests.ctrl.each_group.ends
195
+ do [script] :
196
+
197
+ group_start_sees_first_child [test] :
198
+ description [string] : on_group_start sees the first child of the new group.
199
+ on_test [script] :
200
+ put '' into ^^.starts
201
+ tell ^^.grouped to run
202
+ eval ^^.starts = 'ac'
203
+ assert "expected each group to start with its first child"
204
+
205
+ group_end_sees_last_child [test] :
206
+ description [string] : on_group_end sees the last child of the group that's ending.
207
+ on_test [script] :
208
+ put '' into ^^.ends
209
+ tell ^^.grouped to run
210
+ eval ^^.ends = 'bd'
211
+ assert "expected each group to end with its last child"
@@ -11,6 +11,31 @@ tests.verbs.create [can] :
11
11
  eval it = 'hello'
12
12
  assert "expected it to equal the created value"
13
13
 
14
+ here_box [can] :
15
+
16
+ create_with_a_here_path [test] :
17
+ description [string] : create takes a ^ path inside a script, like other verbs.
18
+ on_test [script] :
19
+ create ^^.here_box.made as string : 'made here'
20
+ eval tests.verbs.create.here_box.made = 'made here'
21
+ assert "expected ^^.here_box.made to be created"
22
+
23
+ create_with_a_one_level_here_path [test] :
24
+ description [string] : create ^.name makes a child of the script's parent (here, the test).
25
+ on_test [script] :
26
+ create ^.child_of_test as int : 3
27
+ eval tests.verbs.create.create_with_a_one_level_here_path.child_of_test = 3
28
+ assert "expected ^.child_of_test under the test"
29
+
30
+ create_with_a_context_path [test] :
31
+ description [string] : create takes an @ path, relative to the context.
32
+ on_test [script] :
33
+ context tests.verbs.create.here_box
34
+ create @.via_context as int : 5
35
+ context root
36
+ eval tests.verbs.create.here_box.via_context = 5
37
+ assert "expected @.via_context to be created in the context"
38
+
14
39
  tests.verbs.create_names [can] :
15
40
 
16
41
  err_fired [bool] : false
@@ -13,6 +13,9 @@ tests.verbs.load [can] :
13
13
  # Scratch files live in the gloo tmp folder ($.gloo_tmp).
14
14
  on_load [script] :
15
15
  put $.gloo_tmp '/gloo_load_no_objects_test.gloo' into ^.f
16
+ put $.gloo_tmp ^.wild_name into ^.wild_dir
17
+ put ^.wild_dir '/wild_a.gloo' into ^.wild_a
18
+ put ^.wild_dir '/wild_b.gloo' into ^.wild_b
16
19
 
17
20
  comments_only [text] : BEGIN
18
21
  # This file has comments,
@@ -26,6 +29,10 @@ END
26
29
 
27
30
  computed_name [string] : /gloo_load_computed_test.gloo
28
31
  lib_name [string] : md
32
+ wild_name [string] : /gloo_load_wild_test
33
+ wild_dir [file] :
34
+ wild_a [file] :
35
+ wild_b [file] :
29
36
  computed_f [file] :
30
37
  computed_fixture [text] : BEGIN
31
38
  computed_demo [can] :
@@ -138,3 +145,30 @@ END
138
145
  assert "expected load lib ( expr ) not to fire on_error"
139
146
  exists? object markdown
140
147
  assert "expected the markdown type to be registered"
148
+
149
+ load_an_absolute_wildcard_path [test] :
150
+ description [string] : load {absolute folder}/* loads every .gloo file in the folder.
151
+ on_test [script] :
152
+ tell ^^.wild_dir to mkdir
153
+ tell ^^.wild_a to write ( 'wild_a [can] :' )
154
+ tell ^^.wild_b to write ( 'wild_b [can] :' )
155
+ load ( ^^.wild_dir '/*' )
156
+ exists? wild_a
157
+ assert "expected wild_a.gloo to be loaded"
158
+ exists? wild_b
159
+ assert "expected wild_b.gloo to be loaded"
160
+ tell wild_a to unload
161
+ tell wild_b to unload
162
+ tell ^^.wild_a to delete
163
+ tell ^^.wild_b to delete
164
+
165
+ load_a_full_path_without_the_extension [test] :
166
+ description [string] : load of a full path finds the .gloo file without the extension being given.
167
+ on_test [script] :
168
+ put $.gloo_tmp ^^.computed_name into ^^.computed_f
169
+ tell ^^.computed_f to write ( ^^.computed_fixture )
170
+ load ( $.gloo_tmp '/gloo_load_computed_test' )
171
+ eval computed_demo.s = 'hi'
172
+ assert "expected the full path without .gloo to load"
173
+ tell computed_demo to unload
174
+ tell ^^.computed_f to delete
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gloo
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.1
4
+ version: 7.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Crane
@@ -442,6 +442,8 @@ files:
442
442
  - lib/gloo/verbs/version.rb
443
443
  - lib/gloo/verbs/wait.rb
444
444
  - lib/run.rb
445
+ - test.gloo/app/embed.test.gloo
446
+ - test.gloo/app/fixtures/embed_harness.rb
445
447
  - test.gloo/basic.test.gloo
446
448
  - test.gloo/ctrl/each.test.gloo
447
449
  - test.gloo/dt/date.test.gloo