serialisable 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d1e4397bf79459b96b569b558d46de21f445186
4
- data.tar.gz: 6d175852e351b5bd7de719fb2ad63c7390b819d5
3
+ metadata.gz: 398799ae5550e1a9379df90c241567166e12eeb7
4
+ data.tar.gz: d785cbed52c32917be7d480a865f80dffcc1316d
5
5
  SHA512:
6
- metadata.gz: 864ee9628a74de37b91a14615db426b6e9146b653d1846449dbfee1c51ea553d91192490b2522c45b73b2468b025cbbc8b00dffa8bc64c27cf09f2681a96f72f
7
- data.tar.gz: 53d06c080b9c9c1650836e0e42fd310057c586999abb598db6d50c6a877ca314987e501ca508dc32a3564b69b0d7b0c829101db26d2f9438f59d14c5d8a5d3b5
6
+ metadata.gz: 1ff5997b676acdbc6335fc0d1525eaa3196738a0c398dfb5b35adbe2fc3291b57b0a7304ed4bdf9ed0e6f5a1087072df8a7e2e274407949b64a186e07fa3c4a8
7
+ data.tar.gz: 1c1d395a6771858063ff8ab519e1ffabf808a32365bda9933108af81bd0f27b18b41442e3e68077db0654c4854e78f6f448b5c08dae21d8250df984fec94d48c
@@ -1,34 +1,218 @@
1
1
  require 'nokogiri'
2
-
2
+ require_relative 'serialisable/selector'
3
+
4
+ # Serialisable allows you to easily define an object that can deserialise xml
5
+ # into instances of itself. It provides a simple but powerful DSL for defining
6
+ # elements and attributes.
7
+ #
8
+ # require 'serialisable'
9
+ # require 'time'
10
+ #
11
+ # class Play
12
+ # extend Serialisable
13
+ #
14
+ # root 'play'
15
+ # element :artist, 'artist'
16
+ # element :name, 'name'
17
+ # element :played_at, 'playedat', Time
18
+ # end
19
+ #
20
+ # class User
21
+ # extend Serialisable
22
+ #
23
+ # root 'user'
24
+ # attribute :id, 'id', :to_i
25
+ # element :name, 'name'
26
+ # elements :plays, 'plays', Play
27
+ #
28
+ # def inspect
29
+ # "#<User:#{id} #{name}>"
30
+ # end
31
+ # end
32
+ #
33
+ # user = User.deserialise <<XML
34
+ # <?xml version="1.0" encoding="utf-8"?>
35
+ # <user id="12452">
36
+ # <name>John Doe</name>
37
+ # <plays>
38
+ # <play>
39
+ # <artist>Arctic Monkeys</artist>
40
+ # <name>505</name>
41
+ # <playedat>2014-02-03T12:23:55Z</playedat>
42
+ # </play>
43
+ # <play>
44
+ # <artist>Aphex Twin</artist>
45
+ # <name>Windowlicker</name>
46
+ # <playedat>2014-02-03T12:26:13Z</playedat>
47
+ # </play>
48
+ # </plays>
49
+ # </user>
50
+ # XML
51
+ #
52
+ # p user
53
+ # #=> #<User:12452 John Doe>
54
+ # p user.plays.map(&:name)
55
+ # #=> ["505", "Windowlicker"]
56
+ #
57
+ #
58
+ # @example Type as Symbol
59
+ #
60
+ # class Count
61
+ # extend Serialisable
62
+ #
63
+ # root 'count'
64
+ # attribute :value, 'value', :to_i
65
+ # end
66
+ #
67
+ # count = Count.deserialise <<XML
68
+ # <?xml version="1.0" encoding="utf-8"?>
69
+ # <count value="500" />
70
+ # XML
71
+ #
72
+ # p count.value #=> 500
73
+ #
74
+ #
75
+ # @example Type as object responding to +#parse+
76
+ #
77
+ # class IntParser
78
+ # def parse(str); str.to_i; end
79
+ # end
80
+ #
81
+ # class Count
82
+ # extend Serialisable
83
+ #
84
+ # root 'count'
85
+ # attribute :value, 'value', IntParser
86
+ # end
87
+ #
88
+ # count = Count.deserialise <<XML
89
+ # <?xml version="1.0" encoding="utf-8"?>
90
+ # <count value="500" />
91
+ # XML
92
+ #
93
+ # p count.value #=> 500
94
+ #
95
+ #
3
96
  module Serialisable
97
+ def self.extended(obj)
98
+ obj.instance_variable_set(:@__selectors, [])
99
+ end
100
+
101
+ # Define the element that makes up the root for the class.
102
+ #
103
+ # @param selector [String] Name of xml element to mark as the root.
4
104
  def root(selector)
5
105
  @__root = selector
6
- @__element = {}
7
- @__elements = {}
8
- @__attribute = {}
9
106
  end
10
107
 
11
- def attribute(name, selector, type=String)
12
- @__attribute[name] = [selector, type]
108
+ # Define an attribute selector. This will match an attribute in the defined
109
+ # root element that has the name given by +selector+.
110
+ #
111
+ # @param name [Symbol] Name of the method to be defined on the class that
112
+ # returns the value matched.
113
+ # @param selector [String] Name of xml attribute to match against.
114
+ # @param type [Symbol, #parse] If a symbol is given the matched string will
115
+ # have the method named by it called on it. If an object responding to
116
+ # #parse is given then the string value will be passed to that method.
117
+ def attribute(name, selector, type = nil)
118
+ @__selectors << Selector::Attribute.new(name, selector, type)
13
119
  end
14
120
 
15
- def element(name, selector, type=String)
16
- @__element[name] = [selector, type]
121
+ # Define an element selector. This will match a node in the defined root
122
+ # element that has the name given by +selector+.
123
+ #
124
+ # @overload element(name, serialisable)
125
+ # Use this when the node being matched contains nested xml.
126
+ #
127
+ # @param name [Symbol] Name of the method to be defined on the class that
128
+ # returns the value matched.
129
+ # @param serialisable [Serialisable]
130
+ #
131
+ # @overload element(name, root, serialisable)
132
+ # Use this when the node being matched contains nested xml and the root
133
+ # needs to be set.
134
+ #
135
+ # @param name [Symbol] Name of the method to be defined on the class that
136
+ # returns the value matched.
137
+ # @param root [String] Name of the root of the nested element, this
138
+ # overrides any root set on the +serialisable+ passed.
139
+ # @param serialisable [Serialisable] Serialisable object that represents
140
+ # the nested element.
141
+ #
142
+ # @overload element(name, selector, type=nil)
143
+ # Use this when the node only contains text.
144
+ #
145
+ # @param name [Symbol] Name of the method to be defined on the class that
146
+ # returns the value matched.
147
+ # @param selector [String] Name of xml attribute to match against.
148
+ # @param type [Symbol, #parse] If a symbol is given the matched string will
149
+ # have the method named by it called on it. If an object responding to
150
+ # #parse is given then the string value will be passed to that method.
151
+ #
152
+ def element(name, selector, type = nil)
153
+ if selector.respond_to?(:__deserialise, true)
154
+ @__selectors << Selector::Nested.new(name, selector)
155
+
156
+ elsif type.respond_to?(:__deserialise, true)
157
+ cloned_type = type.clone
158
+ cloned_type.instance_variable_set(:@__root, selector)
159
+ @__selectors << Selector::Nested.new(name, cloned_type)
160
+
161
+ else
162
+ @__selectors << Selector::Node.new(name, selector, type)
163
+ end
17
164
  end
18
165
 
19
- def elements(name, *args)
20
- case args.size
21
- when 1
22
- klass = args.first
23
- @__elements[name] = [nil, klass]
24
- when 2
25
- selector, type = args
26
- @__elements[name] = [selector, type]
166
+ # Define an elements selector. This will match all nodes in the defined root
167
+ # element that has the name given by +selector+. The method created by this
168
+ # will return an array of matching values.
169
+ #
170
+ # @overload elements(name, serialisable)
171
+ # Use this when the nodes being matched contains nested xml.
172
+ #
173
+ # @param name [Symbol] Name of the method to be defined on the class that
174
+ # returns the value matched.
175
+ # @param serialisable [Serialisable]
176
+ #
177
+ # @overload elements(name, root, serialisable)
178
+ # Use this when the nodes being matched contains nested xml and the root
179
+ # needs to be set.
180
+ #
181
+ # @param name [Symbol] Name of the method to be defined on the class that
182
+ # returns the value matched.
183
+ # @param root [String] Name of the root of the nested element, this
184
+ # overrides any root set on the +serialisable+ passed.
185
+ # @param serialisable [Serialisable] Serialisable object that represents
186
+ # the nested element.
187
+ #
188
+ # @overload elements(name, selector, type=nil)
189
+ # Use this when the nodes only contain text.
190
+ #
191
+ # @param name [Symbol] Name of the method to be defined on the class that
192
+ # returns the value matched.
193
+ # @param selector [String] Name of xml attribute to match against.
194
+ # @param type [Symbol, #parse] If a symbol is given the matched string will
195
+ # have the method named by it called on it. If an object responding to
196
+ # #parse is given then the string value will be passed to that method.
197
+ #
198
+ def elements(name, selector, type = nil)
199
+ if selector.respond_to?(:__deserialise_all, true)
200
+ @__selectors << Selector::NestedMultiple.new(name, selector, type)
201
+
202
+ elsif type.respond_to?(:__deserialise_all, true)
203
+ cloned_type = type.clone
204
+ cloned_type.instance_variable_set(:@__root, selector)
205
+ @__selectors << Selector::NestedMultiple.new(name, cloned_type)
206
+
27
207
  else
28
- raise ArgumentError
208
+ @__selectors << Selector::Nodes.new(name, selector, type)
29
209
  end
30
210
  end
31
211
 
212
+ # Deserialises the given +xml+ into an instance of the class.
213
+ #
214
+ # @param xml [String]
215
+ # @return An instance of the class that the method was called on.
32
216
  def deserialise(xml)
33
217
  __deserialise Nokogiri::XML(xml)
34
218
  end
@@ -37,99 +221,21 @@ module Serialisable
37
221
 
38
222
  def __deserialise_all(doc)
39
223
  doc = doc.children.find_all {|node| node.name == @__root }
40
-
41
- attrs_list = doc.map do |node|
42
- attrs = SerialisableHelpers.get_multiples(node, @__elements)
43
- attrs += SerialisableHelpers.get_singles(node, @__element)
44
- attrs += SerialisableHelpers.get_attributes(node, @__attribute)
45
-
46
- attrs
47
- end
48
-
49
- objs = []
50
- attrs_list.each do |attrs|
51
- attrs = Hash[attrs]
52
-
53
- attrs.each do |key, value|
54
- define_method key do
55
- instance_variable_get(:@__serialisable_attrs)[key]
56
- end
57
- end
58
-
59
- obj = new
60
- obj.instance_variable_set(:@__serialisable_attrs, attrs)
61
- objs << obj
62
- end
63
-
64
- objs
224
+ doc.map {|node| __select(node) }
65
225
  end
66
226
 
67
227
  def __deserialise(doc)
68
- doc = doc.children.find {|node| node.name == @__root }
69
-
70
- attrs = SerialisableHelpers.get_multiples(doc, @__elements)
71
- attrs += SerialisableHelpers.get_singles(doc, @__element)
72
- attrs += SerialisableHelpers.get_attributes(doc, @__attribute)
73
-
74
- attrs = Hash[attrs]
75
-
76
- attrs.each do |key, value|
77
- define_method key do
78
- instance_variable_get(:@__serialisable_attrs)[key]
79
- end
80
- end
81
-
82
- obj = new
83
- obj.instance_variable_set(:@__serialisable_attrs, attrs)
84
- obj
228
+ node = doc.children.find {|node| node.name == @__root }
229
+ __select(node)
85
230
  end
86
- end
87
-
88
- module SerialisableHelpers
89
- extend self
90
231
 
91
- def get_multiples(root, hash)
92
- hash.map do |name, (selector, type)|
93
- if type.respond_to?(:__deserialise_all, true)
94
- [name, type.send(:__deserialise_all, root)]
95
- else
96
- values = root.children.find_all {|node| node.name == selector }
97
- .map {|node| node.children.to_s }
98
- .map {|value| parse_type(value, type) }
99
-
100
- [name, values]
101
- end
102
- end
103
- end
104
-
105
- def get_singles(root, hash)
106
- hash.map do |name, (selector, type)|
107
- if selector.respond_to?(:__deserialise, true)
108
- [name, selector.send(:__deserialise, root)]
109
- else
110
- value = root.children.find {|node| node.name == selector }.children.to_s
111
- value = parse_type(value, type)
112
-
113
- [name, value]
114
- end
115
- end
116
- end
117
-
118
- def get_attributes(root, hash)
119
- hash.map do |name, (selector, type)|
120
- value = root.attributes[selector].value
121
- value = parse_type(value, type)
122
-
123
- [name, value]
124
- end
125
- end
126
-
127
- # Parses the value read from xml if the type given responds to the method
128
- # #parse, otherwise returns the string value.
129
- #
130
- # @param value [String]
131
- # @param type [#parse]
132
- def parse_type(value, type)
133
- type.respond_to?(:parse) ? type.parse(value) : value
232
+ def __select(node)
233
+ new.tap {|obj|
234
+ @__selectors.each {|selector|
235
+ obj.singleton_class.send(:define_method, selector.name) {
236
+ selector.match(node)
237
+ }
238
+ }
239
+ }
134
240
  end
135
241
  end
@@ -0,0 +1,57 @@
1
+ module Serialisable
2
+
3
+ # @abstract Must implement #match
4
+ class Selector
5
+ attr_reader :name
6
+
7
+ def initialize(name, selector, type = nil)
8
+ @name = name
9
+ @selector = selector
10
+ @type = type
11
+ end
12
+
13
+ def parse(value)
14
+ if @type.respond_to?(:parse)
15
+ @type.parse(value)
16
+ elsif @type.is_a?(Symbol)
17
+ value.send(@type)
18
+ else
19
+ value
20
+ end
21
+ end
22
+
23
+ class Attribute < Selector
24
+ def match(root)
25
+ parse root.attributes[@selector].value
26
+ end
27
+ end
28
+
29
+ class Node < Selector
30
+ def match(root)
31
+ parse root.children
32
+ .find {|node| node.name == @selector }
33
+ .children.to_s
34
+ end
35
+ end
36
+
37
+ class Nodes < Selector
38
+ def match(root)
39
+ root.children
40
+ .find_all {|node| node.name == @selector }
41
+ .map {|node| parse node.children.to_s }
42
+ end
43
+ end
44
+
45
+ class Nested < Selector
46
+ def match(root)
47
+ @selector.send(:__deserialise, root)
48
+ end
49
+ end
50
+
51
+ class NestedMultiple < Selector
52
+ def match(root)
53
+ @selector.send(:__deserialise_all, root)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module Serialisable
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -0,0 +1,166 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe Serialisable::Selector do
4
+ describe '#name' do
5
+ let(:selector_name) { "some name" }
6
+ subject { Serialisable::Selector.new(selector_name, nil) }
7
+
8
+ it 'returns the name' do
9
+ subject.name.must_equal selector_name
10
+ end
11
+ end
12
+
13
+ describe Serialisable::Selector::Attribute do
14
+ describe '#match' do
15
+ describe 'when type not given' do
16
+ subject { Serialisable::Selector::Attribute.new(nil, 'hey') }
17
+
18
+ let(:xml) { '<el hey="1" what="5"/>' }
19
+ let(:doc) { Nokogiri::XML(xml) }
20
+
21
+ it 'returns the matching attribute' do
22
+ subject.match(doc.children.first).must_equal "1"
23
+ end
24
+ end
25
+
26
+ describe 'when symbol given as type' do
27
+ subject { Serialisable::Selector::Attribute.new(nil, 'hey', :to_i) }
28
+
29
+ let(:xml) { '<el hey="1" what="5"/>' }
30
+ let(:doc) { Nokogiri::XML(xml) }
31
+
32
+ it 'returns the matching attribute' do
33
+ subject.match(doc.children.first).must_equal 1
34
+ end
35
+ end
36
+
37
+ describe 'when object responding to #parse given as type' do
38
+ let(:type) { Class.new { def parse(v); v.to_i; end }.new }
39
+ subject { Serialisable::Selector::Attribute.new(nil, 'hey', type) }
40
+
41
+ let(:xml) { '<el hey="1" what="5"/>' }
42
+ let(:doc) { Nokogiri::XML(xml) }
43
+
44
+ it 'returns the matching attribute' do
45
+ subject.match(doc.children.first).must_equal 1
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ describe Serialisable::Selector::Node do
52
+ describe '#match' do
53
+ describe 'when type not given' do
54
+ subject { Serialisable::Selector::Node.new(nil, 'hey') }
55
+
56
+ let(:xml) { '<el><hey>5</hey><what>6</what></el>' }
57
+ let(:doc) { Nokogiri::XML(xml) }
58
+
59
+ it 'returns the matching node' do
60
+ subject.match(doc.children.first).must_equal "5"
61
+ end
62
+ end
63
+
64
+ describe 'when symbol given as type' do
65
+ subject { Serialisable::Selector::Node.new(nil, 'hey', :to_i) }
66
+
67
+ let(:xml) { '<el><hey>5</hey><what>6</what></el>' }
68
+ let(:doc) { Nokogiri::XML(xml) }
69
+
70
+ it 'returns the matching node' do
71
+ subject.match(doc.children.first).must_equal 5
72
+ end
73
+ end
74
+
75
+ describe 'when object responding to #parse given as type' do
76
+ let(:type) { Class.new { def parse(v); v.to_i; end }.new }
77
+ subject { Serialisable::Selector::Node.new(nil, 'hey', type) }
78
+
79
+ let(:xml) { '<el><hey>5</hey><what>6</what></el>' }
80
+ let(:doc) { Nokogiri::XML(xml) }
81
+
82
+ it 'returns the matching node' do
83
+ subject.match(doc.children.first).must_equal 5
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ describe Serialisable::Selector::Nodes do
90
+ describe '#match' do
91
+ describe 'when no type given' do
92
+ subject { Serialisable::Selector::Nodes.new(nil, 'hey') }
93
+
94
+ let(:xml) { '<el><hey>5</hey><hey>6</hey><what>7</what></el>' }
95
+ let(:doc) { Nokogiri::XML(xml) }
96
+
97
+ it 'returns the matching nodes' do
98
+ subject.match(doc.children.first).must_equal ['5', '6']
99
+ end
100
+ end
101
+
102
+ describe 'when symbol given as type' do
103
+ subject { Serialisable::Selector::Nodes.new(nil, 'hey', :to_i) }
104
+
105
+ let(:xml) { '<el><hey>5</hey><hey>6</hey><what>7</what></el>' }
106
+ let(:doc) { Nokogiri::XML(xml) }
107
+
108
+ it 'returns the matching nodes' do
109
+ subject.match(doc.children.first).must_equal [5, 6]
110
+ end
111
+ end
112
+
113
+ describe 'when object responding to #parse given as type' do
114
+ let(:type) { Class.new { def parse(v); v.to_i; end }.new }
115
+ subject { Serialisable::Selector::Nodes.new(nil, 'hey', type) }
116
+
117
+ let(:xml) { '<el><hey>5</hey><hey>6</hey><what>7</what></el>' }
118
+ let(:doc) { Nokogiri::XML(xml) }
119
+
120
+ it 'returns the matching nodes' do
121
+ subject.match(doc.children.first).must_equal [5, 6]
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ describe Serialisable::Selector::Nested do
128
+ describe '#match' do
129
+ let(:root) { mock }
130
+ let(:nested) { mock }
131
+ let(:parsed) { mock }
132
+ subject { Serialisable::Selector::Nested.new(nil, nested, nil) }
133
+
134
+ before {
135
+ nested
136
+ .expects(:send)
137
+ .with(:__deserialise, root)
138
+ .returns(parsed)
139
+ }
140
+
141
+ it 'calls the private #__deserialise method' do
142
+ subject.match(root).must_equal parsed
143
+ end
144
+ end
145
+ end
146
+
147
+ describe Serialisable::Selector::NestedMultiple do
148
+ describe '#match' do
149
+ let(:root) { mock }
150
+ let(:nested) { mock }
151
+ let(:parsed) { mock }
152
+ subject { Serialisable::Selector::NestedMultiple.new(nil, nested, nil) }
153
+
154
+ before {
155
+ nested
156
+ .expects(:send)
157
+ .with(:__deserialise_all, root)
158
+ .returns(parsed)
159
+ }
160
+
161
+ it 'calls the private #__deserialise_all method' do
162
+ subject.match(root).must_equal parsed
163
+ end
164
+ end
165
+ end
166
+ end
@@ -79,6 +79,44 @@ EOS
79
79
  result.song.name.must_equal '505'
80
80
  end
81
81
  end
82
+
83
+ describe 'with a nested serialisable given a root' do
84
+ subject {
85
+ track = Class.new {
86
+ extend Serialisable
87
+
88
+ root 'track'
89
+ element :artist, 'artist'
90
+ element :name, 'name'
91
+ }
92
+
93
+ Class.new {
94
+ extend Serialisable
95
+
96
+ root 'songs'
97
+ element :song, 'song', track
98
+ }
99
+ }
100
+
101
+ let(:xml) {
102
+ <<EOS
103
+ <?xml version="1.0" encoding="utf-8"?>
104
+ <songs>
105
+ <song>
106
+ <artist>Arctic Monkeys</artist>
107
+ <name>505</name>
108
+ </song>
109
+ </songs>
110
+ EOS
111
+ }
112
+
113
+ it 'deserialises the nested object correctly' do
114
+ result = subject.deserialise(xml)
115
+
116
+ result.song.artist.must_equal 'Arctic Monkeys'
117
+ result.song.name.must_equal '505'
118
+ end
119
+ end
82
120
  end
83
121
 
84
122
  describe '#elements' do
@@ -149,24 +187,51 @@ EOS
149
187
  end
150
188
  end
151
189
 
152
- it 'raises an exception if not given less than two arguments' do
153
- lambda {
154
- Class.new {
190
+ describe 'with a list of nested objects given a root' do
191
+ subject {
192
+ track = Class.new {
155
193
  extend Serialisable
156
194
 
157
- elements :name
195
+ root 'track'
196
+ element :artist, 'artist'
197
+ element :name, 'name'
158
198
  }
159
- }.must_raise ArgumentError
160
- end
161
199
 
162
- it 'raises an exception if given more than three arguments' do
163
- lambda {
164
200
  Class.new {
165
201
  extend Serialisable
166
202
 
167
- elements :name, 'one', 'two', 'three'
203
+ root 'songs'
204
+ elements :songs, 'song', track
168
205
  }
169
- }.must_raise ArgumentError
206
+ }
207
+
208
+ let(:xml) {
209
+ <<EOS
210
+ <?xml version="1.0" encoding="utf-8"?>
211
+ <songs>
212
+ <song>
213
+ <artist>Arctic Monkeys</artist>
214
+ <name>505</name>
215
+ </song>
216
+ <song>
217
+ <artist>Aphex Twin</artist>
218
+ <name>Windowlicker</name>
219
+ </song>
220
+ </songs>
221
+ EOS
222
+ }
223
+
224
+ it 'takes xml and returns an object with a list of nested objects' do
225
+ result = subject.deserialise(xml)
226
+
227
+ result.songs.length.must_equal 2
228
+
229
+ result.songs[0].artist.must_equal 'Arctic Monkeys'
230
+ result.songs[0].name.must_equal '505'
231
+
232
+ result.songs[1].artist.must_equal 'Aphex Twin'
233
+ result.songs[1].name.must_equal 'Windowlicker'
234
+ end
170
235
  end
171
236
  end
172
237
 
@@ -1,4 +1,6 @@
1
1
  require 'minitest/autorun'
2
2
  require 'minitest/pride'
3
3
 
4
+ require 'mocha/setup'
5
+
4
6
  require_relative '../lib/serialisable'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serialisable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hawxwell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-08 00:00:00.000000000 Z
11
+ date: 2014-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.1
19
+ version: '1.6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.1
26
+ version: '1.6'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 5.2.0
33
+ version: '5.2'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 5.2.0
40
+ version: '5.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mocha
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.0.0
47
+ version: '1.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.0.0
54
+ version: '1.0'
55
55
  description: |2
56
56
  Serialisable provides a simple DSL for turning xml into ruby objects.
57
57
  email: m@hawx.me
@@ -61,9 +61,11 @@ extra_rdoc_files: []
61
61
  files:
62
62
  - README.md
63
63
  - Rakefile
64
+ - lib/serialisable/selector.rb
64
65
  - lib/serialisable/version.rb
65
66
  - lib/serialisable.rb
66
67
  - spec/spec_helper.rb
68
+ - spec/serialisable/selector_spec.rb
67
69
  - spec/serialisable_spec.rb
68
70
  homepage: http://github.com/hawx/serialisable
69
71
  licenses:
@@ -91,4 +93,6 @@ specification_version: 4
91
93
  summary: Serialisable allows easy xml deserialisation
92
94
  test_files:
93
95
  - spec/spec_helper.rb
96
+ - spec/serialisable/selector_spec.rb
94
97
  - spec/serialisable_spec.rb
98
+ has_rdoc: