levels 0.1.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 (90) hide show
  1. data/.gitignore +17 -0
  2. data/.rbenv-version +1 -0
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +12 -0
  5. data/Guardfile +14 -0
  6. data/LICENSE +22 -0
  7. data/README.md +315 -0
  8. data/Rakefile +28 -0
  9. data/bin/levels +130 -0
  10. data/examples/01_base.rb +6 -0
  11. data/examples/01_merge_to_json.sh +27 -0
  12. data/examples/01_prod.json +8 -0
  13. data/examples/02_base.rb +4 -0
  14. data/examples/02_merge_with_file.sh +20 -0
  15. data/examples/02_value +1 -0
  16. data/levels.gemspec +20 -0
  17. data/lib/levels.rb +77 -0
  18. data/lib/levels/audit.rb +24 -0
  19. data/lib/levels/audit/group_observer.rb +26 -0
  20. data/lib/levels/audit/nested_group_observer.rb +37 -0
  21. data/lib/levels/audit/root_observer.rb +63 -0
  22. data/lib/levels/audit/value.rb +64 -0
  23. data/lib/levels/audit/value_observer.rb +46 -0
  24. data/lib/levels/audit/values.rb +66 -0
  25. data/lib/levels/configuration.rb +98 -0
  26. data/lib/levels/configured_group.rb +62 -0
  27. data/lib/levels/event_handler.rb +127 -0
  28. data/lib/levels/group.rb +61 -0
  29. data/lib/levels/input/json.rb +17 -0
  30. data/lib/levels/input/ruby.rb +120 -0
  31. data/lib/levels/input/system.rb +63 -0
  32. data/lib/levels/input/yaml.rb +17 -0
  33. data/lib/levels/key.rb +28 -0
  34. data/lib/levels/key_values.rb +54 -0
  35. data/lib/levels/lazy_evaluator.rb +54 -0
  36. data/lib/levels/level.rb +80 -0
  37. data/lib/levels/method_missing.rb +14 -0
  38. data/lib/levels/output/json.rb +33 -0
  39. data/lib/levels/output/system.rb +29 -0
  40. data/lib/levels/output/yaml.rb +19 -0
  41. data/lib/levels/runtime.rb +30 -0
  42. data/lib/levels/setup.rb +132 -0
  43. data/lib/levels/system/constants.rb +8 -0
  44. data/lib/levels/system/key_formatter.rb +15 -0
  45. data/lib/levels/system/key_generator.rb +50 -0
  46. data/lib/levels/system/key_parser.rb +67 -0
  47. data/lib/levels/version.rb +3 -0
  48. data/test/acceptance/audit_test.rb +105 -0
  49. data/test/acceptance/event_handler_test.rb +43 -0
  50. data/test/acceptance/read_json_test.rb +35 -0
  51. data/test/acceptance/read_ruby_test.rb +117 -0
  52. data/test/acceptance/read_system_test.rb +121 -0
  53. data/test/acceptance/read_yaml_test.rb +38 -0
  54. data/test/acceptance/setup_test.rb +115 -0
  55. data/test/acceptance/write_json_test.rb +39 -0
  56. data/test/acceptance/write_system_test.rb +68 -0
  57. data/test/acceptance/write_yaml_test.rb +33 -0
  58. data/test/bin/merge_test.rb +194 -0
  59. data/test/bin/options_test.rb +41 -0
  60. data/test/helper.rb +12 -0
  61. data/test/support/acceptance_spec.rb +58 -0
  62. data/test/support/base_spec.rb +14 -0
  63. data/test/support/bin_spec.rb +65 -0
  64. data/test/support/tempfile_helper.rb +35 -0
  65. data/test/unit/audit/group_observer_test.rb +24 -0
  66. data/test/unit/audit/nested_group_observer_test.rb +28 -0
  67. data/test/unit/audit/root_observer_test.rb +54 -0
  68. data/test/unit/audit/value_observer_test.rb +63 -0
  69. data/test/unit/audit/value_test.rb +41 -0
  70. data/test/unit/audit/values_test.rb +86 -0
  71. data/test/unit/configuration_test.rb +72 -0
  72. data/test/unit/configured_group_test.rb +75 -0
  73. data/test/unit/group_test.rb +105 -0
  74. data/test/unit/input/json_test.rb +32 -0
  75. data/test/unit/input/ruby_test.rb +140 -0
  76. data/test/unit/input/system_test.rb +59 -0
  77. data/test/unit/input/yaml_test.rb +33 -0
  78. data/test/unit/key_test.rb +45 -0
  79. data/test/unit/key_values_test.rb +106 -0
  80. data/test/unit/lazy_evaluator_test.rb +38 -0
  81. data/test/unit/level_test.rb +89 -0
  82. data/test/unit/levels_test.rb +23 -0
  83. data/test/unit/output/json_test.rb +55 -0
  84. data/test/unit/output/system_test.rb +32 -0
  85. data/test/unit/output/yaml_test.rb +38 -0
  86. data/test/unit/runtime_test.rb +40 -0
  87. data/test/unit/system/key_formatter_test.rb +43 -0
  88. data/test/unit/system/key_generator_test.rb +21 -0
  89. data/test/unit/system/key_parser_test.rb +207 -0
  90. metadata +215 -0
@@ -0,0 +1,121 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: read system" do
4
+
5
+ def read_system(level_name, template, prefix, env)
6
+ key_formatter = Levels::System::KeyFormatter.new(prefix)
7
+ level = Levels::Level.new(level_name)
8
+ input = Levels::Input::System.new(template, key_formatter, env)
9
+ input.read(level)
10
+ level
11
+ end
12
+
13
+ describe "using typecast information" do
14
+
15
+ let(:template) {
16
+ level = Levels::Level.new("template level")
17
+ level.set_group(:types,
18
+ string: nil,
19
+ integer: nil,
20
+ float: nil,
21
+ boolean_true: nil,
22
+ boolean_false: nil,
23
+ array_of_string: nil,
24
+ array_of_integer: nil,
25
+ null: nil
26
+ )
27
+ level.set_group(:group2,
28
+ message: nil
29
+ )
30
+ level
31
+ }
32
+
33
+ let(:env) {
34
+ {
35
+ "TYPES_STRING" => "hello",
36
+ "TYPES_INTEGER" => "123",
37
+ "TYPES_INTEGER_TYPE" => "integer",
38
+ "TYPES_FLOAT" => "1.5",
39
+ "TYPES_FLOAT_TYPE" => "float",
40
+ "TYPES_BOOLEAN_TRUE" => "true",
41
+ "TYPES_BOOLEAN_TRUE_TYPE" => "boolean",
42
+ "TYPES_BOOLEAN_FALSE" => "false",
43
+ "TYPES_BOOLEAN_FALSE_TYPE" => "boolean",
44
+ "TYPES_ARRAY_OF_STRING" => "a:b:c",
45
+ "TYPES_ARRAY_OF_STRING_TYPE" => "array",
46
+ "TYPES_ARRAY_OF_INTEGER" => "1:2:3",
47
+ "TYPES_ARRAY_OF_INTEGER_TYPE" => "array",
48
+ "TYPES_ARRAY_OF_INTEGER_TYPE_TYPE" => "integer",
49
+ "TYPES_NULL" => "",
50
+ "GROUP2_MESSAGE" => "hello world"
51
+ }
52
+ }
53
+
54
+ subject { read_system("the system", template.to_enum, nil, env) }
55
+
56
+ assert_sample_data_set
57
+ end
58
+
59
+ describe "using the template's types" do
60
+
61
+ let(:template) {
62
+ level = Levels::Level.new("template level")
63
+ level.set_group(:types,
64
+ string: "!hello",
65
+ integer: 0123,
66
+ float: 1.55,
67
+ boolean_true: false,
68
+ boolean_false: true,
69
+ array_of_string: ["a", "a", "a"],
70
+ array_of_integer: [1, 1, 1],
71
+ null: 999
72
+ )
73
+ level.set_group(:group2,
74
+ message: "hello there"
75
+ )
76
+ level
77
+ }
78
+
79
+ let(:env) {
80
+ {
81
+ "TYPES_STRING" => "hello",
82
+ "TYPES_INTEGER" => "123",
83
+ "TYPES_FLOAT" => "1.5",
84
+ "TYPES_BOOLEAN_TRUE" => "true",
85
+ "TYPES_BOOLEAN_FALSE" => "false",
86
+ "TYPES_ARRAY_OF_STRING" => "a:b:c",
87
+ "TYPES_ARRAY_OF_INTEGER" => "1:2:3",
88
+ "TYPES_NULL" => "",
89
+ "GROUP2_MESSAGE" => "hello world"
90
+ }
91
+ }
92
+
93
+ subject { read_system("the system", template.to_enum, nil, env) }
94
+
95
+ assert_sample_data_set
96
+ end
97
+
98
+ describe "using a prefix" do
99
+
100
+ let(:template) {
101
+ level = Levels::Level.new("template level")
102
+ level.set_group(:group,
103
+ message: "hello there"
104
+ )
105
+ level
106
+ }
107
+
108
+ let(:env) {
109
+ {
110
+ "PREFIX_GROUP_MESSAGE" => "hello world"
111
+ }
112
+ }
113
+
114
+ subject { read_system("the system", template.to_enum, "PREFIX_", env) }
115
+
116
+ it "finds values" do
117
+ subject.group.message.must_equal "hello world"
118
+ end
119
+ end
120
+ end
121
+
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: read yaml" do
4
+
5
+ def read_yaml(level_name, yaml_string)
6
+ level = Levels::Level.new(level_name)
7
+ input = Levels::Input::YAML.new(yaml_string)
8
+ input.read(level)
9
+ level
10
+ end
11
+
12
+ let(:yaml) {
13
+ <<-YAML
14
+ types:
15
+ string: hello
16
+ integer: 123
17
+ float: 1.5
18
+ boolean_true: true
19
+ boolean_false: false
20
+ array_of_string:
21
+ - a
22
+ - b
23
+ - c
24
+ array_of_integer:
25
+ - 1
26
+ - 2
27
+ - 3
28
+ "null": null
29
+ group2:
30
+ message: hello world
31
+ YAML
32
+ }
33
+
34
+ subject { read_yaml("test", yaml) }
35
+
36
+ assert_sample_data_set
37
+ end
38
+
@@ -0,0 +1,115 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: the Setup" do
4
+
5
+ subject { Levels::Setup.new }
6
+
7
+ describe "reading various inputs" do
8
+
9
+ let(:ruby_code) do
10
+ <<-RUBY
11
+ group :group
12
+ set a: 1
13
+ RUBY
14
+ end
15
+
16
+ let(:json_code) do
17
+ <<-JSON
18
+ {
19
+ "group": {
20
+ "a": 1
21
+ }
22
+ }
23
+ JSON
24
+ end
25
+
26
+ let(:yaml_code) do
27
+ <<-YAML
28
+ ---
29
+ group:
30
+ a: 1
31
+ YAML
32
+ end
33
+
34
+ it "adds a custom source" do
35
+ custom_input = Class.new do
36
+ def read(level)
37
+ level.set_group(:group, a: 1)
38
+ end
39
+ end
40
+ custom = custom_input.new
41
+
42
+ subject.add("custom", custom)
43
+ subject.merge.group.a.must_equal 1
44
+ end
45
+
46
+ it "adds ruby code" do
47
+ subject.add("code", ruby_code)
48
+ subject.merge.group.a.must_equal 1
49
+ end
50
+
51
+ it "adds JSON code" do
52
+ subject.add("code", json_code)
53
+ subject.merge.group.a.must_equal 1
54
+ end
55
+
56
+ it "adds YAML code" do
57
+ subject.add("code", yaml_code)
58
+ subject.merge.group.a.must_equal 1
59
+ end
60
+
61
+ it "adds a ruby file" do
62
+ file = w("input.rb", ruby_code)
63
+ subject.add("file", file.to_s)
64
+ subject.merge.group.a.must_equal 1
65
+ end
66
+
67
+ it "adds a JSON file" do
68
+ file = w("input.json", json_code)
69
+ subject.add("file", file.to_s)
70
+ subject.merge.group.a.must_equal 1
71
+ end
72
+
73
+ it "adds a YAML file (.yml)" do
74
+ file = w("input.yml", yaml_code)
75
+ subject.add("file", file.to_s)
76
+ subject.merge.group.a.must_equal 1
77
+ end
78
+
79
+ it "adds a YAML file (.yaml)" do
80
+ file = w("input.yaml", yaml_code)
81
+ subject.add("file", file.to_s)
82
+ subject.merge.group.a.must_equal 1
83
+ end
84
+
85
+ it "adds system variables" do
86
+ begin
87
+ subject.add "code", '{ "group": { "a": 0 } }'
88
+ subject.add_system
89
+ ENV['GROUP_A'] = '1'
90
+ subject.merge.group.a.must_equal 1
91
+ ensure
92
+ ENV.delete('GROUP_A')
93
+ end
94
+ end
95
+
96
+ it "adds system variables with a prefix" do
97
+ begin
98
+ subject.add "code", '{ "group": { "a": 0 } }'
99
+ subject.add_system 'PFX_'
100
+ ENV['PFX_GROUP_A'] = '1'
101
+ subject.merge.group.a.must_equal 1
102
+ ensure
103
+ ENV.delete('PFX_GROUP_A')
104
+ end
105
+ end
106
+
107
+ it "adds a Level" do
108
+ level = Levels::Level.new("test")
109
+ level.set_group(:group, a: 1)
110
+
111
+ subject.add_level(level)
112
+ subject.merge.group.a.must_equal 1
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,39 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: write json" do
4
+
5
+ def write_json(level)
6
+ output = Levels::Output::JSON.new
7
+ output.generate(level.to_enum)
8
+ end
9
+
10
+ it "converts to JSON" do
11
+ output = write_json(standard_data_types_level)
12
+ output.must_equal <<-JSON.chomp
13
+ {
14
+ "types": {
15
+ "string": "hello",
16
+ "integer": 123,
17
+ "float": 1.5,
18
+ "boolean_true": true,
19
+ "boolean_false": false,
20
+ "array_of_string": [
21
+ "a",
22
+ "b",
23
+ "c"
24
+ ],
25
+ "array_of_integer": [
26
+ 1,
27
+ 2,
28
+ 3
29
+ ],
30
+ "null": null
31
+ },
32
+ "group2": {
33
+ "message": "hello world"
34
+ }
35
+ }
36
+ JSON
37
+ end
38
+ end
39
+
@@ -0,0 +1,68 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: write system" do
4
+
5
+ def write_system(level, prefix = nil)
6
+ key_formatter = Levels::System::KeyFormatter.new(prefix)
7
+ output = Levels::Output::System.new(key_formatter)
8
+ output.generate(level.to_enum)
9
+ end
10
+
11
+ it "converts to ENV variables" do
12
+ output = write_system(standard_data_types_level)
13
+ output.must_equal <<-ENV.chomp
14
+ export TYPES_STRING="hello"
15
+ export TYPES_STRING_TYPE="string"
16
+ export TYPES_INTEGER="123"
17
+ export TYPES_INTEGER_TYPE="integer"
18
+ export TYPES_FLOAT="1.5"
19
+ export TYPES_FLOAT_TYPE="float"
20
+ export TYPES_BOOLEAN_TRUE="true"
21
+ export TYPES_BOOLEAN_TRUE_TYPE="boolean"
22
+ export TYPES_BOOLEAN_FALSE="false"
23
+ export TYPES_BOOLEAN_FALSE_TYPE="boolean"
24
+ export TYPES_ARRAY_OF_STRING="a:b:c"
25
+ export TYPES_ARRAY_OF_STRING_TYPE="array"
26
+ export TYPES_ARRAY_OF_STRING_DELIMITER=":"
27
+ export TYPES_ARRAY_OF_STRING_TYPE_TYPE="string"
28
+ export TYPES_ARRAY_OF_INTEGER="1:2:3"
29
+ export TYPES_ARRAY_OF_INTEGER_TYPE="array"
30
+ export TYPES_ARRAY_OF_INTEGER_DELIMITER=":"
31
+ export TYPES_ARRAY_OF_INTEGER_TYPE_TYPE="integer"
32
+ export TYPES_NULL=""
33
+ export TYPES_NULL_TYPE="string"
34
+ export GROUP2_MESSAGE="hello world"
35
+ export GROUP2_MESSAGE_TYPE="string"
36
+ ENV
37
+ end
38
+
39
+ it "converts to ENV variables with a prefix" do
40
+ output = write_system(standard_data_types_level, "FOO_")
41
+ output.must_equal <<-ENV.chomp
42
+ export FOO_TYPES_STRING="hello"
43
+ export FOO_TYPES_STRING_TYPE="string"
44
+ export FOO_TYPES_INTEGER="123"
45
+ export FOO_TYPES_INTEGER_TYPE="integer"
46
+ export FOO_TYPES_FLOAT="1.5"
47
+ export FOO_TYPES_FLOAT_TYPE="float"
48
+ export FOO_TYPES_BOOLEAN_TRUE="true"
49
+ export FOO_TYPES_BOOLEAN_TRUE_TYPE="boolean"
50
+ export FOO_TYPES_BOOLEAN_FALSE="false"
51
+ export FOO_TYPES_BOOLEAN_FALSE_TYPE="boolean"
52
+ export FOO_TYPES_ARRAY_OF_STRING="a:b:c"
53
+ export FOO_TYPES_ARRAY_OF_STRING_TYPE="array"
54
+ export FOO_TYPES_ARRAY_OF_STRING_DELIMITER=":"
55
+ export FOO_TYPES_ARRAY_OF_STRING_TYPE_TYPE="string"
56
+ export FOO_TYPES_ARRAY_OF_INTEGER="1:2:3"
57
+ export FOO_TYPES_ARRAY_OF_INTEGER_TYPE="array"
58
+ export FOO_TYPES_ARRAY_OF_INTEGER_DELIMITER=":"
59
+ export FOO_TYPES_ARRAY_OF_INTEGER_TYPE_TYPE="integer"
60
+ export FOO_TYPES_NULL=""
61
+ export FOO_TYPES_NULL_TYPE="string"
62
+ export FOO_GROUP2_MESSAGE="hello world"
63
+ export FOO_GROUP2_MESSAGE_TYPE="string"
64
+ ENV
65
+ end
66
+ end
67
+
68
+
@@ -0,0 +1,33 @@
1
+ require 'helper'
2
+
3
+ describe "acceptance: write yaml" do
4
+
5
+ def write_yaml(level)
6
+ output = Levels::Output::YAML.new
7
+ output.generate(level.to_enum)
8
+ end
9
+
10
+ it "converts to YAML" do
11
+ output = write_yaml(standard_data_types_level)
12
+ output.must_equal <<-JSON.sub(/'null':$/, '\0 ') # Handle trailing space for null.
13
+ ---
14
+ types:
15
+ string: hello
16
+ integer: 123
17
+ float: 1.5
18
+ boolean_true: true
19
+ boolean_false: false
20
+ array_of_string:
21
+ - a
22
+ - b
23
+ - c
24
+ array_of_integer:
25
+ - 1
26
+ - 2
27
+ - 3
28
+ 'null':
29
+ group2:
30
+ message: hello world
31
+ JSON
32
+ end
33
+ end
@@ -0,0 +1,194 @@
1
+ require 'helper'
2
+
3
+ describe "bin: merge" do
4
+
5
+ let(:ruby_syntax) do
6
+ <<-STR
7
+ group :sample
8
+ set message: "hello"
9
+ STR
10
+ end
11
+
12
+ let(:json_syntax) do
13
+ <<-STR
14
+ {
15
+ "sample": {
16
+ "message": "hello"
17
+ }
18
+ }
19
+ STR
20
+ end
21
+
22
+ let(:yaml_syntax) do
23
+ <<-STR
24
+ ---
25
+ sample:
26
+ message: hello
27
+ STR
28
+ end
29
+
30
+ let(:system_syntax) do
31
+ <<-STR
32
+ export SAMPLE_MESSAGE="hello"
33
+ export SAMPLE_MESSAGE_TYPE="string"
34
+ STR
35
+ end
36
+
37
+ let(:system_syntax_with_prefix) do
38
+ <<-STR
39
+ export FOO_SAMPLE_MESSAGE="hello"
40
+ export FOO_SAMPLE_MESSAGE_TYPE="string"
41
+ STR
42
+ end
43
+
44
+ let(:merged_json_syntax) do
45
+ <<-STR
46
+ {
47
+ "sample": {
48
+ "message": "goodbye"
49
+ }
50
+ }
51
+ STR
52
+ end
53
+
54
+ let(:merged_system_keys) do
55
+ {
56
+ "SAMPLE_MESSAGE" => "goodbye",
57
+ "SAMPLE_MESSAGE_TYPE" => "string"
58
+ }
59
+ end
60
+
61
+ let(:merged_system_keys_with_prefix) do
62
+ {
63
+ "FOO_SAMPLE_MESSAGE" => "goodbye",
64
+ "FOO_SAMPLE_MESSAGE_TYPE" => "string"
65
+ }
66
+ end
67
+
68
+ describe "reading files" do
69
+
70
+ it "reads a ruby file" do
71
+ w("one.rb", ruby_syntax)
72
+ assert_success "levels #{f 'one.rb'}"
73
+ stdout.must_equal json_syntax
74
+ end
75
+
76
+ it "reads a json file" do
77
+ w("one.json", json_syntax)
78
+ assert_success "levels #{f 'one.json'}"
79
+ stdout.must_equal json_syntax
80
+ end
81
+
82
+ it "reads a yaml file" do
83
+ w("one.yaml", yaml_syntax)
84
+ assert_success "levels #{f 'one.yaml'}"
85
+ stdout.must_equal json_syntax
86
+ end
87
+
88
+ it "reads a yml file" do
89
+ w("one.yml", yaml_syntax)
90
+ assert_success "levels #{f 'one.yml'}"
91
+ stdout.must_equal json_syntax
92
+ end
93
+
94
+ it "merges files" do
95
+ w("one.rb", ruby_syntax)
96
+ w("one.json", merged_json_syntax)
97
+ assert_success "levels #{f 'one.rb'} #{f 'one.json'}"
98
+ stdout.must_equal merged_json_syntax
99
+ end
100
+ end
101
+
102
+ describe "reading the system" do
103
+
104
+ it "merges with the base" do
105
+ w("one.rb", ruby_syntax)
106
+ set_env merged_system_keys
107
+ assert_success "levels --system #{f 'one.rb'}"
108
+ stdout.must_equal merged_json_syntax
109
+ end
110
+
111
+ it "merges with the base with a prefix" do
112
+ w("one.rb", ruby_syntax)
113
+ set_env merged_system_keys_with_prefix
114
+ assert_success "levels --system FOO_ #{f 'one.rb'}"
115
+ stdout.must_equal merged_json_syntax
116
+ end
117
+ end
118
+
119
+ describe "writing output" do
120
+
121
+ it "writes json" do
122
+ w("one.rb", ruby_syntax)
123
+ assert_success "levels --output json #{f 'one.rb'}"
124
+ stdout.must_equal json_syntax
125
+ end
126
+
127
+ it "writes yaml" do
128
+ w("one.rb", ruby_syntax)
129
+ assert_success "levels --output yaml #{f 'one.rb'}"
130
+ stdout.must_equal yaml_syntax
131
+ end
132
+
133
+ it "writes system" do
134
+ w("one.rb", ruby_syntax)
135
+ assert_success "levels --output system #{f 'one.rb'}"
136
+ stdout.must_equal system_syntax
137
+ end
138
+
139
+ it "writes system with a prefix" do
140
+ w("one.rb", ruby_syntax)
141
+ assert_success "levels --output system --prefix FOO_ #{f 'one.rb'}"
142
+ stdout.must_equal system_syntax_with_prefix
143
+ end
144
+ end
145
+
146
+ describe "logging" do
147
+
148
+ it "logs each file read" do
149
+ w("one.rb", ruby_syntax)
150
+ w("one.json", json_syntax)
151
+ assert_success "levels --no-output #{f 'one.rb'} #{f 'one.json'}"
152
+ stderr.must_equal <<-STR
153
+ Add level "one.rb" from one.rb
154
+ Add level "one.json" from one.json
155
+ STR
156
+ stdout.must_equal ""
157
+ end
158
+
159
+ it "logs when the files are given level names" do
160
+ w("one.rb", ruby_syntax)
161
+ w("two.rb", ruby_syntax)
162
+ w("one.json", json_syntax)
163
+ w("three.rb", ruby_syntax)
164
+ assert_success "levels --no-output --level 'RB one' --level --level 'JSON one' #{f 'one.rb'} #{f 'two.rb'} #{f 'one.json'} #{f 'three.rb'}"
165
+ stderr.must_equal <<-STR
166
+ Add level "RB one" from one.rb
167
+ Add level "two.rb" from two.rb
168
+ Add level "JSON one" from one.json
169
+ Add level "three.rb" from three.rb
170
+ STR
171
+ stdout.must_equal ""
172
+ end
173
+
174
+ it "logs when the system is used" do
175
+ w("one.rb", ruby_syntax)
176
+ assert_success "levels --no-output --system --level 'First Level' #{f 'one.rb'}"
177
+ stderr.must_equal <<-STR
178
+ Add level "First Level" from one.rb
179
+ Add level "System Environment"
180
+ STR
181
+ stdout.must_equal ""
182
+ end
183
+
184
+ it "logs when the system is used with a prefix" do
185
+ w("one.rb", ruby_syntax)
186
+ assert_success "levels --no-output --system FOO_ --level 'First Level' #{f 'one.rb'}"
187
+ stderr.must_equal <<-STR
188
+ Add level "First Level" from one.rb
189
+ Add level "System Environment" with prefix FOO_
190
+ STR
191
+ stdout.must_equal ""
192
+ end
193
+ end
194
+ end