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.
- checksums.yaml +5 -5
- data/README.md +28 -15
- data/lib/key_value_name/builders/container_builder.rb +49 -0
- data/lib/key_value_name/builders/file_builder.rb +59 -0
- data/lib/key_value_name/builders/folder_builder.rb +45 -0
- data/lib/key_value_name/builders/key_value_builder.rb +43 -0
- data/lib/key_value_name/builders/schema_builder.rb +19 -0
- data/lib/key_value_name/collection.rb +41 -0
- data/lib/key_value_name/marshalers/base.rb +7 -4
- data/lib/key_value_name/marshalers/boolean_marshaler.rb +24 -0
- data/lib/key_value_name/marshalers/float_marshaler.rb +26 -0
- data/lib/key_value_name/marshalers/integer_marshaler.rb +37 -0
- data/lib/key_value_name/marshalers/symbol_marshaler.rb +2 -2
- data/lib/key_value_name/marshalers.rb +14 -2
- data/lib/key_value_name/mixins/file_name.rb +50 -0
- data/lib/key_value_name/mixins/folder_name.rb +34 -0
- data/lib/key_value_name/mixins/name.rb +52 -0
- data/lib/key_value_name/schema.rb +26 -0
- data/lib/key_value_name/spec.rb +38 -17
- data/lib/key_value_name/version.rb +2 -2
- data/lib/key_value_name.rb +26 -6
- data/test/key_value_name/extension_test.rb +49 -0
- data/test/key_value_name/file_builder_test.rb +64 -0
- data/test/key_value_name/folder_builder_test.rb +27 -0
- data/test/key_value_name/key_value_name_test.rb +58 -35
- data/test/key_value_name/schema_test.rb +256 -0
- metadata +27 -12
- data/lib/key_value_name/builder.rb +0 -91
- data/lib/key_value_name/marshalers/numeric_marshaler.rb +0 -44
data/lib/key_value_name/spec.rb
CHANGED
@@ -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,
|
8
|
+
def initialize(marshalers, prefix = nil, suffix = nil)
|
9
9
|
@marshalers = marshalers
|
10
|
-
@
|
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 :
|
19
|
+
attr_reader :prefix
|
20
|
+
attr_reader :suffix
|
19
21
|
attr_reader :matcher
|
20
22
|
|
21
|
-
def matches?(
|
22
|
-
|
23
|
+
def matches?(basename)
|
24
|
+
basename =~ matcher
|
23
25
|
end
|
24
26
|
|
25
|
-
def
|
26
|
-
|
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.
|
38
|
+
[key, marshaler.parse(Regexp.last_match(index + 1))]
|
29
39
|
end]
|
30
40
|
end
|
31
41
|
|
32
|
-
def
|
33
|
-
|
34
|
-
value_string = marshalers[key].
|
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
|
-
|
38
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
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
|
data/lib/key_value_name.rb
CHANGED
@@ -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
|
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.
|
17
|
-
|
18
|
-
|
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/
|
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 <
|
10
|
-
TestInteger = KeyValueName.new do
|
11
|
-
|
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
|
15
|
-
|
14
|
+
TestHexNumeric = KeyValueName.new do
|
15
|
+
key :b, type: Integer, format: '%x'
|
16
16
|
end
|
17
17
|
|
18
|
-
TestFormattedNumeric = KeyValueName.new do
|
19
|
-
|
18
|
+
TestFormattedNumeric = KeyValueName.new do
|
19
|
+
key :c, type: Float, format: '%.3f'
|
20
20
|
end
|
21
21
|
|
22
|
-
TestPaddedNumeric = KeyValueName.new do
|
23
|
-
|
22
|
+
TestPaddedNumeric = KeyValueName.new do
|
23
|
+
key :d, type: Integer, format: '%04d'
|
24
24
|
end
|
25
25
|
|
26
|
-
TestSymbol = KeyValueName.new do
|
27
|
-
|
26
|
+
TestSymbol = KeyValueName.new do
|
27
|
+
key :a, type: Symbol
|
28
28
|
end
|
29
29
|
|
30
|
-
TestFloat = KeyValueName.new do
|
31
|
-
|
30
|
+
TestFloat = KeyValueName.new do
|
31
|
+
key :a, type: Float
|
32
32
|
end
|
33
33
|
|
34
|
-
TestTwoIntegers = KeyValueName.new do
|
35
|
-
|
36
|
-
|
34
|
+
TestTwoIntegers = KeyValueName.new do
|
35
|
+
include_keys TestInteger
|
36
|
+
include_keys TestHexNumeric
|
37
37
|
end
|
38
38
|
|
39
|
-
TestMixed = KeyValueName.new do
|
40
|
-
|
41
|
-
|
42
|
-
|
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
|
46
|
-
|
47
|
-
|
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
|
51
|
-
|
52
|
-
|
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.
|
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.
|
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.
|
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).
|
140
|
-
FileUtils.touch TestInteger.new(a: 2).
|
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
|