gloo 6.2.1 → 6.3.0

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/.mailmap +1 -0
  3. data/docs/language_syntax.md +18 -2
  4. data/docs/objects.md +4 -0
  5. data/docs/plugins.md +12 -4
  6. data/docs/verbs.md +8 -0
  7. data/lib/VERSION +1 -1
  8. data/lib/VERSION_NOTES +4 -0
  9. data/lib/gloo/objs/basic/untyped.rb +14 -2
  10. data/lib/gloo/persist/file_loader.rb +27 -1
  11. data/lib/gloo/verbs/check.rb +16 -4
  12. data/lib/gloo/verbs/create.rb +8 -3
  13. data/lib/gloo/verbs/eval.rb +16 -2
  14. data/lib/gloo/verbs/tell.rb +15 -3
  15. data/lib/gloo/verbs/throw.rb +29 -1
  16. data/test.gloo/lang/continuation.test.gloo +39 -0
  17. data/test.gloo/lang/convert.test.gloo +70 -0
  18. data/test.gloo/lang/here.test.gloo +41 -0
  19. data/test.gloo/lang/it.test.gloo +41 -0
  20. data/test.gloo/lang/literal.test.gloo +61 -0
  21. data/test.gloo/lang/load_lib_directive.test.gloo +33 -0
  22. data/test.gloo/lang/naming.test.gloo +44 -0
  23. data/test.gloo/objs/cipher.test.gloo +45 -0
  24. data/test.gloo/objs/erb.test.gloo +18 -0
  25. data/test.gloo/objs/file.test.gloo +77 -0
  26. data/test.gloo/objs/function.test.gloo +54 -0
  27. data/test.gloo/objs/json.test.gloo +70 -0
  28. data/test.gloo/objs/outline.test.gloo +72 -0
  29. data/test.gloo/objs/password.test.gloo +40 -0
  30. data/test.gloo/objs/repeat.test.gloo +48 -0
  31. data/test.gloo/objs/untyped.test.gloo +20 -2
  32. data/test.gloo/objs/uri.test.gloo +43 -0
  33. data/test.gloo/verbs/context.test.gloo +19 -0
  34. data/test.gloo/verbs/list.test.gloo +34 -0
  35. data/test.gloo/verbs/load.test.gloo +32 -0
  36. data/test.gloo/verbs/show.test.gloo +37 -0
  37. data/test.gloo/verbs/throw.test.gloo +44 -0
  38. data/test.gloo/verbs/unload.test.gloo +21 -0
  39. metadata +23 -1
@@ -0,0 +1,33 @@
1
+ #
2
+ # Top-of-file 'load lib' directive test
3
+ #
4
+ # The line below runs before this file's object tree is built, so a
5
+ # core-library type is available to declarations in the same file.
6
+ #
7
+ load lib yaml
8
+
9
+ tests [can] :
10
+ lang [can] :
11
+ load_lib_directive [can] :
12
+
13
+ # this declaration only parses because 'load lib yaml' above
14
+ # registered the type before the loader got here
15
+ cfg [yaml] :
16
+
17
+ library_type_is_available [test] :
18
+ description [string] : a load lib directive at the top of the file registers the library's types.
19
+ on_test [script] :
20
+ exists? object yaml
21
+ assert "expected the yaml type to be registered by the directive"
22
+
23
+ exists? object yml
24
+ assert "expected the yaml short name to be registered too"
25
+
26
+ typed_object_was_created [test] :
27
+ description [string] : an object of the library's type declared in the same file exists.
28
+ on_test [script] :
29
+ exists? instance tests.lang.load_lib_directive.cfg
30
+ assert "expected the [yaml] object to have been created during load"
31
+
32
+ check tests.lang.load_lib_directive.cfg for responds_to? ( 'load' )
33
+ assert "expected it to be a real yaml object that responds to load"
@@ -0,0 +1,44 @@
1
+ #
2
+ # Object naming tests
3
+ #
4
+
5
+ tests [can] :
6
+ lang [can] :
7
+ naming [can] :
8
+
9
+ dup [string] : first
10
+ dup [string] : second
11
+
12
+ Alpha [string] : mixed case
13
+
14
+ 1 [string] : numeric name
15
+
16
+ string [string] : a type keyword as a name
17
+ put [string] : a verb keyword as a name
18
+
19
+ first_of_a_duplicate_name_wins [test] :
20
+ description [string] : when two siblings share a name, the path always reaches the first.
21
+ on_test [script] :
22
+ eval ^^.dup = 'first'
23
+ assert "expected the first 'dup' to be the one reached"
24
+
25
+ path_lookup_is_case_insensitive [test] :
26
+ description [string] : a pathname segment matches a name regardless of case.
27
+ on_test [script] :
28
+ eval tests.lang.naming.alpha = 'mixed case'
29
+ assert "expected lower-case lookup to find 'Alpha'"
30
+
31
+ eval tests.lang.naming.ALPHA = 'mixed case'
32
+ assert "expected upper-case lookup to find 'Alpha'"
33
+
34
+ numeric_and_keyword_names [test] :
35
+ description [string] : digits and reserved-looking words are valid object names.
36
+ on_test [script] :
37
+ eval tests.lang.naming.1 = 'numeric name'
38
+ assert "expected a numeric name to work"
39
+
40
+ eval ^^.string = 'a type keyword as a name'
41
+ assert "expected a type keyword to be usable as a name"
42
+
43
+ eval ^^.put = 'a verb keyword as a name'
44
+ assert "expected a verb keyword to be usable as a name"
@@ -0,0 +1,45 @@
1
+ #
2
+ # Cipher object tests
3
+ #
4
+
5
+ tests [can] :
6
+ objs [can] :
7
+ cipher [can] :
8
+
9
+ plaintext [string] : attack at dawn
10
+
11
+ round_trip [test] :
12
+ description [string] : encrypt then decrypt returns the original text.
13
+ on_test [script] :
14
+ create tests.objs.cipher.c as cipher
15
+
16
+ tell tests.objs.cipher.c to generate_keys
17
+ check tests.objs.cipher.c.key for blank?
18
+ refute "expected generate_keys to set a key"
19
+
20
+ put ^^.plaintext into tests.objs.cipher.c.data
21
+ tell tests.objs.cipher.c to encrypt
22
+ eval tests.objs.cipher.c.data = ^^.plaintext
23
+ refute "expected the data to be encrypted (not the plaintext)"
24
+
25
+ tell tests.objs.cipher.c to decrypt
26
+ eval tests.objs.cipher.c.data = ^^.plaintext
27
+ assert "expected decrypt to restore the original text"
28
+
29
+ shared_keys [test] :
30
+ description [string] : a second cipher with the same key + init_vector can decrypt.
31
+ on_test [script] :
32
+ create tests.objs.cipher.a as cipher
33
+ create tests.objs.cipher.b as cipher
34
+
35
+ tell tests.objs.cipher.a to generate_keys
36
+ put ^^.plaintext into tests.objs.cipher.a.data
37
+ tell tests.objs.cipher.a to encrypt
38
+
39
+ put tests.objs.cipher.a.key into tests.objs.cipher.b.key
40
+ put tests.objs.cipher.a.init_vector into tests.objs.cipher.b.init_vector
41
+ put tests.objs.cipher.a.data into tests.objs.cipher.b.data
42
+
43
+ tell tests.objs.cipher.b to decrypt
44
+ eval tests.objs.cipher.b.data = ^^.plaintext
45
+ assert "expected the second cipher to decrypt with the shared key"
@@ -20,6 +20,12 @@ tests [can] :
20
20
  name [string] : gloo
21
21
  result [text] :
22
22
 
23
+ with_logic [erb] :
24
+ template [text] : <%= n == "yes" ? "ACTIVE" : "closed" %>
25
+ params [can] :
26
+ n [string] : no
27
+ result [text] :
28
+
23
29
  run_basic [test] :
24
30
  description [string] : Render a template with a param
25
31
  on_test [script] :
@@ -33,3 +39,15 @@ tests [can] :
33
39
  tell ^^.aliased_template to run
34
40
  eval ^^.aliased_template.result = 'gloo!!'
35
41
  assert "expected alias to be resolved before rendering the template"
42
+
43
+ run_with_logic [test] :
44
+ description [string] : A <% %> tag runs Ruby; the param drives which branch renders
45
+ on_test [script] :
46
+ tell ^^.with_logic to run
47
+ eval ^^.with_logic.result = 'closed'
48
+ assert "expected the 'no' param to render the closed branch"
49
+
50
+ put 'yes' into ^^.with_logic.params.n
51
+ tell ^^.with_logic to run
52
+ eval ^^.with_logic.result = 'ACTIVE'
53
+ assert "expected the 'yes' param to render the ACTIVE branch"
@@ -0,0 +1,77 @@
1
+ #
2
+ # File object tests
3
+ #
4
+ # The file object's value is a path. These tests write a scratch
5
+ # file under /tmp, exercise it, and delete it at the end.
6
+ #
7
+
8
+ tests [can] :
9
+ objs [can] :
10
+ file [can] :
11
+
12
+ f [file] : /tmp/gloo_file_test.txt
13
+ names [file] : /Users/me/project/report.csv
14
+
15
+ first [string] : first line
16
+ second [string] : second line
17
+ back [string] :
18
+
19
+ write_read_round_trip [test] :
20
+ description [string] : write puts an object's value in the file; read gets it back.
21
+ on_test [script] :
22
+ tell ^^.f to write ( ^^.first )
23
+
24
+ check ^^.f for exists?
25
+ assert "expected the file to exist after write"
26
+
27
+ check ^^.f for is_file?
28
+ assert "expected exists to be a regular file"
29
+
30
+ check ^^.f for is_dir?
31
+ refute "expected the file not to be a directory"
32
+
33
+ tell ^^.f to read ( ^^.back )
34
+ eval ^^.back = 'first line'
35
+ assert "expected read to return what was written"
36
+
37
+ tell ^^.f to delete
38
+
39
+ append_adds_a_line [test] :
40
+ description [string] : append adds a new line to the file.
41
+ on_test [script] :
42
+ tell ^^.f to write ( ^^.first )
43
+ tell ^^.f to append ( ^^.second )
44
+
45
+ tell ^^.f to read ( ^^.back )
46
+ check ^^.back for substring? ( "first line" )
47
+ assert "expected the original line to still be there"
48
+ check ^^.back for substring? ( "second line" )
49
+ assert "expected the appended line to be there"
50
+
51
+ tell ^^.f to delete
52
+
53
+ path_parts [test] :
54
+ description [string] : get_name, get_ext and get_parent read the path, not the disk.
55
+ on_test [script] :
56
+ tell ^^.names to get_name
57
+ eval it = 'report'
58
+ assert "expected the base name without extension"
59
+
60
+ tell ^^.names to get_ext
61
+ eval it = '.csv'
62
+ assert "expected the extension"
63
+
64
+ tell ^^.names to get_parent
65
+ eval it = '/Users/me/project'
66
+ assert "expected the parent directory"
67
+
68
+ delete_removes_the_file [test] :
69
+ description [string] : delete removes the file from disk.
70
+ on_test [script] :
71
+ tell ^^.f to write ( ^^.first )
72
+ check ^^.f for exists?
73
+ assert "sanity: file exists before delete"
74
+
75
+ tell ^^.f to delete
76
+ check ^^.f for exists?
77
+ refute "expected the file to be gone after delete"
@@ -0,0 +1,54 @@
1
+ #
2
+ # Function object tests
3
+ #
4
+ # The 'invoke' verb and inline invoke( ... ) are covered in
5
+ # verbs/invoke.test.gloo. These tests cover the function object
6
+ # itself: the 'invoke' message, param defaults, and the
7
+ # after_invoke event.
8
+ #
9
+
10
+ tests [can] :
11
+ objs [can] :
12
+ function [can] :
13
+
14
+ after_ran [bool] : false
15
+
16
+ greet [ƒ] :
17
+ params [can] :
18
+ name [string] : Default Person
19
+ on_invoke [script] :
20
+ put 'Hi, ' + ^.params.name into ^.result
21
+ after_invoke [script] :
22
+ put true into tests.objs.function.after_ran
23
+ result [string] :
24
+
25
+ boom [ƒ] :
26
+ params [can] :
27
+ on_invoke [script] :
28
+ put no_such_object into ^.result
29
+ after_invoke [script] :
30
+ put true into tests.objs.function.after_ran
31
+ result [string] :
32
+
33
+ invoke_message_uses_param_defaults [test] :
34
+ description [string] : the invoke message with no args runs on_invoke against the param defaults.
35
+ on_test [script] :
36
+ tell ^^.greet to invoke
37
+ eval ^^.greet.result = 'Hi, Default Person'
38
+ assert "expected on_invoke to run with the default param value"
39
+
40
+ after_invoke_runs_on_success [test] :
41
+ description [string] : after_invoke runs once the function has been invoked.
42
+ on_test [script] :
43
+ put false into ^^.after_ran
44
+ tell ^^.greet to invoke
45
+ eval ^^.after_ran = true
46
+ assert "expected after_invoke to run after a successful invoke"
47
+
48
+ after_invoke_runs_on_failure [test] :
49
+ description [string] : after_invoke still runs when on_invoke hits an error.
50
+ on_test [script] :
51
+ put false into ^^.after_ran
52
+ tell ^^.boom to invoke
53
+ eval ^^.after_ran = true
54
+ assert "expected after_invoke to run even after on_invoke failed"
@@ -0,0 +1,70 @@
1
+ #
2
+ # JSON object tests
3
+ #
4
+
5
+ tests [can] :
6
+ objs [can] :
7
+ json [can] :
8
+
9
+ payload [json] : BEGIN
10
+ { "title":"Brute Force",
11
+ "meta":{ "author":"ESR", "year":"2003" } }
12
+ END
13
+
14
+ compact [json] : {"a":"1","b":{"c":"2"}}
15
+
16
+ source [can] :
17
+ name [string] : gloo
18
+ kind [string] : language
19
+
20
+ built [json] :
21
+ out [can] :
22
+ found [string] :
23
+
24
+ get_a_value [test] :
25
+ description [string] : get pulls a value out by dotted path.
26
+ on_test [script] :
27
+ tell ^^.payload to get ( 'title' )
28
+ eval it = 'Brute Force'
29
+ assert "expected the top-level title"
30
+
31
+ tell ^^.payload to get ( 'meta.author' )
32
+ eval it = 'ESR'
33
+ assert "expected the nested author"
34
+
35
+ get_missing_is_blank [test] :
36
+ description [string] : get for a path that isn't there returns blank.
37
+ on_test [script] :
38
+ tell ^^.payload to get ( 'nope' )
39
+ put it into tests.objs.json.found
40
+ check tests.objs.json.found for blank?
41
+ assert "expected a missing path to return blank"
42
+
43
+ parse_into_objects [test] :
44
+ description [string] : parse builds an object tree from the JSON.
45
+ on_test [script] :
46
+ tell ^^.payload to parse ( tests.objs.json.out )
47
+
48
+ eval tests.objs.json.out.title = 'Brute Force'
49
+ assert "expected parse to set the title"
50
+
51
+ eval tests.objs.json.out.meta.author = 'ESR'
52
+ assert "expected parse to build the nested meta container"
53
+
54
+ set_from_objects_round_trip [test] :
55
+ description [string] : set serialises an object tree; get reads it back.
56
+ on_test [script] :
57
+ # a path inside ( ) params must be absolute, not a ^ ref
58
+ tell ^^.built to set ( tests.objs.json.source )
59
+
60
+ tell ^^.built to get ( 'name' )
61
+ eval it = 'gloo'
62
+ assert "expected set then get to round-trip a value"
63
+
64
+ pretty_keeps_it_valid [test] :
65
+ description [string] : pretty reformats the text without breaking it.
66
+ on_test [script] :
67
+ tell ^^.compact to pretty
68
+ tell ^^.compact to get ( 'b.c' )
69
+ eval it = '2'
70
+ assert "expected the value to still be reachable after pretty"
@@ -0,0 +1,72 @@
1
+ #
2
+ # Outline object tests
3
+ #
4
+ # 'generate' turns a flat list of path-structured names into a nested
5
+ # <ul>/<li> outline. Each source item is a container whose first
6
+ # child is the id and whose second child is the name.
7
+ #
8
+
9
+ tests [can] :
10
+ objs [can] :
11
+ outline [can] :
12
+
13
+ src [container] :
14
+ 1 [container] :
15
+ id [int] : 1
16
+ name [string] : a/b/c
17
+ 2 [container] :
18
+ id [int] : 2
19
+ name [string] : a/b/d
20
+ 3 [container] :
21
+ id [int] : 3
22
+ name [string] : top
23
+
24
+ dotted [container] :
25
+ 1 [container] :
26
+ id [int] : 9
27
+ name [string] : x.y.z
28
+
29
+ linked [outline] :
30
+ object_source [alias] : tests.objs.outline.src
31
+ entity_path [string] : /entity/
32
+ separator_char [string] : /
33
+ data [string] :
34
+
35
+ plain [outline] :
36
+ object_source [alias] : tests.objs.outline.dotted
37
+ separator_char [string] : .
38
+ data [string] :
39
+
40
+ builds_nested_html_with_links [test] :
41
+ description [string] : generate nests shared path segments and links leaves that have an id.
42
+ on_test [script] :
43
+ tell ^^.linked to generate
44
+
45
+ check ^^.linked.data for starts_with? ( "<ul>" )
46
+ assert "expected the outline to start with <ul>"
47
+
48
+ check ^^.linked.data for substring? ( "<li>a</li>" )
49
+ assert "expected a shared 'a' segment as a plain node"
50
+
51
+ check ^^.linked.data for substring? ( "<li>b</li>" )
52
+ assert "expected a shared 'b' segment as a plain node"
53
+
54
+ check ^^.linked.data for substring? ( "<a href='/entity/1'>c</a>" )
55
+ assert "expected leaf 'c' to be linked with its id and entity_path"
56
+
57
+ check ^^.linked.data for substring? ( "<a href='/entity/3'>top</a>" )
58
+ assert "expected the top-level 'top' item to be linked"
59
+
60
+ custom_separator_and_no_links [test] :
61
+ description [string] : separator_char sets the split char; with no entity_path leaves are plain.
62
+ on_test [script] :
63
+ tell ^^.plain to generate
64
+
65
+ check ^^.plain.data for substring? ( "<li>x</li>" )
66
+ assert "expected '.' to split x.y.z so 'x' is its own node"
67
+
68
+ check ^^.plain.data for substring? ( "<li>z</li>" )
69
+ assert "expected leaf 'z' rendered plain (no entity_path)"
70
+
71
+ check ^^.plain.data for substring? ( "href" )
72
+ refute "expected no links when entity_path is not set"
@@ -0,0 +1,40 @@
1
+ #
2
+ # Password object tests
3
+ #
4
+
5
+ tests [can] :
6
+ objs [can] :
7
+ password [can] :
8
+
9
+ hash_and_check [test] :
10
+ description [string] : check succeeds for the right password and fails for the wrong one.
11
+ on_test [script] :
12
+ create tests.objs.password.p as password
13
+ put 'user-1' into tests.objs.password.p.salt
14
+ put 's3cret' into tests.objs.password.p.password
15
+ tell tests.objs.password.p to hash
16
+
17
+ check tests.objs.password.p.hash for blank?
18
+ refute "expected hash to be populated"
19
+
20
+ tell tests.objs.password.p to check
21
+ assert "expected check to pass for the original password"
22
+
23
+ put 'not the password' into tests.objs.password.p.password
24
+ tell tests.objs.password.p to check
25
+ refute "expected check to fail for a wrong password"
26
+
27
+ generate_length [test] :
28
+ description [string] : generate makes a password of the requested length and puts it in it.
29
+ on_test [script] :
30
+ create tests.objs.password.g as password
31
+
32
+ tell tests.objs.password.g to generate
33
+ tell tests.objs.password.g.password to size
34
+ eval it = 7
35
+ assert "expected the default generated length to be 7"
36
+
37
+ tell tests.objs.password.g to generate ( 20 )
38
+ tell tests.objs.password.g.password to size
39
+ eval it = 20
40
+ assert "expected the generated length to be 20"
@@ -0,0 +1,48 @@
1
+ #
2
+ # Repeat object tests
3
+ #
4
+
5
+ tests [can] :
6
+ objs [can] :
7
+ repeat [can] :
8
+
9
+ count [int] : 0
10
+ seen [string] :
11
+
12
+ loop [repeat] :
13
+ times [integer] : 4
14
+ index [integer] : 0
15
+ do [script] :
16
+ put tests.objs.repeat.count + 1 into tests.objs.repeat.count
17
+ put tests.objs.repeat.seen + tests.objs.repeat.loop.index into tests.objs.repeat.seen
18
+
19
+ zero [repeat] :
20
+ times [integer] : 0
21
+ index [integer] : 0
22
+ do [script] :
23
+ put tests.objs.repeat.count + 100 into tests.objs.repeat.count
24
+
25
+ runs_the_do_script_n_times [test] :
26
+ description [string] : run executes 'do' once per 'times', and 'index' walks 0..times-1.
27
+ on_test [script] :
28
+ put 0 into ^^.count
29
+ put '' into ^^.seen
30
+
31
+ tell ^^.loop to run
32
+
33
+ eval ^^.count = 4
34
+ assert "expected the do script to run 4 times"
35
+
36
+ eval ^^.seen = '0123'
37
+ assert "expected index to be 0,1,2,3 across the iterations"
38
+
39
+ eval ^^.loop.index = 3
40
+ assert "expected index to be left at times-1 after the run"
41
+
42
+ zero_times_does_nothing [test] :
43
+ description [string] : run with times = 0 never executes 'do'.
44
+ on_test [script] :
45
+ put 0 into ^^.count
46
+ tell ^^.zero to run
47
+ eval ^^.count = 0
48
+ assert "expected the do script not to run when times is 0"
@@ -1,12 +1,12 @@
1
1
  #
2
- # Script tests
2
+ # Untyped object tests
3
3
  #
4
4
 
5
5
  tests [can] :
6
6
  objs [can] :
7
7
  untyped [can] :
8
8
 
9
- a [any] :
9
+ a [any] :
10
10
 
11
11
  test_untyped [test] :
12
12
  description [string] : Test untyped with different values
@@ -23,3 +23,21 @@ tests [can] :
23
23
  eval ^^.a = true
24
24
  assert "expected it to be true"
25
25
 
26
+ base_messages_work [test] :
27
+ description [string] : an untyped object still receives the base object messages
28
+ on_test [script] :
29
+ put "" into ^^.a
30
+ check ^^.a for blank?
31
+ assert "expected an empty untyped object to be blank"
32
+
33
+ put "x" into ^^.a
34
+ check ^^.a for blank?
35
+ refute "expected a non-empty untyped object to not be blank"
36
+
37
+ type_messages_do_not [test] :
38
+ description [string] : an untyped object does not receive type-specific messages
39
+ on_test [script] :
40
+ put "hello" into ^^.a
41
+ check ^^.a for responds_to? ( "up" )
42
+ refute "expected an untyped object to not respond to 'up'"
43
+
@@ -0,0 +1,43 @@
1
+ #
2
+ # URI object tests
3
+ #
4
+
5
+ tests [can] :
6
+ objs [can] :
7
+ uri [can] :
8
+
9
+ link [uri] : https://example.com:8443/docs/guide?page=3&sort=asc#install
10
+ bare [uri] : https://example.com
11
+
12
+ parts_of_a_url [test] :
13
+ description [string] : the get_ messages pull each piece of the URL into it.
14
+ on_test [script] :
15
+ tell ^^.link to get_scheme
16
+ eval it = 'https'
17
+ assert "expected scheme https"
18
+
19
+ tell ^^.link to get_host
20
+ eval it = 'example.com'
21
+ assert "expected host example.com (no port)"
22
+
23
+ tell ^^.link to get_path
24
+ eval it = '/docs/guide'
25
+ assert "expected path /docs/guide"
26
+
27
+ tell ^^.link to get_query
28
+ eval it = 'page=3&sort=asc'
29
+ assert "expected the query string"
30
+
31
+ tell ^^.link to get_fragment
32
+ eval it = 'install'
33
+ assert "expected fragment install"
34
+
35
+ missing_pieces [test] :
36
+ description [string] : a bare URL has an empty path.
37
+ on_test [script] :
38
+ tell ^^.bare to get_path
39
+ put it into tests.objs.uri.result
40
+ check tests.objs.uri.result for blank?
41
+ assert "expected the path of a bare URL to be blank"
42
+
43
+ result [string] :
@@ -0,0 +1,19 @@
1
+ #
2
+ # Context verb tests
3
+ #
4
+
5
+ tests [can] :
6
+ verbs [can] :
7
+ context [can] :
8
+
9
+ set_context [test] :
10
+ description [string] : context {path} sets the context and puts the path in it.
11
+ on_test [script] :
12
+ context tests.verbs.context
13
+ eval it = 'tests.verbs.context'
14
+ assert "expected it to be the new context path"
15
+
16
+ # restore, so later tests run at root
17
+ context root
18
+ eval it = 'root'
19
+ assert "expected context to be restored to root"
@@ -0,0 +1,34 @@
1
+ #
2
+ # List verb tests
3
+ #
4
+ # 'list' only writes to the console, so these tests check its error
5
+ # behaviour rather than its output.
6
+ #
7
+
8
+ tests [can] :
9
+ verbs [can] :
10
+ list [can] :
11
+
12
+ data [can] :
13
+ a [string] : A
14
+ b [string] : B
15
+
16
+ err_fired [bool] : false
17
+ on_error [script] :
18
+ put true into ^.err_fired
19
+
20
+ list_real_container [test] :
21
+ description [string] : listing a real container does not fire on_error.
22
+ on_test [script] :
23
+ put false into ^^.err_fired
24
+ list tests.verbs.list.data
25
+ eval ^^.err_fired = false
26
+ assert "listing a real container should not fire on_error"
27
+
28
+ list_missing_target [test] :
29
+ description [string] : listing a missing target fires on_error.
30
+ on_test [script] :
31
+ put false into ^^.err_fired
32
+ list tests.verbs.list.no_such_thing
33
+ eval ^^.err_fired = true
34
+ assert "listing a missing target should fire on_error"
@@ -0,0 +1,32 @@
1
+ #
2
+ # Load verb tests
3
+ #
4
+ # Uses 'load lib' because it is self-contained (no fixture files) and
5
+ # its effect is observable through 'exists?'.
6
+ #
7
+
8
+ tests [can] :
9
+ verbs [can] :
10
+ load [can] :
11
+
12
+ err_fired [bool] : false
13
+ on_error [script] :
14
+ put true into ^.err_fired
15
+
16
+ load_lib_registers_type [test] :
17
+ description [string] : load lib registers that library's object types.
18
+ on_test [script] :
19
+ exists? object markdown
20
+ refute "markdown type should not be registered before load"
21
+
22
+ load lib md
23
+ exists? object markdown
24
+ assert "expected the markdown type to be registered after 'load lib md'"
25
+
26
+ load_no_args_errors [test] :
27
+ description [string] : load with no arguments fires on_error.
28
+ on_test [script] :
29
+ put false into ^^.err_fired
30
+ load
31
+ eval ^^.err_fired = true
32
+ assert "expected 'load' with no arguments to fire on_error"