key_value_name 0.0.1 → 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.
@@ -5,9 +5,10 @@ module KeyValueName
5
5
  # Specify the keys and value types for a KeyValueName.
6
6
  #
7
7
  class Spec
8
- def initialize(marshalers, extension)
8
+ def initialize(marshalers, prefix = nil, suffix = nil)
9
9
  @marshalers = marshalers
10
- @extension = extension
10
+ @prefix = prefix
11
+ @suffix = suffix
11
12
  @matcher = build_matcher
12
13
 
13
14
  marshalers.freeze
@@ -15,38 +16,58 @@ module KeyValueName
15
16
  end
16
17
 
17
18
  attr_reader :marshalers
18
- attr_reader :extension
19
+ attr_reader :prefix
20
+ attr_reader :suffix
19
21
  attr_reader :matcher
20
22
 
21
- def matches?(string)
22
- string =~ matcher
23
+ def matches?(basename)
24
+ basename =~ matcher
23
25
  end
24
26
 
25
- def read(string)
26
- raise ArgumentError, "bad filename: #{string}" unless string =~ matcher
27
+ def glob
28
+ if marshalers.any?
29
+ "#{prefix}*#{suffix}"
30
+ else
31
+ "#{prefix}#{suffix}"
32
+ end
33
+ end
34
+
35
+ def parse(basename)
36
+ raise ArgumentError, "bad name: #{basename}" unless matcher =~ basename
27
37
  Hash[marshalers.map.with_index do |(key, marshaler), index|
28
- [key, marshaler.read(Regexp.last_match(index + 1))]
38
+ [key, marshaler.parse(Regexp.last_match(index + 1))]
29
39
  end]
30
40
  end
31
41
 
32
- def write(name)
33
- string = name.each_pair.map do |key, value|
34
- value_string = marshalers[key].write(value)
42
+ def generate(struct)
43
+ body = struct.each_pair.map do |key, value|
44
+ value_string = marshalers[key].generate(value)
35
45
  "#{key}#{KEY_VALUE_SEPARATOR}#{value_string}"
36
46
  end.join(PAIR_SEPARATOR)
37
- string += ".#{extension}" unless extension.nil?
38
- string
47
+ "#{prefix}#{body}#{suffix}"
48
+ end
49
+
50
+ def compare(a, b)
51
+ return 0 if a.nil? && b.nil?
52
+ return nil if a.nil? || b.nil?
53
+ a.each_pair do |key, value|
54
+ marshaler = marshalers[key]
55
+ a_comparable = marshaler.to_comparable(value)
56
+ b_comparable = marshaler.to_comparable(b[key])
57
+ signum = a_comparable <=> b_comparable
58
+ return signum if signum != 0
59
+ end
60
+ 0
39
61
  end
40
62
 
41
- private
63
+ protected
42
64
 
43
65
  def build_matcher
44
66
  pair_rxs = marshalers.map do |name, marshaler|
45
67
  /#{name}#{KEY_VALUE_SEPARATOR}(#{marshaler.matcher})/
46
68
  end
47
- pairs_matcher = pair_rxs.map(&:to_s).join(PAIR_SEPARATOR_RX.to_s)
48
- extension_matcher = extension.nil? ? '' : /[.]#{extension}/.to_s
49
- Regexp.new('\A' + pairs_matcher + extension_matcher + '\z')
69
+ body = pair_rxs.map(&:to_s).join(PAIR_SEPARATOR_RX.to_s)
70
+ Regexp.new("\\A#{prefix}#{body}#{suffix}\\z")
50
71
  end
51
72
  end
52
73
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module KeyValueName
4
4
  VERSION_MAJOR = 0
5
- VERSION_MINOR = 0
6
- VERSION_PATCH = 1
5
+ VERSION_MINOR = 1
6
+ VERSION_PATCH = 0
7
7
  VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH].join('.')
8
8
  end
@@ -9,18 +9,38 @@ module KeyValueName
9
9
  PAIR_SEPARATOR = '.'
10
10
  PAIR_SEPARATOR_RX = /[.]/
11
11
 
12
+ def self.camelize(name)
13
+ name.to_s.gsub(/(?:\A|_)(.)/) { Regexp.last_match(1).upcase }
14
+ end
15
+
12
16
  def self.check_symbol(name)
13
- raise ArgumentError, "bad symbol: #{name}" unless name =~ /\A#{KEY_RX}\z/
17
+ raise ArgumentError, "bad symbol: #{name}" unless
18
+ name.match?(/\A#{KEY_RX}\z/)
19
+ raise ArgumentError, "reserved symbol: #{name}" if
20
+ %i[parent].member?(name)
21
+ end
22
+
23
+ def self.new(name = nil, &block)
24
+ raise unless block_given?
25
+ FileBuilder.new(name, &block).build
14
26
  end
15
27
 
16
- def self.new
17
- builder = Builder.new
18
- yield builder
19
- builder.build
28
+ def self.schema(&block)
29
+ raise unless block_given?
30
+ SchemaBuilder.new(&block).build
20
31
  end
21
32
  end
22
33
 
23
34
  require_relative 'key_value_name/version'
24
35
  require_relative 'key_value_name/marshalers'
36
+ require_relative 'key_value_name/schema'
37
+ require_relative 'key_value_name/collection'
38
+ require_relative 'key_value_name/mixins/name'
39
+ require_relative 'key_value_name/mixins/file_name'
40
+ require_relative 'key_value_name/mixins/folder_name'
25
41
  require_relative 'key_value_name/spec'
26
- require_relative 'key_value_name/builder'
42
+ require_relative 'key_value_name/builders/key_value_builder'
43
+ require_relative 'key_value_name/builders/container_builder'
44
+ require_relative 'key_value_name/builders/schema_builder'
45
+ require_relative 'key_value_name/builders/file_builder'
46
+ require_relative 'key_value_name/builders/folder_builder'
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+
5
+ require 'key_value_name'
6
+
7
+ class TestExtension < Minitest::Test
8
+ ExtensionSchema = KeyValueName.schema do
9
+ file :foo
10
+
11
+ file :foo, :tar
12
+
13
+ file :foo, :tar, :gz
14
+
15
+ file :bar, :tar do
16
+ key :a, type: Integer
17
+ end
18
+
19
+ file :bar, :tar, :gz do
20
+ key :a, type: Integer
21
+ end
22
+ end
23
+
24
+ def test_extensions
25
+ Dir.mktmpdir do |tmp|
26
+ schema = ExtensionSchema.new(root: tmp)
27
+
28
+ foo = schema.foo
29
+ assert_equal File.join(tmp, 'foo'), foo.to_s
30
+ assert_match(/ExtensionSchema::Foo\z/, foo.class.to_s)
31
+
32
+ foo_tar = schema.foo_tar
33
+ assert_equal File.join(tmp, 'foo.tar'), foo_tar.to_s
34
+ assert_match(/ExtensionSchema::FooTar\z/, foo_tar.class.to_s)
35
+
36
+ foo_tar_gz = schema.foo_tar_gz
37
+ assert_equal File.join(tmp, 'foo.tar.gz'), foo_tar_gz.to_s
38
+ assert_match(/ExtensionSchema::FooTarGz\z/, foo_tar_gz.class.to_s)
39
+
40
+ bar_tar = schema.bar_tar.new(a: 1)
41
+ assert_equal File.join(tmp, 'bar-a-1.tar'), bar_tar.to_s
42
+ assert_match(/ExtensionSchema::BarTar\z/, bar_tar.class.to_s)
43
+
44
+ bar_tar_gz = schema.bar_tar_gz.new(a: 1)
45
+ assert_equal File.join(tmp, 'bar-a-1.tar.gz'), bar_tar_gz.to_s
46
+ assert_match(/ExtensionSchema::BarTarGz\z/, bar_tar_gz.class.to_s)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+
5
+ require 'key_value_name'
6
+
7
+ class TestFileBuilder < Minitest::Test
8
+ OneFolderSetSchema = KeyValueName.schema do
9
+ file :foo do
10
+ key :a, type: Integer
11
+ end
12
+ end
13
+
14
+ OneFolderSetOneFileSchema = KeyValueName.schema do
15
+ folder :foo do
16
+ key :a, type: Integer
17
+ file :bar
18
+ end
19
+ end
20
+
21
+ def test_one_folder_set_schema
22
+ Dir.mktmpdir do |tmp|
23
+ schema = OneFolderSetSchema.new(root: tmp)
24
+ assert_equal [], schema.foo.all
25
+
26
+ foos = Array.new(3) do |i|
27
+ schema.foo.new(a: i).touch!
28
+ end
29
+
30
+ assert_equal [foos[1]], schema.foo.where(a: 1)
31
+ assert_equal foos[1], schema.foo.find_by(a: 1)
32
+ end
33
+ end
34
+
35
+ def test_file_destroy!
36
+ Dir.mktmpdir do |tmp|
37
+ schema = OneFolderSetOneFileSchema.new(root: tmp)
38
+
39
+ # Should suceed even if parent directory does not exist.
40
+ foo = schema.foo.new(a: 1)
41
+ assert !foo.exist?
42
+ foo.bar.destroy!
43
+ assert !foo.bar.exist?
44
+
45
+ foo.bar.touch!
46
+ assert foo.bar.exist?
47
+ foo.bar.destroy!
48
+ assert !foo.bar.exist?
49
+ end
50
+ end
51
+
52
+ def test_file_mkdir!
53
+ Dir.mktmpdir do |tmp|
54
+ schema = OneFolderSetOneFileSchema.new(root: tmp)
55
+
56
+ foo = schema.foo.new(a: 1)
57
+ bar = foo.bar.mkdir!
58
+ assert_equal File.join(foo.to_s, 'bar'), bar.to_s
59
+ assert_equal [foo], schema.foo.all
60
+ assert foo.exist?
61
+ assert !bar.exist?
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+
5
+ require 'key_value_name'
6
+
7
+ class TestFolderBuilder < Minitest::Test
8
+ OneFolderSetSchema = KeyValueName.schema do
9
+ folder :foo do
10
+ key :a, type: Integer
11
+ end
12
+ end
13
+
14
+ def test_one_folder_set_schema
15
+ Dir.mktmpdir do |tmp|
16
+ schema = OneFolderSetSchema.new(root: tmp)
17
+ assert_equal [], schema.foo.all
18
+
19
+ foos = Array.new(3) do |i|
20
+ schema.foo.new(a: i).mkdir!
21
+ end
22
+
23
+ assert_equal [foos[1]], schema.foo.where(a: 1)
24
+ assert_equal foos[1], schema.foo.find_by(a: 1)
25
+ end
26
+ end
27
+ end
@@ -6,54 +6,58 @@ require 'tmpdir'
6
6
 
7
7
  require 'key_value_name'
8
8
 
9
- class TestKeyValueName < MiniTest::Test
10
- TestInteger = KeyValueName.new do |n|
11
- n.key :a, type: Numeric, format: '%d'
9
+ class TestKeyValueName < Minitest::Test
10
+ TestInteger = KeyValueName.new do
11
+ key :a, type: Integer, format: '%d'
12
12
  end
13
13
 
14
- TestHexNumeric = KeyValueName.new do |n|
15
- n.key :b, type: Numeric, format: '%x'
14
+ TestHexNumeric = KeyValueName.new do
15
+ key :b, type: Integer, format: '%x'
16
16
  end
17
17
 
18
- TestFormattedNumeric = KeyValueName.new do |n|
19
- n.key :c, type: Numeric, format: '%.3f', scan_format: '%f'
18
+ TestFormattedNumeric = KeyValueName.new do
19
+ key :c, type: Float, format: '%.3f'
20
20
  end
21
21
 
22
- TestPaddedNumeric = KeyValueName.new do |n|
23
- n.key :d, type: Numeric, format: '%04d'
22
+ TestPaddedNumeric = KeyValueName.new do
23
+ key :d, type: Integer, format: '%04d'
24
24
  end
25
25
 
26
- TestSymbol = KeyValueName.new do |n|
27
- n.key :a, type: Symbol
26
+ TestSymbol = KeyValueName.new do
27
+ key :a, type: Symbol
28
28
  end
29
29
 
30
- TestFloat = KeyValueName.new do |n|
31
- n.key :a, type: Numeric
30
+ TestFloat = KeyValueName.new do
31
+ key :a, type: Float
32
32
  end
33
33
 
34
- TestTwoIntegers = KeyValueName.new do |n|
35
- n.include_keys TestInteger
36
- n.include_keys TestHexNumeric
34
+ TestTwoIntegers = KeyValueName.new do
35
+ include_keys TestInteger
36
+ include_keys TestHexNumeric
37
37
  end
38
38
 
39
- TestMixed = KeyValueName.new do |n|
40
- n.key :id, type: Symbol
41
- n.key :ordinal, type: Numeric, format: '%d'
42
- n.key :value, type: Numeric
39
+ TestMixed = KeyValueName.new do
40
+ key :id, type: Symbol
41
+ key :ordinal, type: Integer
42
+ key :value, type: Float
43
43
  end
44
44
 
45
- TestExtension = KeyValueName.new do |n|
46
- n.key :big_number, type: Numeric, format: '%04d'
47
- n.extension 'bin'
45
+ TestExtension = KeyValueName.new do
46
+ key :big_number, type: Integer, format: '%04d'
47
+ extension 'bin'
48
48
  end
49
49
 
50
- TestEKey = KeyValueName.new do |n|
51
- n.key :x, type: Numeric
52
- n.key :e, type: Numeric
50
+ TestEKey = KeyValueName.new do
51
+ key :x, type: Float
52
+ key :e, type: Float
53
+ end
54
+
55
+ TestBoolean = KeyValueName.new do
56
+ key :a, type: :boolean
53
57
  end
54
58
 
55
59
  def roundtrip(klass, string, args)
56
- name = klass.read(string)
60
+ name = klass.parse(string)
57
61
  assert_equal args.keys, name.to_h.keys
58
62
  args.each do |key, value|
59
63
  assert_equal value, name[key]
@@ -76,7 +80,7 @@ class TestKeyValueName < MiniTest::Test
76
80
  end
77
81
 
78
82
  def test_formatted_numeric_parse
79
- assert_equal(-0.0013, TestFormattedNumeric.read('c--1.3e-3').c)
83
+ assert_equal(-0.0013, TestFormattedNumeric.parse('c--1.3e-3').c)
80
84
  end
81
85
 
82
86
  def test_padded_numeric_roundtrip
@@ -95,6 +99,13 @@ class TestKeyValueName < MiniTest::Test
95
99
  roundtrip(TestFloat, 'a-2.25', a: 2.25)
96
100
  end
97
101
 
102
+ def test_exponent_float_roundtrip
103
+ roundtrip(TestFloat, 'a-1e+06', a: 1e6)
104
+ roundtrip(TestFloat, 'a--1e+06', a: -1e6)
105
+ roundtrip(TestFloat, 'a-1e-06', a: 1e-6)
106
+ roundtrip(TestFloat, 'a--1e-06', a: -1e-6)
107
+ end
108
+
98
109
  def test_two_integers_roundtrip
99
110
  roundtrip(TestTwoIntegers, 'a-123.b-ff', a: 123, b: 255)
100
111
  end
@@ -121,27 +132,39 @@ class TestKeyValueName < MiniTest::Test
121
132
  roundtrip(TestEKey, 'x-1.e-2', x: 1, e: 2)
122
133
  end
123
134
 
135
+ def test_boolean_roundtrip
136
+ roundtrip(TestBoolean, 'a-true', a: true)
137
+ roundtrip(TestBoolean, 'a-false', a: false)
138
+ end
139
+
124
140
  def test_missing_key
125
141
  assert_raises do
126
142
  TestInteger.new(b: 3)
127
143
  end
128
144
  assert_raises(ArgumentError) do
129
- TestInteger.read('b-3')
145
+ TestInteger.parse('b-3')
130
146
  end
131
147
  end
132
148
 
133
- def test_in_folder
134
- assert_equal File.join('foo', 'a-1'), TestInteger.new(a: 1).in('foo')
135
- end
136
-
137
149
  def test_glob_with_integers
138
150
  Dir.mktmpdir do |tmp|
139
- FileUtils.touch TestInteger.new(a: 1).in(tmp)
140
- FileUtils.touch TestInteger.new(a: 2).in(tmp)
151
+ FileUtils.touch File.join(tmp, TestInteger.new(a: 1).to_s)
152
+ FileUtils.touch File.join(tmp, TestInteger.new(a: 2).to_s)
141
153
  names = TestInteger.glob(tmp).sort_by(&:a)
142
154
  assert_equal 2, names.size
143
155
  assert_equal 1, names[0].a
144
156
  assert_equal 2, names[1].a
145
157
  end
146
158
  end
159
+
160
+ def test_sortable
161
+ names = [TestInteger.new(a: 2), TestInteger.new(a: 1)]
162
+ assert_equal [1, 2], names.sort.map(&:a)
163
+
164
+ names = [TestInteger.new(a: 1), TestInteger.new(a: 1)]
165
+ assert_equal [1, 1], names.sort.map(&:a)
166
+
167
+ names = [TestBoolean.new(a: true), TestBoolean.new(a: false)]
168
+ assert_equal [false, true], names.sort.map(&:a)
169
+ end
147
170
  end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest/autorun'
4
+ require 'tmpdir'
5
+
6
+ require 'key_value_name'
7
+
8
+ class TestSchema < Minitest::Test
9
+ OneFileSchema = KeyValueName.schema do
10
+ file :foo
11
+ end
12
+
13
+ OneFileSetSchema = KeyValueName.schema do
14
+ file :foo do
15
+ key :a, type: Integer
16
+ end
17
+ end
18
+
19
+ OneFolderSchema = KeyValueName.schema do
20
+ folder :foo
21
+ end
22
+
23
+ OneFolderSetSchema = KeyValueName.schema do
24
+ folder :foo do
25
+ key :a, type: Integer
26
+ end
27
+ end
28
+
29
+ OneFolderSetOneFileSchema = KeyValueName.schema do
30
+ folder :foo do
31
+ key :a, type: Integer
32
+ file :bar
33
+ end
34
+ end
35
+
36
+ OneFolderSetOneFolderSchema = KeyValueName.schema do
37
+ folder :foo do
38
+ key :a, type: Integer
39
+ folder :bar
40
+ end
41
+ end
42
+
43
+ OneFolderSetOneFolderSetSchema = KeyValueName.schema do
44
+ folder :foo do
45
+ key :a, type: Integer
46
+ folder :bar do
47
+ key :b, type: Symbol
48
+ end
49
+ end
50
+ end
51
+
52
+ TripleNestedSchema = KeyValueName.schema do
53
+ folder :foo do
54
+ key :a, type: Integer
55
+ folder :bar do
56
+ key :b, type: Integer
57
+ folder :baz do
58
+ key :c, type: Integer
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ CustomClassNameSchema = KeyValueName.schema do
65
+ folder :foo, class_name: :CustomFoo do
66
+ file :bar, class_name: :CustomBar
67
+ end
68
+ end
69
+
70
+ def test_one_file_schema
71
+ Dir.mktmpdir do |tmp|
72
+ schema = OneFileSchema.new(root: tmp)
73
+ foo = schema.foo
74
+ assert !foo.exist?
75
+
76
+ assert_equal File.join(tmp, 'foo'), foo.to_s
77
+
78
+ foo.touch!
79
+ assert foo.exist?
80
+
81
+ foo.destroy!
82
+ assert !foo.exist?
83
+ end
84
+ end
85
+
86
+ def test_one_file_set_schema
87
+ Dir.mktmpdir do |tmp|
88
+ schema = OneFileSetSchema.new(root: tmp)
89
+ assert_equal [], schema.foo.all
90
+
91
+ foo1 = schema.foo.new(a: 1)
92
+ assert_equal File.join(tmp, 'foo-a-1'), foo1.to_s
93
+ assert_equal 1, foo1.a
94
+
95
+ foo2 = schema.foo.new(a: 2)
96
+ assert_equal File.join(tmp, 'foo-a-2'), foo2.to_s
97
+ assert_equal 2, foo2.a
98
+ end
99
+ end
100
+
101
+ def test_one_folder_schema
102
+ Dir.mktmpdir do |tmp|
103
+ schema = OneFolderSchema.new(root: tmp)
104
+ foo = schema.foo
105
+ assert !foo.exist?
106
+
107
+ assert_equal File.join(tmp, 'foo'), foo.to_s
108
+
109
+ foo.mkdir!
110
+ assert foo.exist?
111
+
112
+ foo.destroy!
113
+ assert !foo.exist?
114
+ end
115
+ end
116
+
117
+ def test_one_folder_set_schema
118
+ Dir.mktmpdir do |tmp|
119
+ schema = OneFolderSetSchema.new(root: tmp)
120
+ assert_equal [], schema.foo.all
121
+
122
+ foo1 = schema.foo.new(a: 1)
123
+ assert_equal File.join(tmp, 'foo-a-1'), foo1.to_s
124
+ assert_equal 1, foo1.a
125
+
126
+ foo2 = schema.foo.new(a: 2)
127
+ assert_equal File.join(tmp, 'foo-a-2'), foo2.to_s
128
+ assert_equal 2, foo2.a
129
+ end
130
+ end
131
+
132
+ def test_one_folder_set_one_file_schema
133
+ Dir.mktmpdir do |tmp|
134
+ schema = OneFolderSetOneFileSchema.new(root: tmp)
135
+
136
+ foo = schema.foo.new(a: 1)
137
+ bar = foo.bar
138
+ assert_equal File.join(tmp, 'foo-a-1', 'bar'), bar.to_s
139
+
140
+ bar.touch!
141
+ assert bar.exist?
142
+
143
+ bar.destroy!
144
+ assert !bar.exist?
145
+ end
146
+ end
147
+
148
+ def test_one_folder_set_one_folder_schema
149
+ Dir.mktmpdir do |tmp|
150
+ schema = OneFolderSetOneFolderSchema.new(root: tmp)
151
+
152
+ foo = schema.foo.new(a: 1)
153
+ bar = foo.bar
154
+ assert_equal File.join(tmp, 'foo-a-1', 'bar'), bar.to_s
155
+
156
+ bar.mkdir!
157
+ assert bar.exist?
158
+
159
+ bar.destroy!
160
+ assert !bar.exist?
161
+ end
162
+ end
163
+
164
+ def test_one_folder_set_one_folder_set_schema
165
+ Dir.mktmpdir do |tmp|
166
+ schema = OneFolderSetOneFolderSetSchema.new(root: tmp)
167
+
168
+ foo = schema.foo.new(a: 1)
169
+ bar = foo.bar.new(b: :c)
170
+ assert_equal File.join(tmp, 'foo-a-1', 'bar-b-c'), bar.to_s
171
+
172
+ bar.mkdir!
173
+ assert_equal [bar], foo.bar.all
174
+
175
+ bar.destroy!
176
+ assert_equal [], foo.bar.all
177
+ end
178
+ end
179
+
180
+ def test_triple_nested_schema
181
+ Dir.mktmpdir do |tmp|
182
+ schema = TripleNestedSchema.new(root: tmp)
183
+
184
+ foo = schema.foo.new(a: 1)
185
+ bar = foo.bar.new(b: 2)
186
+ baz = bar.baz.new(c: 3)
187
+ assert_equal \
188
+ File.join(tmp, 'foo-a-1', 'bar-b-2', 'baz-c-3'), baz.to_s
189
+
190
+ baz.mkdir!
191
+ assert_equal [baz], bar.baz.all
192
+
193
+ baz.destroy!
194
+ assert_equal [], bar.baz.all
195
+
196
+ foo.destroy!
197
+ assert_equal [], schema.foo.all
198
+ end
199
+ end
200
+
201
+ def test_parent
202
+ Dir.mktmpdir do |tmp|
203
+ schema = TripleNestedSchema.new(root: tmp)
204
+
205
+ foo = schema.foo.new(a: 1)
206
+ bar = foo.bar.new(b: 2)
207
+ baz = bar.baz.new(c: 3)
208
+
209
+ assert_nil schema.parent
210
+ assert_equal schema, foo.parent
211
+ assert_equal foo, bar.parent
212
+ assert_equal bar, baz.parent
213
+ assert_equal foo, baz.parent.parent
214
+ end
215
+ end
216
+
217
+ def test_reserved_keys
218
+ error = assert_raises(ArgumentError) do
219
+ KeyValueName.schema do
220
+ file :parent
221
+ end
222
+ end
223
+ assert_match(/reserved symbol/, error.message)
224
+
225
+ error = assert_raises(ArgumentError) do
226
+ KeyValueName.schema do
227
+ folder :parent
228
+ end
229
+ end
230
+ assert_match(/reserved symbol/, error.message)
231
+
232
+ error = assert_raises(ArgumentError) do
233
+ KeyValueName.schema do
234
+ folder :foo do
235
+ key :parent, type: Integer
236
+ end
237
+ end
238
+ end
239
+ assert_match(/reserved symbol/, error.message)
240
+ end
241
+
242
+ def test_custom_class_name
243
+ Dir.mktmpdir do |tmp|
244
+ schema = CustomClassNameSchema.new(root: tmp)
245
+
246
+ foo = schema.foo
247
+ assert_match(/CustomClassNameSchema::CustomFoo\z/, foo.class.to_s)
248
+
249
+ bar = foo.bar
250
+ assert_match(
251
+ /CustomClassNameSchema::CustomFoo::CustomBar\z/,
252
+ bar.class.to_s
253
+ )
254
+ end
255
+ end
256
+ end