levels 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,32 @@
1
+ require 'helper'
2
+
3
+ describe Levels::Output::System do
4
+
5
+ let(:data) {
6
+ {
7
+ group1: {
8
+ key: "hello",
9
+ },
10
+ group2: {
11
+ key: "world"
12
+ }
13
+ }
14
+ }
15
+
16
+ subject { Levels::Output::System.new }
17
+
18
+ def result
19
+ subject.generate(data.to_enum)
20
+ end
21
+
22
+ it "converts to environment vars" do
23
+ result.must_equal <<-STR.chomp
24
+ export GROUP1_KEY="hello"
25
+ export GROUP1_KEY_TYPE="string"
26
+ export GROUP2_KEY="world"
27
+ export GROUP2_KEY_TYPE="string"
28
+ STR
29
+ end
30
+ end
31
+
32
+
@@ -0,0 +1,38 @@
1
+ require 'helper'
2
+
3
+ describe Levels::Output::YAML do
4
+
5
+ let(:data) {
6
+ {
7
+ group1: {
8
+ key1: "string",
9
+ key2: 123
10
+ },
11
+ group2: {
12
+ key: [1, 2, 3]
13
+ }
14
+ }
15
+ }
16
+
17
+ subject { Levels::Output::YAML.new }
18
+
19
+ def result
20
+ subject.generate(data.to_enum)
21
+ end
22
+
23
+ it "converts to YAML" do
24
+ result.must_equal <<-STR
25
+ ---
26
+ group1:
27
+ key1: string
28
+ key2: 123
29
+ group2:
30
+ key:
31
+ - 1
32
+ - 2
33
+ - 3
34
+ STR
35
+ end
36
+ end
37
+
38
+
@@ -0,0 +1,40 @@
1
+ require 'helper'
2
+ require 'tempfile'
3
+
4
+ describe Levels::Runtime do
5
+
6
+ let(:klass) {
7
+ Class.new do
8
+ include Levels::Runtime
9
+ end
10
+ }
11
+
12
+ subject { klass.new }
13
+
14
+ describe "#file" do
15
+
16
+ # NOTE: This test uses an absolute path. The test
17
+ # for relative path interpretation is in
18
+ # acceptance/read_ruby_test.rb
19
+ it "returns a proc that reads a file" do
20
+ f = Tempfile.new("f")
21
+ begin
22
+ f.print "hello"
23
+ f.close
24
+ proc = subject.file(f.path)
25
+ proc.call.must_equal "hello"
26
+ ensure
27
+ f.close!
28
+ end
29
+ end
30
+
31
+ it "raises an error from the proc when given a path that doesn't exist" do
32
+ proc = subject.file("/no/file/here")
33
+ -> { proc.call }.must_raise(Levels::Runtime::FileNotFoundError)
34
+ end
35
+
36
+ it "returns nil if given nil" do
37
+ subject.file(nil).must_equal nil
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,43 @@
1
+ require 'helper'
2
+
3
+ describe Levels::System::KeyFormatter do
4
+
5
+ let(:prefix) { nil }
6
+ let(:joiner) { nil }
7
+
8
+ subject { Levels::System::KeyFormatter.new(prefix, joiner) }
9
+
10
+ describe "without a prefix" do
11
+
12
+ it "creates a key" do
13
+ subject.create(:a, "b", "C").must_equal "A_B_C"
14
+ end
15
+ end
16
+
17
+ describe "with a prefix" do
18
+
19
+ let(:prefix) { "PREFIX_" }
20
+
21
+ it "creates a key" do
22
+ subject.create(:a, "b", "C").must_equal "PREFIX_A_B_C"
23
+ end
24
+ end
25
+
26
+ describe "with a custom joiner" do
27
+
28
+ let(:joiner) { "-" }
29
+
30
+ it "changes the joiner" do
31
+ subject.create(:a, "b", "C").must_equal "A-B-C"
32
+ end
33
+
34
+ describe "with a prefix" do
35
+
36
+ let(:prefix) { "PREFIX_" }
37
+
38
+ it "does not affect the prefix" do
39
+ subject.create(:a, "b", "C").must_equal "PREFIX_A-B-C"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ require 'helper'
2
+
3
+ describe Levels::System::KeyGenerator do
4
+
5
+ subject { Levels::System::KeyGenerator.new }
6
+
7
+ it "generates key/values for the data and typecasting" do
8
+ enum = [
9
+ [:group, :key1, "string"],
10
+ [:group, :key2, 123]
11
+ ].to_enum
12
+ keys = subject.generate(enum)
13
+ keys.must_equal(
14
+ "GROUP_KEY1" => "string",
15
+ "GROUP_KEY1_TYPE" => "string",
16
+ "GROUP_KEY2" => "123",
17
+ "GROUP_KEY2_TYPE" => "integer"
18
+ )
19
+ end
20
+ end
21
+
@@ -0,0 +1,207 @@
1
+ require 'helper'
2
+
3
+ describe Levels::System::KeyParser do
4
+
5
+ subject { Levels::System::KeyParser.new }
6
+
7
+ describe "basic parsing rules" do
8
+
9
+ it "returns nil if the value is empty" do
10
+ env = {
11
+ "K" => ""
12
+ }
13
+ value = subject.parse(env, "K", "template is string")
14
+ value.must_equal nil
15
+ end
16
+
17
+ it "returns a value based on typecast info if the template value is nil" do
18
+ env = {
19
+ "K" => "123",
20
+ "K_TYPE" => "integer"
21
+ }
22
+ value = subject.parse(env, "K", nil)
23
+ value.must_equal 123
24
+ end
25
+
26
+ it "returns a value based on the template if no typecast info is available" do
27
+ env = {
28
+ "K" => "123"
29
+ }
30
+ value = subject.parse(env, "K", 999)
31
+ value.must_equal 123
32
+ end
33
+
34
+ it "returns a value based on typecast info if both template and typecast info exist" do
35
+ env = {
36
+ "K" => "123",
37
+ "K_TYPE" => "integer"
38
+ }
39
+ value = subject.parse(env, "K", "template is a string")
40
+ value.must_equal 123
41
+ end
42
+
43
+ it "returns a string if neither typecast or template are available" do
44
+ env = {
45
+ "K" => "123"
46
+ }
47
+ value = subject.parse(env, "K", nil)
48
+ value.must_equal "123"
49
+ end
50
+ end
51
+
52
+ describe "parsing simple types" do
53
+
54
+ describe "from typecast info" do
55
+
56
+ specify "string" do
57
+ env = {
58
+ "K" => "hello",
59
+ "K_TYPE" => "string"
60
+ }
61
+ subject.parse(env, "K", nil).must_equal "hello"
62
+ end
63
+
64
+ specify "integer" do
65
+ env = {
66
+ "K" => "123",
67
+ "K_TYPE" => "integer"
68
+ }
69
+ subject.parse(env, "K", nil).must_equal 123
70
+ end
71
+
72
+ specify "float" do
73
+ env = {
74
+ "K" => "1.5",
75
+ "K_TYPE" => "float"
76
+ }
77
+ subject.parse(env, "K", nil).must_equal 1.5
78
+ end
79
+
80
+ specify "boolean" do
81
+ env = {
82
+ "T" => "true",
83
+ "T_TYPE" => "boolean",
84
+ "O" => "1",
85
+ "O_TYPE" => "boolean",
86
+ "F" => "false",
87
+ "F_TYPE" => "boolean",
88
+ "X" => "blah",
89
+ "X_TYPE" => "boolean"
90
+ }
91
+ subject.parse(env, "T", nil).must_equal true
92
+ subject.parse(env, "O", nil).must_equal true
93
+ subject.parse(env, "F", nil).must_equal false
94
+ subject.parse(env, "X", nil).must_equal false
95
+ end
96
+
97
+ specify "an unknown type" do
98
+ env = {
99
+ "K" => "hello",
100
+ "K_TYPE" => "other"
101
+ }
102
+ -> { subject.parse(env, "K", nil) }.must_raise(ArgumentError)
103
+ end
104
+ end
105
+
106
+ describe "from the template value" do
107
+
108
+ specify "string" do
109
+ env = {
110
+ "K" => "hello"
111
+ }
112
+ subject.parse(env, "K", "str").must_equal "hello"
113
+ end
114
+
115
+ specify "integer" do
116
+ env = {
117
+ "K" => "123"
118
+ }
119
+ subject.parse(env, "K", 999).must_equal 123
120
+ end
121
+
122
+ specify "float" do
123
+ env = {
124
+ "K" => "1.5"
125
+ }
126
+ subject.parse(env, "K", 1.0).must_equal 1.5
127
+ end
128
+
129
+ specify "boolean" do
130
+ env = {
131
+ "T" => "true",
132
+ "O" => "1",
133
+ "F" => "false",
134
+ "X" => "blah"
135
+ }
136
+ subject.parse(env, "T", false).must_equal true
137
+ subject.parse(env, "O", false).must_equal true
138
+ subject.parse(env, "F", true).must_equal false
139
+ subject.parse(env, "X", true).must_equal false
140
+ end
141
+
142
+ specify "an unknown type" do
143
+ env = {
144
+ "K" => "hello"
145
+ }
146
+ -> { subject.parse(env, "K", Object.new) }.must_raise(ArgumentError)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe "parsing an array" do
152
+
153
+ describe "from typecast info" do
154
+
155
+ it "parses from the array" do
156
+ env = {
157
+ "K" => "a:b:c",
158
+ "K_TYPE" => "array"
159
+ }
160
+ subject.parse(env, "K", nil).must_equal ["a", "b", "c"]
161
+ end
162
+
163
+ it "parses the array values" do
164
+ env = {
165
+ "K" => "1:2:3",
166
+ "K_TYPE" => "array",
167
+ "K_TYPE_TYPE" => "integer"
168
+ }
169
+ subject.parse(env, "K", nil).must_equal [1, 2, 3]
170
+ end
171
+ end
172
+
173
+ describe "from the template value" do
174
+
175
+ it "it parses the array" do
176
+ env = {
177
+ "K" => "a:b:c"
178
+ }
179
+ subject.parse(env, "K", []).must_equal ["a", "b", "c"]
180
+ end
181
+
182
+ it "parses the array values" do
183
+ env = {
184
+ "K" => "1:2:3"
185
+ }
186
+ subject.parse(env, "K", [1]).must_equal [1, 2, 3]
187
+ end
188
+
189
+ it "parses the array values from typecast info" do
190
+ env = {
191
+ "K" => "1:2:3",
192
+ "K_TYPE_TYPE" => "integer"
193
+ }
194
+ subject.parse(env, "K", []).must_equal [1, 2, 3]
195
+ subject.parse(env, "K", ["string"]).must_equal [1, 2, 3]
196
+ end
197
+ end
198
+
199
+ it "uses another delimiter" do
200
+ env = {
201
+ "K" => "a,b,c",
202
+ "K_DELIMITER" => ","
203
+ }
204
+ subject.parse(env, "K", []).must_equal ["a", "b", "c"]
205
+ end
206
+ end
207
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: levels
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryan Carver
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: minitest
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '4.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '4.0'
46
+ description: A tool for reading and writing configuration data.
47
+ email:
48
+ - ryan@ryancarver.com
49
+ executables:
50
+ - levels
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .rbenv-version
56
+ - CHANGELOG.md
57
+ - Gemfile
58
+ - Guardfile
59
+ - LICENSE
60
+ - README.md
61
+ - Rakefile
62
+ - bin/levels
63
+ - examples/01_base.rb
64
+ - examples/01_merge_to_json.sh
65
+ - examples/01_prod.json
66
+ - examples/02_base.rb
67
+ - examples/02_merge_with_file.sh
68
+ - examples/02_value
69
+ - levels.gemspec
70
+ - lib/levels.rb
71
+ - lib/levels/audit.rb
72
+ - lib/levels/audit/group_observer.rb
73
+ - lib/levels/audit/nested_group_observer.rb
74
+ - lib/levels/audit/root_observer.rb
75
+ - lib/levels/audit/value.rb
76
+ - lib/levels/audit/value_observer.rb
77
+ - lib/levels/audit/values.rb
78
+ - lib/levels/configuration.rb
79
+ - lib/levels/configured_group.rb
80
+ - lib/levels/event_handler.rb
81
+ - lib/levels/group.rb
82
+ - lib/levels/input/json.rb
83
+ - lib/levels/input/ruby.rb
84
+ - lib/levels/input/system.rb
85
+ - lib/levels/input/yaml.rb
86
+ - lib/levels/key.rb
87
+ - lib/levels/key_values.rb
88
+ - lib/levels/lazy_evaluator.rb
89
+ - lib/levels/level.rb
90
+ - lib/levels/method_missing.rb
91
+ - lib/levels/output/json.rb
92
+ - lib/levels/output/system.rb
93
+ - lib/levels/output/yaml.rb
94
+ - lib/levels/runtime.rb
95
+ - lib/levels/setup.rb
96
+ - lib/levels/system/constants.rb
97
+ - lib/levels/system/key_formatter.rb
98
+ - lib/levels/system/key_generator.rb
99
+ - lib/levels/system/key_parser.rb
100
+ - lib/levels/version.rb
101
+ - test/acceptance/audit_test.rb
102
+ - test/acceptance/event_handler_test.rb
103
+ - test/acceptance/read_json_test.rb
104
+ - test/acceptance/read_ruby_test.rb
105
+ - test/acceptance/read_system_test.rb
106
+ - test/acceptance/read_yaml_test.rb
107
+ - test/acceptance/setup_test.rb
108
+ - test/acceptance/write_json_test.rb
109
+ - test/acceptance/write_system_test.rb
110
+ - test/acceptance/write_yaml_test.rb
111
+ - test/bin/merge_test.rb
112
+ - test/bin/options_test.rb
113
+ - test/helper.rb
114
+ - test/support/acceptance_spec.rb
115
+ - test/support/base_spec.rb
116
+ - test/support/bin_spec.rb
117
+ - test/support/tempfile_helper.rb
118
+ - test/unit/audit/group_observer_test.rb
119
+ - test/unit/audit/nested_group_observer_test.rb
120
+ - test/unit/audit/root_observer_test.rb
121
+ - test/unit/audit/value_observer_test.rb
122
+ - test/unit/audit/value_test.rb
123
+ - test/unit/audit/values_test.rb
124
+ - test/unit/configuration_test.rb
125
+ - test/unit/configured_group_test.rb
126
+ - test/unit/group_test.rb
127
+ - test/unit/input/json_test.rb
128
+ - test/unit/input/ruby_test.rb
129
+ - test/unit/input/system_test.rb
130
+ - test/unit/input/yaml_test.rb
131
+ - test/unit/key_test.rb
132
+ - test/unit/key_values_test.rb
133
+ - test/unit/lazy_evaluator_test.rb
134
+ - test/unit/level_test.rb
135
+ - test/unit/levels_test.rb
136
+ - test/unit/output/json_test.rb
137
+ - test/unit/output/system_test.rb
138
+ - test/unit/output/yaml_test.rb
139
+ - test/unit/runtime_test.rb
140
+ - test/unit/system/key_formatter_test.rb
141
+ - test/unit/system/key_generator_test.rb
142
+ - test/unit/system/key_parser_test.rb
143
+ homepage: https://github.com/rcarver/levels
144
+ licenses: []
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ none: false
151
+ requirements:
152
+ - - ! '>='
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ segments:
156
+ - 0
157
+ hash: 352126220844248083
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ segments:
165
+ - 0
166
+ hash: 352126220844248083
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 1.8.23
170
+ signing_key:
171
+ specification_version: 3
172
+ summary: A tool for reading and writing configuration data.
173
+ test_files:
174
+ - test/acceptance/audit_test.rb
175
+ - test/acceptance/event_handler_test.rb
176
+ - test/acceptance/read_json_test.rb
177
+ - test/acceptance/read_ruby_test.rb
178
+ - test/acceptance/read_system_test.rb
179
+ - test/acceptance/read_yaml_test.rb
180
+ - test/acceptance/setup_test.rb
181
+ - test/acceptance/write_json_test.rb
182
+ - test/acceptance/write_system_test.rb
183
+ - test/acceptance/write_yaml_test.rb
184
+ - test/bin/merge_test.rb
185
+ - test/bin/options_test.rb
186
+ - test/helper.rb
187
+ - test/support/acceptance_spec.rb
188
+ - test/support/base_spec.rb
189
+ - test/support/bin_spec.rb
190
+ - test/support/tempfile_helper.rb
191
+ - test/unit/audit/group_observer_test.rb
192
+ - test/unit/audit/nested_group_observer_test.rb
193
+ - test/unit/audit/root_observer_test.rb
194
+ - test/unit/audit/value_observer_test.rb
195
+ - test/unit/audit/value_test.rb
196
+ - test/unit/audit/values_test.rb
197
+ - test/unit/configuration_test.rb
198
+ - test/unit/configured_group_test.rb
199
+ - test/unit/group_test.rb
200
+ - test/unit/input/json_test.rb
201
+ - test/unit/input/ruby_test.rb
202
+ - test/unit/input/system_test.rb
203
+ - test/unit/input/yaml_test.rb
204
+ - test/unit/key_test.rb
205
+ - test/unit/key_values_test.rb
206
+ - test/unit/lazy_evaluator_test.rb
207
+ - test/unit/level_test.rb
208
+ - test/unit/levels_test.rb
209
+ - test/unit/output/json_test.rb
210
+ - test/unit/output/system_test.rb
211
+ - test/unit/output/yaml_test.rb
212
+ - test/unit/runtime_test.rb
213
+ - test/unit/system/key_formatter_test.rb
214
+ - test/unit/system/key_generator_test.rb
215
+ - test/unit/system/key_parser_test.rb