transmogrifier 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/README.md +27 -1
- data/lib/transmogrifier/engine.rb +8 -1
- data/lib/transmogrifier/nodes/array_node.rb +23 -3
- data/lib/transmogrifier/nodes/hash_node.rb +7 -0
- data/lib/transmogrifier/nodes/node.rb +8 -0
- data/lib/transmogrifier/nodes/value_node.rb +5 -0
- data/lib/transmogrifier/rules/copy.rb +29 -0
- data/lib/transmogrifier/rules/modify.rb +19 -0
- data/lib/transmogrifier/selector.rb +12 -1
- data/lib/transmogrifier/version.rb +1 -1
- data/spec/engine_spec.rb +18 -1
- data/spec/nodes/array_node_spec.rb +84 -14
- data/spec/nodes/hash_node_spec.rb +21 -1
- data/spec/nodes/value_node_spec.rb +32 -0
- data/spec/rules/copy_spec.rb +99 -0
- data/spec/rules/delete_spec.rb +16 -0
- data/spec/rules/modify_spec.rb +34 -0
- data/spec/rules/move_spec.rb +17 -0
- data/spec/selector_spec.rb +11 -2
- data/spec/transmogrifier_spec.rb +178 -5
- metadata +12 -8
- data/.gitignore +0 -18
- data/Rakefile +0 -1
- data/transmogrifier.gemspec +0 -37
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDE3MWU3Yjc2NTU5ZjQ5NTNmMzhmZDU0YWU0N2NjZWExMjQzNmQwMA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
7
|
-
|
6
|
+
ZTk1NTkyN2JlZTRkMzI2MTgxZTM3ZjY2OWFmZTY4YjRjYmUxZTQwOA==
|
7
|
+
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDQ3MDFkYzkyZTE2NDk1M2RlYmM1MjFlOTRhNzIxN2JmZWE4MWFlNDk5MDcw
|
10
|
+
NjhkMWVlZTBjZDllZTNhZjg2MWU1OWU2N2QxNDNmYWQyYzk3MWE2YjVjNDIy
|
11
|
+
YzJjNTM3NWVjNmU1YTQ3YjgxNGRhNTBlZTIxMzY4NTM4NGQzYTk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDdhNWI1ODUwNDcxNDQ0YTFmZDBmMjI4MzMwNTgzMjFiNDhlMGYxZDQ2MTVl
|
14
|
+
NjJhMDhkZTMzOTE3NDBhMjk5YzgwNjY0OTMyYWI1MWIxYTFkZmE0NjllOTgy
|
15
|
+
ZjdjZWM5YThjY2ZiMWYzNmNkNmJiZWE0MzA4ZDRjNzFhZDg5MTQ=
|
data/README.md
CHANGED
@@ -17,6 +17,19 @@ output_hash = engine.run(input_hash)
|
|
17
17
|
# output_hash => {"key" => "value", "new_key" => "new_value"}
|
18
18
|
```
|
19
19
|
|
20
|
+
#### Copying a key
|
21
|
+
```ruby
|
22
|
+
engine = Transmogrifier::Engine.new
|
23
|
+
move = Transmogrifier::Rules::Copy.new("", "key", "nested")
|
24
|
+
|
25
|
+
engine.add_rule(:copy, "", "key", "nested")
|
26
|
+
|
27
|
+
input_hash = {"key" => "value", "nested" => {"nested_key" => "nested_value"}}
|
28
|
+
output_hash = transmogrifier.run(input_hash)
|
29
|
+
|
30
|
+
# output_hash => {"key" => "value", "nested" => {"nested_key" => "nested_value", "key" => "value"}}
|
31
|
+
```
|
32
|
+
|
20
33
|
#### Deleting a key
|
21
34
|
```ruby
|
22
35
|
engine = Transmogrifier::Engine.new
|
@@ -30,6 +43,19 @@ output_hash = engine.run(input_hash)
|
|
30
43
|
# output_hash => {"key" => "value"}
|
31
44
|
```
|
32
45
|
|
46
|
+
#### Modifying a value
|
47
|
+
```ruby
|
48
|
+
engine = Transmogrifier::Engine.new
|
49
|
+
move = Transmogrifier::Rules::Modify.new("", "key", "nested")
|
50
|
+
|
51
|
+
engine.add_rule(:modify, "key", "al", "og")
|
52
|
+
|
53
|
+
input_hash = {"key" => "value", "nested" => {"nested_key" => "nested_value"}}
|
54
|
+
output_hash = transmogrifier.run(input_hash)
|
55
|
+
|
56
|
+
# output_hash => {"key" => "vogue", "nested" => {"nested_key" => "nested_value"}}
|
57
|
+
```
|
58
|
+
|
33
59
|
#### Moving a key
|
34
60
|
```ruby
|
35
61
|
engine = Transmogrifier::Engine.new
|
@@ -109,4 +135,4 @@ the selector `nested.second_level.deep` will apply to `buried_value`. Rules can
|
|
109
135
|
],
|
110
136
|
}
|
111
137
|
```
|
112
|
-
the hash with the name `this one!` can be operated on with `array.[name=this one!]`. Arrays can also wildcard match all children. For example to match both hashes in the array above, use the selector `array.[]`.
|
138
|
+
the hash with the name `this one!` can be operated on with `array.[name=this one!]` or `array.[name!=not me]`. Arrays can also wildcard match all children. For example to match both hashes in the array above, use the selector `array.[]`.
|
@@ -5,7 +5,14 @@ module Transmogrifier
|
|
5
5
|
rules_array.map do |rule|
|
6
6
|
type = rule["type"].capitalize
|
7
7
|
selector = rule["selector"]
|
8
|
-
options = [
|
8
|
+
options = [
|
9
|
+
rule["object"],
|
10
|
+
rule["from"],
|
11
|
+
rule["to"],
|
12
|
+
rule["name"],
|
13
|
+
rule["pattern"],
|
14
|
+
rule["replacement"],
|
15
|
+
].compact
|
9
16
|
Transmogrifier::Rules.const_get(type).new(selector, *options)
|
10
17
|
end
|
11
18
|
)
|
@@ -18,10 +18,17 @@ module Transmogrifier
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
def clone(key)
|
22
|
+
matching_nodes = find_nodes(key)
|
23
|
+
raise "Multiple nodes match #{key}, clone criteria ambiguous" if matching_nodes.length > 1
|
24
|
+
|
25
|
+
Marshal.load(Marshal.dump(matching_nodes.first))
|
26
|
+
end
|
27
|
+
|
21
28
|
def delete(key)
|
22
29
|
matching_nodes = find_nodes(key)
|
23
|
-
|
24
|
-
|
30
|
+
deleted_nodes = matching_nodes.each { |n| @array.delete(n) }
|
31
|
+
deleted_nodes.length > 1 ? deleted_nodes : deleted_nodes.first
|
25
32
|
end
|
26
33
|
|
27
34
|
def_delegator :@array, :<<, :append
|
@@ -30,7 +37,20 @@ module Transmogrifier
|
|
30
37
|
private
|
31
38
|
|
32
39
|
def find_nodes(attributes)
|
33
|
-
@array
|
40
|
+
return @array if attributes.empty?
|
41
|
+
|
42
|
+
filtered = @array.clone
|
43
|
+
attributes.each do |attr|
|
44
|
+
case attr[0]
|
45
|
+
when "="
|
46
|
+
filtered.select! { |node| node.merge(Hash[*attr[1..-1]]) == node }
|
47
|
+
when "!="
|
48
|
+
filtered.reject! { |node| node.merge(Hash[*attr[1..-1]]) == node }
|
49
|
+
else
|
50
|
+
raise "Unsupported attribute filter #{attr.inspect}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
filtered
|
34
54
|
end
|
35
55
|
end
|
36
56
|
end
|
@@ -20,6 +20,13 @@ module Transmogrifier
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
def clone(key)
|
24
|
+
matching_node = @hash[key]
|
25
|
+
raise "Multiple nodes match #{key}, clone criteria ambiguous" if matching_node.nil?
|
26
|
+
|
27
|
+
Marshal.load(Marshal.dump(matching_node))
|
28
|
+
end
|
29
|
+
|
23
30
|
def_delegator :@hash, :delete
|
24
31
|
def_delegator :@hash, :merge!, :append
|
25
32
|
def_delegator :@hash, :to_hash, :raw
|
@@ -19,6 +19,10 @@ module Transmogrifier
|
|
19
19
|
raise NotImplementedError
|
20
20
|
end
|
21
21
|
|
22
|
+
def clone(key_or_name)
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
22
26
|
def delete(key_or_name)
|
23
27
|
raise NotImplementedError
|
24
28
|
end
|
@@ -26,5 +30,9 @@ module Transmogrifier
|
|
26
30
|
def append(node)
|
27
31
|
raise NotImplementedError
|
28
32
|
end
|
33
|
+
|
34
|
+
def modify(pattern, replacement)
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
@@ -11,6 +11,11 @@ module Transmogrifier
|
|
11
11
|
raise "cannot find children of ValueNode satisfying non-empty selector #{keys}"
|
12
12
|
end
|
13
13
|
|
14
|
+
def modify(pattern, replacement)
|
15
|
+
raise "Value is not modifiable using pattern matching" unless @value.respond_to?(:gsub)
|
16
|
+
return @value.gsub!(Regexp.new(pattern), replacement)
|
17
|
+
end
|
18
|
+
|
14
19
|
def raw
|
15
20
|
@value
|
16
21
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Transmogrifier
|
2
|
+
module Rules
|
3
|
+
class Copy
|
4
|
+
def initialize(parent_selector, from, to)
|
5
|
+
@parent_selector, @from, @to = parent_selector, from, to
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply!(input_hash)
|
9
|
+
top = Node.for(input_hash)
|
10
|
+
*from_keys, from_key = Selector.from_string(@from).keys
|
11
|
+
*to_keys, to_key = Selector.from_string(@to).keys
|
12
|
+
|
13
|
+
parents = top.find_all(Selector.from_string(@parent_selector).keys)
|
14
|
+
parents.each do |parent|
|
15
|
+
to_parent = parent.find_all(to_keys).first
|
16
|
+
object = parent.find_all(from_keys).first.clone(from_key)
|
17
|
+
|
18
|
+
if to_child = to_parent.find_all([to_key]).first
|
19
|
+
to_child.append(object)
|
20
|
+
else
|
21
|
+
to_parent.append({to_key => object})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
top.raw
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Transmogrifier
|
2
|
+
module Rules
|
3
|
+
class Modify
|
4
|
+
def initialize(parent_selector, pattern, replacement)
|
5
|
+
@parent_selector, @pattern, @replacement = parent_selector, pattern, replacement
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply!(input_hash)
|
9
|
+
top = Node.for(input_hash)
|
10
|
+
parent_keys = Selector.from_string(@parent_selector).keys
|
11
|
+
|
12
|
+
parents = top.find_all(parent_keys)
|
13
|
+
parents.each { |parent| parent.modify(@pattern, @replacement) }
|
14
|
+
|
15
|
+
top.raw
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Transmogrifier
|
2
2
|
class Selector
|
3
3
|
FILTER_REGEX = /\[(.*)\]/
|
4
|
+
OPERATORS = ["!=", "="]
|
4
5
|
|
5
6
|
def self.from_string(string)
|
6
7
|
new(
|
7
8
|
string.split(".").map do |str|
|
8
9
|
match = str.scan(FILTER_REGEX).flatten.first
|
9
|
-
match ? match.split(",").map {
|
10
|
+
match ? match.split(",").map {|s| to_array(s)} : str
|
10
11
|
end
|
11
12
|
)
|
12
13
|
end
|
@@ -16,5 +17,15 @@ module Transmogrifier
|
|
16
17
|
def initialize(keys)
|
17
18
|
@keys = keys
|
18
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def self.to_array(string)
|
24
|
+
OPERATORS.each do |op|
|
25
|
+
next unless string.include?(op)
|
26
|
+
return string.split(op).insert(0, op)
|
27
|
+
end
|
28
|
+
[string]
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
data/spec/engine_spec.rb
CHANGED
@@ -23,6 +23,20 @@ describe Transmogrifier::Engine do
|
|
23
23
|
"type" => "delete",
|
24
24
|
"selector" => "top",
|
25
25
|
"name" => "key3"
|
26
|
+
},
|
27
|
+
|
28
|
+
{
|
29
|
+
"type" => "copy",
|
30
|
+
"selector" => "top",
|
31
|
+
"from" => "key4",
|
32
|
+
"to" => "key5",
|
33
|
+
},
|
34
|
+
|
35
|
+
{
|
36
|
+
"type" => "modify",
|
37
|
+
"selector" => "top.key5",
|
38
|
+
"pattern" => "\\d+",
|
39
|
+
"replacement" => ".num",
|
26
40
|
}
|
27
41
|
]
|
28
42
|
end
|
@@ -31,7 +45,8 @@ describe Transmogrifier::Engine do
|
|
31
45
|
input_hash = {
|
32
46
|
"top" => {
|
33
47
|
"key1" => "value1",
|
34
|
-
"key3" => "value2"
|
48
|
+
"key3" => "value2",
|
49
|
+
"key4" => "value4",
|
35
50
|
}
|
36
51
|
}
|
37
52
|
|
@@ -39,6 +54,8 @@ describe Transmogrifier::Engine do
|
|
39
54
|
"top" => {
|
40
55
|
"some" => "attributes",
|
41
56
|
"key2" => "value1",
|
57
|
+
"key4" => "value4",
|
58
|
+
"key5" => "value.num",
|
42
59
|
}
|
43
60
|
})
|
44
61
|
end
|
@@ -24,14 +24,78 @@ module Transmogrifier
|
|
24
24
|
])
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
context "when attribute filters are specified" do
|
28
|
+
it "filters using '='" do
|
29
|
+
array = [
|
30
|
+
{"type" => "object", "key1" => "value1"},
|
31
|
+
{"type" => "object", "key2" => "value2"},
|
32
|
+
]
|
33
|
+
node = ArrayNode.new(array)
|
34
|
+
|
35
|
+
expect(node.find_all([[["=", "type", "object"]]]).map(&:raw)).to eq(array)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "filters using '!='" do
|
39
|
+
array = [
|
40
|
+
{"type" => "object1", "key1" => "value1"},
|
41
|
+
{"type" => "object2", "key2" => "value2"},
|
42
|
+
]
|
43
|
+
node = ArrayNode.new(array)
|
44
|
+
|
45
|
+
expect(node.find_all([[["!=", "type", "object1"]]]).map(&:raw)).to eq(array.slice(1,1))
|
46
|
+
end
|
47
|
+
|
48
|
+
it "filters using '!=' and '='" do
|
49
|
+
array = [
|
50
|
+
{"type" => "object1", "key1" => "value1"},
|
51
|
+
{"type" => "object2", "key2" => "value2"},
|
52
|
+
{"type" => "object3", "key3" => "value3"},
|
53
|
+
]
|
54
|
+
node = ArrayNode.new(array)
|
55
|
+
|
56
|
+
expect(node.find_all([[["!=", "type", "object1"],["=", "type", "object2"]]]).map(&:raw)).to eq(array.slice(1,1))
|
57
|
+
end
|
58
|
+
|
59
|
+
it "raises ArgumentError for unknown operators" do
|
60
|
+
array = [
|
61
|
+
{"type" => "object1", "key1" => "value1"},
|
62
|
+
{"type" => "object2", "key2" => "value2"},
|
63
|
+
]
|
64
|
+
node = ArrayNode.new(array)
|
65
|
+
|
66
|
+
expect{node.find_all([[["~", "type", "object1"]]])}.to raise_error
|
67
|
+
expect{node.find_all([[["value"]]])}.to raise_error
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#clone" do
|
73
|
+
context "when one node matches the criteria" do
|
74
|
+
it "returns the node from the array" do
|
75
|
+
value = {"name" => "object1"}
|
76
|
+
array = [value, {"name" => "object2"}]
|
77
|
+
node = ArrayNode.new(array)
|
78
|
+
expect(node.clone([["=", "name", "object1"]])).to eq(value)
|
79
|
+
expect(node.clone([["=", "name", "object1"]])).to_not be(value)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when more than one node matches the criteria" do
|
84
|
+
it "raises an error" do
|
85
|
+
array = [{"name" => "object1", "common_key" => "common_value"}, {"name" => "object2", "common_key" => "common_value"}]
|
86
|
+
node = ArrayNode.new(array)
|
87
|
+
expect {
|
88
|
+
node.clone([["=", "common_key", "common_value"]])
|
89
|
+
}.to raise_error
|
90
|
+
end
|
91
|
+
end
|
33
92
|
|
34
|
-
|
93
|
+
context "when no nodes match the criteria" do
|
94
|
+
it "returns nil" do
|
95
|
+
array = [{"name" => "object1"}, {"name" => "object2"}]
|
96
|
+
node = ArrayNode.new(array)
|
97
|
+
expect(node.clone([["=", "name", "not_present"]])).to be_nil
|
98
|
+
end
|
35
99
|
end
|
36
100
|
end
|
37
101
|
|
@@ -43,20 +107,18 @@ module Transmogrifier
|
|
43
107
|
{"name" => "object2"},
|
44
108
|
]
|
45
109
|
node = ArrayNode.new(array)
|
46
|
-
expect(node.delete([["name", "object1"]])).to eq({"name" => "object1"})
|
110
|
+
expect(node.delete([["=", "name", "object1"]])).to eq({"name" => "object1"})
|
47
111
|
end
|
48
112
|
end
|
49
113
|
|
50
114
|
context "when more than one node matches the criteria" do
|
51
|
-
it "
|
115
|
+
it "deletes all matching nodes from array" do
|
52
116
|
array = [
|
53
117
|
{"name" => "object1", "common_key" => "common_value"},
|
54
118
|
{"name" => "object2", "common_key" => "common_value"},
|
55
119
|
]
|
56
|
-
node = ArrayNode.new(array)
|
57
|
-
expect
|
58
|
-
node.delete([["common_key", "common_value"]])
|
59
|
-
}.to raise_error
|
120
|
+
node = ArrayNode.new(array.clone)
|
121
|
+
expect(node.delete([["=", "common_key", "common_value"]])).to eq(array)
|
60
122
|
end
|
61
123
|
end
|
62
124
|
|
@@ -67,7 +129,7 @@ module Transmogrifier
|
|
67
129
|
{"name" => "object2"},
|
68
130
|
]
|
69
131
|
node = ArrayNode.new(array)
|
70
|
-
expect(node.delete([["name", "not_present"]])).to be_nil
|
132
|
+
expect(node.delete([["=", "name", "not_present"]])).to be_nil
|
71
133
|
end
|
72
134
|
end
|
73
135
|
end
|
@@ -80,5 +142,13 @@ module Transmogrifier
|
|
80
142
|
expect(node.raw).to eq([{"name" => "object1"}, {"name" => "object2"}])
|
81
143
|
end
|
82
144
|
end
|
145
|
+
|
146
|
+
describe "#modify" do
|
147
|
+
it "raises a NotImplementedError" do
|
148
|
+
expect {
|
149
|
+
ArrayNode.new("hello").modify("value", "value2")
|
150
|
+
}.to raise_error(NotImplementedError)
|
151
|
+
end
|
152
|
+
end
|
83
153
|
end
|
84
154
|
end
|
@@ -26,7 +26,7 @@ module Transmogrifier
|
|
26
26
|
end
|
27
27
|
|
28
28
|
context "given multiple selector keys" do
|
29
|
-
let(:keys) { ["key", [["k", "v"]]] }
|
29
|
+
let(:keys) { ["key", [["=", "k", "v"]]] }
|
30
30
|
|
31
31
|
context "when the first key is a key in the hash" do
|
32
32
|
let(:hash) {{
|
@@ -65,6 +65,18 @@ module Transmogrifier
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
describe "#clone" do
|
69
|
+
it "returns a copy of value" do
|
70
|
+
value = "other_value"
|
71
|
+
hash = {"key" => "value", "extra_key" => value}
|
72
|
+
node = HashNode.new(hash)
|
73
|
+
|
74
|
+
expect(node.clone("extra_key")).to eql(value)
|
75
|
+
expect(node.clone("extra_key")).to_not be(value)
|
76
|
+
expect(node.raw).to eq("key" => "value", "extra_key" => "other_value")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
68
80
|
describe "#delete" do
|
69
81
|
it "deletes the given key" do
|
70
82
|
hash = {"key" => "value", "extra_key" => "other_value"}
|
@@ -90,5 +102,13 @@ module Transmogrifier
|
|
90
102
|
expect(node.raw).to eq({"key" => "value", "extra_key" => "extra_value"})
|
91
103
|
end
|
92
104
|
end
|
105
|
+
|
106
|
+
describe "#modify" do
|
107
|
+
it "raises a NotImplementedError" do
|
108
|
+
expect {
|
109
|
+
HashNode.new("hello").modify("value", "value2")
|
110
|
+
}.to raise_error(NotImplementedError)
|
111
|
+
end
|
112
|
+
end
|
93
113
|
end
|
94
114
|
end
|
@@ -27,6 +27,14 @@ module Transmogrifier
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
describe "#clone" do
|
31
|
+
it "raises a NotImplementedError" do
|
32
|
+
expect {
|
33
|
+
ValueNode.new("hello").clone("key")
|
34
|
+
}.to raise_error(NotImplementedError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
30
38
|
describe "#delete" do
|
31
39
|
it "raises a NotImplementedError" do
|
32
40
|
expect {
|
@@ -42,5 +50,29 @@ module Transmogrifier
|
|
42
50
|
}.to raise_error(NotImplementedError)
|
43
51
|
end
|
44
52
|
end
|
53
|
+
|
54
|
+
describe "#modify" do
|
55
|
+
context "when pattern matches" do
|
56
|
+
it "modifies the value based on simple pattern" do
|
57
|
+
node = ValueNode.new("value")
|
58
|
+
expect(node.modify("al", "og")).to eq("vogue")
|
59
|
+
expect(node.raw).to eq("vogue")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "modifies the value based on complex pattern" do
|
63
|
+
node = ValueNode.new("valllue")
|
64
|
+
expect(node.modify("a.*u", "ogu")).to eq("vogue")
|
65
|
+
expect(node.raw).to eq("vogue")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when pattern does not match" do
|
70
|
+
it "does not modify value" do
|
71
|
+
node = ValueNode.new("value")
|
72
|
+
expect(node.modify("ss", "og")).to be_nil
|
73
|
+
expect(node.raw).to eq("value")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
45
77
|
end
|
46
78
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require "transmogrifier"
|
2
|
+
|
3
|
+
describe Transmogrifier::Rules::Copy do
|
4
|
+
let(:input_hash) do
|
5
|
+
{
|
6
|
+
"key" => "value",
|
7
|
+
"array" => [{"inside" => "value"}],
|
8
|
+
"nested" => {
|
9
|
+
"key" => "value",
|
10
|
+
},
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when the selector finds a HashNode" do
|
15
|
+
context "when the target key exists" do
|
16
|
+
subject(:copy) { described_class.new("", "array.[inside=value]", "nested") }
|
17
|
+
|
18
|
+
it "moves the hash to the to selector" do
|
19
|
+
expect(copy.apply!(input_hash)).to eq({
|
20
|
+
"key" => "value",
|
21
|
+
"array" => [{"inside" => "value"}],
|
22
|
+
"nested" => {
|
23
|
+
"key" => "value",
|
24
|
+
"inside" => "value",
|
25
|
+
},
|
26
|
+
})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when the target key doesn't exist" do
|
31
|
+
subject(:copy) { described_class.new("", "array.[inside=value]", "nested.nested_again") }
|
32
|
+
|
33
|
+
it "moves the hash to a new child" do
|
34
|
+
expect(copy.apply!(input_hash)).to eq({
|
35
|
+
"key" => "value",
|
36
|
+
"array" => [{"inside" => "value"}],
|
37
|
+
"nested" => {
|
38
|
+
"key" => "value",
|
39
|
+
"nested_again" => {
|
40
|
+
"inside" => "value",
|
41
|
+
}
|
42
|
+
},
|
43
|
+
})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when the from selector has a wildcard" do
|
48
|
+
let(:input_hash) do
|
49
|
+
{
|
50
|
+
"list_of_things" => [
|
51
|
+
{
|
52
|
+
"name" => "object1",
|
53
|
+
"property" => "property1",
|
54
|
+
"nested" => {}
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"name" => "object2",
|
58
|
+
"property" => "property2",
|
59
|
+
"nested" => {}
|
60
|
+
},
|
61
|
+
]
|
62
|
+
}
|
63
|
+
end
|
64
|
+
subject(:copy) { described_class.new("list_of_things.[]", "property", "nested.property") }
|
65
|
+
|
66
|
+
it "moves the matched hash to the correct place" do
|
67
|
+
expect(copy.apply!(input_hash)).to eq({
|
68
|
+
"list_of_things" => [
|
69
|
+
{
|
70
|
+
"name" => "object1",
|
71
|
+
"property" => "property1",
|
72
|
+
"nested" => { "property" => "property1" }
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"name" => "object2",
|
76
|
+
"property" => "property2",
|
77
|
+
"nested" => { "property" => "property2" }
|
78
|
+
},
|
79
|
+
]
|
80
|
+
})
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the selector finds an ArrayNode" do
|
86
|
+
subject(:copy) { described_class.new("", "array", "nested.array") }
|
87
|
+
|
88
|
+
it "moves the array to the to selector" do
|
89
|
+
expect(copy.apply!(input_hash)).to eq({
|
90
|
+
"key" => "value",
|
91
|
+
"array" => [{"inside" => "value"}],
|
92
|
+
"nested" => {
|
93
|
+
"key" => "value",
|
94
|
+
"array" => [{"inside" => "value"}],
|
95
|
+
},
|
96
|
+
})
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/spec/rules/delete_spec.rb
CHANGED
@@ -35,4 +35,20 @@ describe Transmogrifier::Rules::Delete do
|
|
35
35
|
})
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
context "when the selector matches multiple nodes" do
|
40
|
+
subject(:delete) { described_class.new("array", "[inside=value]") }
|
41
|
+
|
42
|
+
before { input_hash["array"] << {"inside" => "value"} }
|
43
|
+
|
44
|
+
it "deletes all entries from the array" do
|
45
|
+
expect(delete.apply!(input_hash)).to eq({
|
46
|
+
"key" => "value",
|
47
|
+
"array" => [],
|
48
|
+
"nested" => {
|
49
|
+
"key" => "value"
|
50
|
+
},
|
51
|
+
})
|
52
|
+
end
|
53
|
+
end
|
38
54
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "transmogrifier"
|
2
|
+
|
3
|
+
describe Transmogrifier::Rules::Modify do
|
4
|
+
let(:input_hash) do
|
5
|
+
{ "key" => "value", "array" => [] }
|
6
|
+
end
|
7
|
+
|
8
|
+
context "when the selector finds a ValueNode" do
|
9
|
+
subject(:modify) { described_class.new("key", "al", "og") }
|
10
|
+
|
11
|
+
it "modifies the value" do
|
12
|
+
expect(modify.apply!(input_hash)).to eq({
|
13
|
+
"key" => "vogue",
|
14
|
+
"array" => [],
|
15
|
+
})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when the selector finds a HashNode" do
|
20
|
+
subject(:modify) { described_class.new("", "al", "og") }
|
21
|
+
|
22
|
+
it "appends to the hash" do
|
23
|
+
expect{modify.apply!(input_hash)}.to raise_error(NotImplementedError)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when the selector finds an ArrayNode" do
|
28
|
+
subject(:modify) { described_class.new("array", "al", "og") }
|
29
|
+
|
30
|
+
it "appends to the array" do
|
31
|
+
expect{modify.apply!(input_hash)}.to raise_error(NotImplementedError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/rules/move_spec.rb
CHANGED
@@ -94,6 +94,23 @@ describe Transmogrifier::Rules::Move do
|
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
+
context "when the selector finds multiple nodes" do
|
98
|
+
subject(:move) { described_class.new("", "array.[inside=value]", "nested.array") }
|
99
|
+
|
100
|
+
before { input_hash["array"] << {"inside" => "value"} }
|
101
|
+
|
102
|
+
it "moves them all as an array to the selector" do
|
103
|
+
expect(move.apply!(input_hash)).to eq({
|
104
|
+
"key" => "value",
|
105
|
+
"array" => [],
|
106
|
+
"nested" => {
|
107
|
+
"key" => "value",
|
108
|
+
"array" => [{"inside" => "value"},{"inside" => "value"}],
|
109
|
+
},
|
110
|
+
})
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
97
114
|
context "using move as a rename" do
|
98
115
|
subject(:rename) { described_class.new("", "array", "new_array") }
|
99
116
|
|
data/spec/selector_spec.rb
CHANGED
@@ -11,15 +11,24 @@ describe Transmogrifier::Selector do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it "allows filtering by attribute" do
|
14
|
-
described_class.from_string("[attr1=val1,attr2=val2]").keys.should == [[["attr1", "val1"],["attr2", "val2"]]]
|
14
|
+
described_class.from_string("[attr1=val1,attr2=val2]").keys.should == [[["=", "attr1", "val1"],["=", "attr2", "val2"]]]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allows filtering by attribute with not-equal comparison" do
|
18
|
+
described_class.from_string("[attr1!=val1,attr2!=val2]").keys.should == [[["!=", "attr1", "val1"],["!=", "attr2", "val2"]]]
|
15
19
|
end
|
16
20
|
|
17
21
|
it "allows empty array" do
|
18
22
|
described_class.from_string("[]").keys.should == [[]]
|
19
23
|
end
|
20
24
|
|
25
|
+
it "returns array filter with the whole value for unknown or missing operator" do
|
26
|
+
described_class.from_string("[attr1,attr2~val2]").keys.should == [[["attr1"], ["attr2~val2"]]]
|
27
|
+
end
|
28
|
+
|
21
29
|
it "combines hash and array filtering" do
|
22
|
-
described_class.from_string("foo.[attr=val]").keys.should == ["foo", [["attr", "val"]]]
|
30
|
+
described_class.from_string("foo.[attr=val,attr!=val1]").keys.should == ["foo", [["=", "attr", "val"],["!=", "attr", "val1"]]]
|
31
|
+
described_class.from_string("[attr=val,attr!=val1].bar").keys.should == [[["=", "attr", "val"],["!=", "attr", "val1"]], "bar"]
|
23
32
|
end
|
24
33
|
end
|
25
34
|
end
|
data/spec/transmogrifier_spec.rb
CHANGED
@@ -12,19 +12,29 @@ describe Transmogrifier::Engine do
|
|
12
12
|
"selector" => "top",
|
13
13
|
"object" => {"some" => "attributes"}
|
14
14
|
},
|
15
|
-
|
16
15
|
{
|
17
16
|
"type" => "move",
|
18
17
|
"selector" => "top",
|
19
18
|
"from" => "key1",
|
20
19
|
"to" => "key2",
|
21
20
|
},
|
22
|
-
|
23
21
|
{
|
24
22
|
"type" => "delete",
|
25
23
|
"selector" => "top",
|
26
24
|
"name" => "key3"
|
27
|
-
}
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"type" => "copy",
|
28
|
+
"selector" => "top",
|
29
|
+
"from" => "key4",
|
30
|
+
"to" => "key5",
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"type" => "modify",
|
34
|
+
"selector" => "top.key5",
|
35
|
+
"pattern" => "\\d+",
|
36
|
+
"replacement" => ".num",
|
37
|
+
},
|
28
38
|
]
|
29
39
|
end
|
30
40
|
|
@@ -32,7 +42,8 @@ describe Transmogrifier::Engine do
|
|
32
42
|
input_hash = {
|
33
43
|
"top" => {
|
34
44
|
"key1" => "value1",
|
35
|
-
"key3" => "value2"
|
45
|
+
"key3" => "value2",
|
46
|
+
"key4" => "value4",
|
36
47
|
}
|
37
48
|
}
|
38
49
|
|
@@ -40,6 +51,8 @@ describe Transmogrifier::Engine do
|
|
40
51
|
"top" => {
|
41
52
|
"some" => "attributes",
|
42
53
|
"key2" => "value1",
|
54
|
+
"key4" => "value4",
|
55
|
+
"key5" => "value.num",
|
43
56
|
}
|
44
57
|
})
|
45
58
|
end
|
@@ -75,6 +88,100 @@ describe Transmogrifier::Engine do
|
|
75
88
|
end
|
76
89
|
end
|
77
90
|
|
91
|
+
describe "copying keys" do
|
92
|
+
let(:input_hash) do
|
93
|
+
{
|
94
|
+
"key" => "value",
|
95
|
+
"array" => [{"inside" => "value"}],
|
96
|
+
"nested" => { "key" => "value" },
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when the selector finds a HashNode" do
|
101
|
+
context "when the target key exists" do
|
102
|
+
let(:rules) { [ {"type" => "copy", "selector" => "", "from" => "array.[inside=value]", "to" => "nested"}]}
|
103
|
+
|
104
|
+
it "copies the hash to the to selector" do
|
105
|
+
expect(engine.run(input_hash)).to eq({
|
106
|
+
"key" => "value",
|
107
|
+
"array" => [{"inside" => "value"}],
|
108
|
+
"nested" => {
|
109
|
+
"key" => "value",
|
110
|
+
"inside" => "value",
|
111
|
+
},
|
112
|
+
})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when the target key doesn't exist" do
|
117
|
+
let(:rules) { [ {"type" => "copy", "selector" => "", "from" => "array.[inside=value]", "to" => "nested.nested_again"} ] }
|
118
|
+
|
119
|
+
it "copies the hash to a new child" do
|
120
|
+
expect(engine.run(input_hash)).to eq({
|
121
|
+
"key" => "value",
|
122
|
+
"array" => [{"inside" => "value"}],
|
123
|
+
"nested" => {
|
124
|
+
"key" => "value",
|
125
|
+
"nested_again" => { "inside" => "value" }
|
126
|
+
},
|
127
|
+
})
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when the from selector has a wildcard" do
|
132
|
+
let(:input_hash) do
|
133
|
+
{
|
134
|
+
"list_of_things" => [
|
135
|
+
{
|
136
|
+
"name" => "object1",
|
137
|
+
"property" => "property1",
|
138
|
+
"nested" => {}
|
139
|
+
},
|
140
|
+
{
|
141
|
+
"name" => "object2",
|
142
|
+
"property" => "property2",
|
143
|
+
"nested" => {}
|
144
|
+
},
|
145
|
+
]
|
146
|
+
}
|
147
|
+
end
|
148
|
+
let(:rules) { [ {"type" => "copy", "selector" => "list_of_things.[]", "from" => "property", "to" => "nested.property"} ] }
|
149
|
+
|
150
|
+
it "copies the matched hash to the correct place" do
|
151
|
+
expect(engine.run(input_hash)).to eq({
|
152
|
+
"list_of_things" => [
|
153
|
+
{
|
154
|
+
"name" => "object1",
|
155
|
+
"property" => "property1",
|
156
|
+
"nested" => { "property" => "property1" },
|
157
|
+
},
|
158
|
+
{
|
159
|
+
"name" => "object2",
|
160
|
+
"property" => "property2",
|
161
|
+
"nested" => { "property" => "property2" },
|
162
|
+
},
|
163
|
+
]
|
164
|
+
})
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when the selector finds an ArrayNode" do
|
170
|
+
let(:rules) { [ {"type" => "copy", "selector" => "", "from" => "array", "to" => "nested.array"} ] }
|
171
|
+
|
172
|
+
it "copies the array to the to selector" do
|
173
|
+
expect(engine.run(input_hash)).to eq({
|
174
|
+
"key" => "value",
|
175
|
+
"array" => [{"inside" => "value"}],
|
176
|
+
"nested" => {
|
177
|
+
"key" => "value",
|
178
|
+
"array" => [{"inside" => "value"}],
|
179
|
+
},
|
180
|
+
})
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
78
185
|
describe "deleting keys" do
|
79
186
|
let(:input_hash) do
|
80
187
|
{
|
@@ -100,7 +207,23 @@ describe Transmogrifier::Engine do
|
|
100
207
|
context "when the selector finds an ArrayNode" do
|
101
208
|
let(:rules) { [ {"type" => "delete", "selector" => "array", "name" => "[inside=value]"} ] }
|
102
209
|
|
103
|
-
it "deletes
|
210
|
+
it "deletes matching item from array" do
|
211
|
+
expect(engine.run(input_hash)).to eq({
|
212
|
+
"key" => "value",
|
213
|
+
"array" => [],
|
214
|
+
"nested" => {
|
215
|
+
"key" => "value"
|
216
|
+
},
|
217
|
+
})
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "when the selector matches multiple nodes" do
|
222
|
+
let(:rules) { [ {"type" => "delete", "selector" => "array", "name" => "[inside=value]"} ] }
|
223
|
+
|
224
|
+
before { input_hash["array"] << {"inside" => "value"} }
|
225
|
+
|
226
|
+
it "deletes all entries from the array" do
|
104
227
|
expect(engine.run(input_hash)).to eq({
|
105
228
|
"key" => "value",
|
106
229
|
"array" => [],
|
@@ -206,6 +329,23 @@ describe Transmogrifier::Engine do
|
|
206
329
|
end
|
207
330
|
end
|
208
331
|
|
332
|
+
context "when the selector finds multiple nodes" do
|
333
|
+
let(:rules) { [ {"type" => "move", "selector" => "", "from" => "array.[inside=value]", "to" => "nested.array"} ] }
|
334
|
+
|
335
|
+
before { input_hash["array"] << {"inside" => "value"} }
|
336
|
+
|
337
|
+
it "moves them all as an array to the selector" do
|
338
|
+
expect(engine.run(input_hash)).to eq({
|
339
|
+
"key" => "value",
|
340
|
+
"array" => [],
|
341
|
+
"nested" => {
|
342
|
+
"key" => "value",
|
343
|
+
"array" => [{"inside" => "value"},{"inside" => "value"}],
|
344
|
+
},
|
345
|
+
})
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
209
349
|
context "using move as a rename" do
|
210
350
|
let(:rules) { [ {"type" => "move", "selector" => "", "from" => "array", "to" => "new_array"} ] }
|
211
351
|
|
@@ -220,6 +360,39 @@ describe Transmogrifier::Engine do
|
|
220
360
|
end
|
221
361
|
end
|
222
362
|
end
|
363
|
+
|
364
|
+
describe "modifying value" do
|
365
|
+
let(:input_hash) do
|
366
|
+
{ "key" => "value", "array" => [] }
|
367
|
+
end
|
368
|
+
|
369
|
+
context "when the selector finds a ValueNode" do
|
370
|
+
let(:rules) { [ {"type" => "modify", "selector" => "key", "pattern" => "al", "replacement" => "og"} ] }
|
371
|
+
|
372
|
+
it "modifies the value" do
|
373
|
+
expect(engine.run(input_hash)).to eq({
|
374
|
+
"key" => "vogue",
|
375
|
+
"array" => [],
|
376
|
+
})
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
context "when the selector finds a HashNode" do
|
381
|
+
let(:rules) { [ {"type" => "modify", "selector" => "", "pattern" => "al", "replacement" => "og"} ] }
|
382
|
+
|
383
|
+
it "appends to the hash" do
|
384
|
+
expect{engine.run(input_hash)}.to raise_error(NotImplementedError)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
context "when the selector finds an ArrayNode" do
|
389
|
+
let(:rules) { [ {"type" => "modify", "selector" => "array", "pattern" => "al", "replacement" => "og"} ] }
|
390
|
+
|
391
|
+
it "appends to the array" do
|
392
|
+
expect{engine.run(input_hash)}.to raise_error(NotImplementedError)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
223
396
|
end
|
224
397
|
end
|
225
398
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transmogrifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Foley
|
@@ -59,11 +59,6 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- Gemfile
|
64
|
-
- LICENSE.txt
|
65
|
-
- README.md
|
66
|
-
- Rakefile
|
67
62
|
- lib/transmogrifier.rb
|
68
63
|
- lib/transmogrifier/engine.rb
|
69
64
|
- lib/transmogrifier/nodes.rb
|
@@ -73,21 +68,27 @@ files:
|
|
73
68
|
- lib/transmogrifier/nodes/value_node.rb
|
74
69
|
- lib/transmogrifier/rules.rb
|
75
70
|
- lib/transmogrifier/rules/append.rb
|
71
|
+
- lib/transmogrifier/rules/copy.rb
|
76
72
|
- lib/transmogrifier/rules/delete.rb
|
73
|
+
- lib/transmogrifier/rules/modify.rb
|
77
74
|
- lib/transmogrifier/rules/move.rb
|
78
75
|
- lib/transmogrifier/selector.rb
|
79
76
|
- lib/transmogrifier/version.rb
|
77
|
+
- README.md
|
78
|
+
- LICENSE.txt
|
79
|
+
- Gemfile
|
80
80
|
- spec/engine_spec.rb
|
81
81
|
- spec/nodes/array_node_spec.rb
|
82
82
|
- spec/nodes/hash_node_spec.rb
|
83
83
|
- spec/nodes/node_spec.rb
|
84
84
|
- spec/nodes/value_node_spec.rb
|
85
85
|
- spec/rules/append_spec.rb
|
86
|
+
- spec/rules/copy_spec.rb
|
86
87
|
- spec/rules/delete_spec.rb
|
88
|
+
- spec/rules/modify_spec.rb
|
87
89
|
- spec/rules/move_spec.rb
|
88
90
|
- spec/selector_spec.rb
|
89
91
|
- spec/transmogrifier_spec.rb
|
90
|
-
- transmogrifier.gemspec
|
91
92
|
homepage: http://github.com/jfoley/transmogrifier
|
92
93
|
licenses:
|
93
94
|
- MIT
|
@@ -108,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
version: '0'
|
109
110
|
requirements: []
|
110
111
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.1.11
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: A tool for manipulating schemas
|
@@ -119,7 +120,10 @@ test_files:
|
|
119
120
|
- spec/nodes/node_spec.rb
|
120
121
|
- spec/nodes/value_node_spec.rb
|
121
122
|
- spec/rules/append_spec.rb
|
123
|
+
- spec/rules/copy_spec.rb
|
122
124
|
- spec/rules/delete_spec.rb
|
125
|
+
- spec/rules/modify_spec.rb
|
123
126
|
- spec/rules/move_spec.rb
|
124
127
|
- spec/selector_spec.rb
|
125
128
|
- spec/transmogrifier_spec.rb
|
129
|
+
has_rdoc:
|
data/.gitignore
DELETED
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
data/transmogrifier.gemspec
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
Gem::Specification.new do |s|
|
4
|
-
s.name = "transmogrifier"
|
5
|
-
s.version = "0.0.1"
|
6
|
-
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["John Foley"]
|
9
|
-
s.date = "2013-11-06"
|
10
|
-
s.description = "A tool for manipulating schemas"
|
11
|
-
s.email = ["john@hisfoleyness.com"]
|
12
|
-
s.files = [".gitignore", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "lib/transmogrifier.rb", "lib/transmogrifier/engine.rb", "lib/transmogrifier/nodes.rb", "lib/transmogrifier/nodes/array_node.rb", "lib/transmogrifier/nodes/hash_node.rb", "lib/transmogrifier/nodes/node.rb", "lib/transmogrifier/nodes/value_node.rb", "lib/transmogrifier/rules.rb", "lib/transmogrifier/rules/append.rb", "lib/transmogrifier/rules/delete.rb", "lib/transmogrifier/rules/move.rb", "lib/transmogrifier/selector.rb", "lib/transmogrifier/version.rb", "spec/engine_spec.rb", "spec/nodes/array_node_spec.rb", "spec/nodes/hash_node_spec.rb", "spec/nodes/node_spec.rb", "spec/nodes/value_node_spec.rb", "spec/rules/append_spec.rb", "spec/rules/delete_spec.rb", "spec/rules/move_spec.rb", "spec/selector_spec.rb", "spec/transmogrifier_spec.rb", "transmogrifier.gemspec"]
|
13
|
-
s.homepage = "http://github.com/jfoley/transmogrifier"
|
14
|
-
s.licenses = ["MIT"]
|
15
|
-
s.require_paths = ["lib"]
|
16
|
-
s.rubygems_version = "2.0.7"
|
17
|
-
s.summary = "A tool for manipulating schemas"
|
18
|
-
s.test_files = ["spec/engine_spec.rb", "spec/nodes/array_node_spec.rb", "spec/nodes/hash_node_spec.rb", "spec/nodes/node_spec.rb", "spec/nodes/value_node_spec.rb", "spec/rules/append_spec.rb", "spec/rules/delete_spec.rb", "spec/rules/move_spec.rb", "spec/selector_spec.rb", "spec/transmogrifier_spec.rb"]
|
19
|
-
|
20
|
-
if s.respond_to? :specification_version then
|
21
|
-
s.specification_version = 4
|
22
|
-
|
23
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
24
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.3"])
|
25
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
26
|
-
s.add_development_dependency(%q<rspec>, [">= 0"])
|
27
|
-
else
|
28
|
-
s.add_dependency(%q<bundler>, ["~> 1.3"])
|
29
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
30
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
31
|
-
end
|
32
|
-
else
|
33
|
-
s.add_dependency(%q<bundler>, ["~> 1.3"])
|
34
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
35
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
36
|
-
end
|
37
|
-
end
|