document_builder 0.1.2 → 0.2.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 +8 -8
- data/README.md +41 -85
- data/lib/document_builder.rb +3 -2
- data/lib/document_builder/coercion.rb +22 -55
- data/lib/document_builder/collection.rb +23 -38
- data/lib/document_builder/model.rb +52 -9
- data/lib/document_builder/property.rb +23 -0
- data/lib/document_builder/tag.rb +18 -0
- data/lib/document_builder/version.rb +1 -1
- data/spec/document_builder/model_spec.rb +53 -0
- data/spec/fixtures/document.rb +25 -33
- data/spec/integration_spec.rb +5 -2
- metadata +6 -3
- data/lib/document_builder/attribute.rb +0 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZGFkOWQ4NTM0NDI2ZTFiZDk0ZjczODgwYWQ2OWI4YmI4N2FjZDM0Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjkyNGU1MmIwMDZkYTZiZWJhNjg2Njg3MTMxNWVkY2QzOTFiODcxNw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NzRkNzY1YTIyZjg1MzQ3NGVmY2ZjMzEyNjFhYmRlNmFlMjU0YWJmZThlYWRk
|
10
|
+
YmQ4ZTJiMTgwZDhmYzQ1ODJhMjgzZWJmZjg2ODhkNDM3YzU1ZDMzNWI2M2Nh
|
11
|
+
ZjNjMjFiY2IwOWYxNzkxMjgyN2VkNmM3ZTYzNzU4Mzk0ODIyMzc=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
N2Y5MGE1M2IzZTQ5ZjdjMWRjMDIyMzU3MThlNTkxOTIzZDAzNzM1NmY1MzM5
|
14
|
+
MmVkMzE3YTVhYzI1ZDAxNjU2MmVmMTlkYmEzMTcxYzI2MWIwMjY0OWQ4Yjhm
|
15
|
+
NDkyODdmNzMyNGFiNGE2NjI2ZjdmZDZhZGY5M2JiMTE3MWY0ZWE=
|
data/README.md
CHANGED
@@ -27,97 +27,53 @@ Or install it yourself as:
|
|
27
27
|
following example
|
28
28
|
|
29
29
|
```ruby
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
xpath 'category'
|
34
|
-
attribute :domain, 'domain', DocumentBuilder::ElementAttribute
|
35
|
-
attribute :nicename, 'nicename', DocumentBuilder::ElementAttribute
|
36
|
-
attribute :body, nil, DocumentBuilder::ChildAttribute
|
37
|
-
end
|
38
|
-
|
39
|
-
class Postmeta
|
40
|
-
include DocumentBuilder::Model
|
41
|
-
xpath 'postmeta'
|
42
|
-
attribute :key, "wp:meta_key"
|
43
|
-
attribute :value, "wp:meta_value", DocumentBuilder::IntegerAttribute
|
44
|
-
end
|
45
|
-
|
46
|
-
class PostmetaCollection
|
47
|
-
include DocumentBuilder::Collection
|
48
|
-
xpath "item"
|
49
|
-
collection :postmeta, "//wp:postmeta", Postmeta
|
50
|
-
end
|
51
|
-
|
52
|
-
class Post
|
53
|
-
include DocumentBuilder::Model
|
54
|
-
xpath "item"
|
55
|
-
attribute :title
|
56
|
-
attribute :link
|
57
|
-
attribute :pub_date, "pubDate", DocumentBuilder::TimeAttribute
|
58
|
-
attribute :creator, "dc:creator"
|
59
|
-
attribute :content, "content:encoded"
|
60
|
-
attribute :excerpt, "excerpt:encoded"
|
61
|
-
attribute :id, "wp:post_id", DocumentBuilder::IntegerAttribute
|
62
|
-
attribute :published_at, 'wp:post_date_gmt', DocumentBuilder::TimeAttribute
|
63
|
-
attribute :comment_status, "wp:comment_status"
|
64
|
-
attribute :ping_status, "wp:ping_status"
|
65
|
-
attribute :name, 'wp:post_name'
|
66
|
-
attribute :status, "wp:status"
|
67
|
-
attribute :parent, "wp:post_parent", DocumentBuilder::IntegerAttribute
|
68
|
-
attribute :menu_order, "wp:menu_order", DocumentBuilder::IntegerAttribute
|
69
|
-
attribute :type, "wp:post_type"
|
70
|
-
attribute :is_sticky, "wp:is_sticky", DocumentBuilder::IntegerAttribute
|
71
|
-
attribute :category, "category", Category
|
72
|
-
attribute :postmetas, 'item', PostmetaCollection
|
73
|
-
end
|
30
|
+
class ListItem
|
31
|
+
include DocumentBuilder::Model
|
32
|
+
property :name, type: TextProperty
|
74
33
|
end
|
75
34
|
|
76
|
-
|
35
|
+
class SomeDocument
|
36
|
+
include DocumentBuilder::Model
|
37
|
+
root "//root"
|
38
|
+
collection :collection, selector: "//collection//inner-list-item", type: ListItem
|
39
|
+
collection :outer_collection, selector: "outer-list-item", type: ListItem
|
40
|
+
property :property, selector: "//property", type: TextProperty
|
41
|
+
end
|
77
42
|
```
|
78
43
|
|
79
44
|
```ruby
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
"
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
"
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
"
|
108
|
-
"domain": "category",
|
109
|
-
"nicename": "wrxer-news",
|
110
|
-
"body": "Wrxer News"
|
111
|
-
},
|
112
|
-
"postmetas": {
|
113
|
-
"data": "#<Enumerator::Lazy:0x007fa8f315a970>"
|
114
|
-
},
|
115
|
-
"comments": {
|
116
|
-
"data": "#<Enumerator::Lazy:0x007fa8f315a3f8>"
|
117
|
-
}
|
45
|
+
require 'document_builder'
|
46
|
+
require 'nokogiri'
|
47
|
+
|
48
|
+
DOCUMENT = <<-XML
|
49
|
+
<root>
|
50
|
+
<collection>
|
51
|
+
<inner-list-item>Inner Item 1</inner-list-item>
|
52
|
+
<inner-list-item>Inner Item 2</inner-list-item>
|
53
|
+
</collection>
|
54
|
+
<outer-list-item>Outer Item 1</outer-list-item>
|
55
|
+
<outer-list-item>Outer Item 2</outer-list-item>
|
56
|
+
<property>Some Property</property>
|
57
|
+
</root>
|
58
|
+
XML
|
59
|
+
|
60
|
+
document = Nokogiri::XML(DOCUMENT)
|
61
|
+
some_document = SomeDocument.new(document)
|
62
|
+
|
63
|
+
=> #<SomeDocument:0x3fd4799693ac> Attributes: {
|
64
|
+
"collection": [
|
65
|
+
{ "name": "Inner Item 1" },
|
66
|
+
{ "name": "Inner Item 2" }
|
67
|
+
],
|
68
|
+
"outer_collection": [
|
69
|
+
{ "name": "Outer Item 1" },
|
70
|
+
{ "name": "Outer Item 2" }
|
71
|
+
],
|
72
|
+
"property": "Some Property"
|
118
73
|
}
|
119
|
-
|
120
|
-
|
74
|
+
|
75
|
+
some_document.property
|
76
|
+
=> "Some Property"
|
121
77
|
```
|
122
78
|
|
123
79
|
## Contributing
|
data/lib/document_builder.rb
CHANGED
@@ -4,9 +4,10 @@ require 'active_support/time'
|
|
4
4
|
require 'json'
|
5
5
|
|
6
6
|
require 'document_builder/coercion'
|
7
|
-
require 'document_builder/
|
8
|
-
require 'document_builder/model'
|
7
|
+
require 'document_builder/property'
|
9
8
|
require 'document_builder/collection'
|
9
|
+
require 'document_builder/tag'
|
10
|
+
require 'document_builder/model'
|
10
11
|
|
11
12
|
module DocumentBuilder
|
12
13
|
end
|
@@ -1,16 +1,7 @@
|
|
1
1
|
module DocumentBuilder
|
2
2
|
module Coercion
|
3
3
|
module ClassMethods
|
4
|
-
def
|
5
|
-
@xpath = value
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(document, params = {})
|
9
|
-
root = @xpath || params[:xpath]
|
10
|
-
unless document.name == root
|
11
|
-
document = document.at_xpath(root)
|
12
|
-
end
|
13
|
-
|
4
|
+
def call(document)
|
14
5
|
document.nil? ? nil : self.coerce(document)
|
15
6
|
end
|
16
7
|
|
@@ -22,59 +13,35 @@ module DocumentBuilder
|
|
22
13
|
def self.included(base)
|
23
14
|
base.extend(ClassMethods)
|
24
15
|
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class TextAttribute
|
28
|
-
include Coercion
|
29
|
-
def self.coerce(document)
|
30
|
-
document.text
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class IntegerAttribute
|
35
|
-
include Coercion
|
36
|
-
def self.coerce(document)
|
37
|
-
Integer(document.text)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class TimeAttribute
|
42
|
-
include Coercion
|
43
|
-
def self.coerce(document)
|
44
|
-
Time.parse(document.text)
|
45
|
-
end
|
46
|
-
end
|
47
16
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
Time.zone.parse(document.text)
|
17
|
+
class TextProperty
|
18
|
+
include Coercion
|
19
|
+
def self.coerce(document)
|
20
|
+
document.text
|
53
21
|
end
|
54
22
|
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class ElementAttribute
|
58
|
-
include Coercion
|
59
|
-
def self.call(document, params = {})
|
60
|
-
element = document.attributes[params[:xpath].to_s]
|
61
|
-
element.nil? ? nil : self.coerce(element)
|
62
|
-
end
|
63
23
|
|
64
|
-
|
65
|
-
|
24
|
+
class IntegerProperty
|
25
|
+
include Coercion
|
26
|
+
def self.coerce(document)
|
27
|
+
Integer(document.text)
|
28
|
+
end
|
66
29
|
end
|
67
|
-
end
|
68
30
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
31
|
+
class TimeProperty
|
32
|
+
include Coercion
|
33
|
+
def self.coerce(document)
|
34
|
+
Time.parse(document.text)
|
35
|
+
end
|
74
36
|
end
|
75
37
|
|
76
|
-
|
77
|
-
|
38
|
+
class UtcTimeProperty
|
39
|
+
include Coercion
|
40
|
+
def self.coerce(document)
|
41
|
+
Time.use_zone("UTC") do
|
42
|
+
Time.zone.parse(document.text)
|
43
|
+
end
|
44
|
+
end
|
78
45
|
end
|
79
46
|
end
|
80
47
|
end
|
@@ -1,55 +1,40 @@
|
|
1
1
|
module DocumentBuilder
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
document.nil? ? nil : self.coerce(document)
|
11
|
-
end
|
12
|
-
|
13
|
-
def collection(value, xpath, parser)
|
14
|
-
@collection = Attribute.new(value, xpath, parser)
|
15
|
-
end
|
16
|
-
|
17
|
-
def inherited(subclass)
|
18
|
-
subclass.instance_variable_set(:@collection, @collection)
|
19
|
-
super
|
20
|
-
end
|
2
|
+
class Collection
|
3
|
+
include Enumerable
|
4
|
+
attr_reader :name, :selector, :type, :node
|
5
|
+
|
6
|
+
def initialize(name, selector:, type:)
|
7
|
+
@name = name
|
8
|
+
@selector = selector
|
9
|
+
@type = type
|
21
10
|
end
|
22
11
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
include Enumerable
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def collection
|
32
|
-
self.class.instance_variable_get(:@collection)
|
12
|
+
def call(document)
|
13
|
+
return nil if document.nil?
|
14
|
+
@node = document.xpath(selector)
|
15
|
+
self
|
33
16
|
end
|
34
17
|
|
35
|
-
def each
|
36
|
-
|
37
|
-
|
38
|
-
collection.call(item)
|
39
|
-
)
|
18
|
+
def each
|
19
|
+
@node.each do |element|
|
20
|
+
yield type.new(element)
|
40
21
|
end
|
41
22
|
end
|
42
23
|
|
43
|
-
def
|
44
|
-
|
24
|
+
def to_s(*args)
|
25
|
+
JSON.pretty_generate(to_hash)
|
45
26
|
end
|
46
27
|
|
47
28
|
def inspect
|
48
|
-
"#<#{self.class}:0x#{self.object_id.to_s(16)}>
|
29
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}> Attributes: " + JSON.pretty_generate(to_hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json(*args)
|
33
|
+
JSON.generate(to_hash)
|
49
34
|
end
|
50
35
|
|
51
36
|
def to_hash
|
52
|
-
|
37
|
+
entries.map(&:to_hash)
|
53
38
|
end
|
54
39
|
end
|
55
40
|
end
|
@@ -1,23 +1,42 @@
|
|
1
1
|
module DocumentBuilder
|
2
2
|
module Model
|
3
3
|
module ClassMethods
|
4
|
-
def
|
5
|
-
@attributes ||=
|
6
|
-
@attributes
|
4
|
+
def add_attribute(name, attribute)
|
5
|
+
@attributes ||= {}
|
6
|
+
@attributes[name.to_sym] = attribute
|
7
|
+
end
|
8
|
+
|
9
|
+
def property(name, selector: nil, type: nil)
|
10
|
+
add_attribute name, Property.new(name, selector: selector, type: type)
|
11
|
+
end
|
12
|
+
|
13
|
+
def tag(name, selector: nil, type: nil)
|
14
|
+
add_attribute name, Tag.new(name, selector: selector, type: type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def collection(name, selector: nil, type: nil)
|
18
|
+
add_attribute name, Collection.new(name, selector: selector, type: type)
|
19
|
+
end
|
20
|
+
|
21
|
+
def root(selector)
|
22
|
+
@root = selector
|
7
23
|
end
|
8
24
|
|
9
25
|
def inherited(subclass)
|
10
26
|
subclass.instance_variable_set(:@attributes, @attributes)
|
27
|
+
subclass.instance_variable_set(:@root, @root)
|
11
28
|
super
|
12
29
|
end
|
30
|
+
|
31
|
+
def call(document)
|
32
|
+
self.new(document)
|
33
|
+
end
|
13
34
|
end
|
14
35
|
|
15
36
|
def self.included(base)
|
16
37
|
base.extend(ClassMethods)
|
17
38
|
base.class_eval do
|
18
39
|
include Coercion
|
19
|
-
|
20
|
-
attr_reader :document
|
21
40
|
end
|
22
41
|
end
|
23
42
|
|
@@ -25,16 +44,40 @@ module DocumentBuilder
|
|
25
44
|
@document = document
|
26
45
|
end
|
27
46
|
|
47
|
+
def document
|
48
|
+
if root && @document.name != root
|
49
|
+
@document.at_xpath(root)
|
50
|
+
else
|
51
|
+
@document
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def root
|
56
|
+
self.class.instance_variable_get(:@root)
|
57
|
+
end
|
58
|
+
|
28
59
|
def attributes
|
29
60
|
self.class.instance_variable_get(:@attributes)
|
30
61
|
end
|
31
62
|
|
63
|
+
def get_attribute(name)
|
64
|
+
if respond_to?(name)
|
65
|
+
public_send(name)
|
66
|
+
else
|
67
|
+
attributes[name].call(document)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def add_attribute(name, attribute)
|
72
|
+
self.class.add_attribute(name, attribute)
|
73
|
+
end
|
74
|
+
|
32
75
|
def [](key)
|
33
|
-
|
76
|
+
get_attribute(key)
|
34
77
|
end
|
35
78
|
|
36
79
|
def method_missing(name, *args)
|
37
|
-
|
80
|
+
get_attribute(name)
|
38
81
|
rescue NoMethodError => e
|
39
82
|
raise NoMethodError.new("undefined method '#{name}' for #{self.class}")
|
40
83
|
end
|
@@ -53,8 +96,8 @@ module DocumentBuilder
|
|
53
96
|
|
54
97
|
def to_hash
|
55
98
|
attributes.inject({}) do |acc, (key, value)|
|
56
|
-
|
57
|
-
acc[key
|
99
|
+
obj = get_attribute(key)
|
100
|
+
acc[key] = obj.respond_to?(:to_hash) ? obj.to_hash : obj
|
58
101
|
acc
|
59
102
|
end
|
60
103
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DocumentBuilder
|
2
|
+
class Property
|
3
|
+
attr_reader :name, :selector, :type, :node
|
4
|
+
|
5
|
+
def initialize(name, type: nil, selector: nil)
|
6
|
+
@name = name
|
7
|
+
@selector = selector
|
8
|
+
@type = type || Coercion::TextProperty
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(document)
|
12
|
+
return nil if document.nil?
|
13
|
+
|
14
|
+
if selector.nil? || document.name == selector
|
15
|
+
@node = document
|
16
|
+
else
|
17
|
+
@node = document.at_xpath(selector)
|
18
|
+
end
|
19
|
+
|
20
|
+
type.call(@node)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DocumentBuilder
|
2
|
+
class Tag
|
3
|
+
attr_reader :name, :selector, :type, :node
|
4
|
+
|
5
|
+
def initialize(name, type: nil, selector: nil)
|
6
|
+
@name = name
|
7
|
+
@selector = selector
|
8
|
+
@type = type || Coercion::TextProperty
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(document)
|
12
|
+
return nil if document.nil?
|
13
|
+
|
14
|
+
@node = selector.nil? ? document : document.attributes[selector]
|
15
|
+
type.call(@node)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
RSpec.describe DocumentBuilder::Model do
|
5
|
+
DOCUMENT = <<-XML
|
6
|
+
<root>
|
7
|
+
<collection>
|
8
|
+
<inner-list-item>Inner Item 1</inner-list-item>
|
9
|
+
<inner-list-item>Inner Item 2</inner-list-item>
|
10
|
+
</collection>
|
11
|
+
<outer-list-item>Outer Item 1</outer-list-item>
|
12
|
+
<outer-list-item>Outer Item 2</outer-list-item>
|
13
|
+
<property>Some Property</property>
|
14
|
+
</root>
|
15
|
+
XML
|
16
|
+
|
17
|
+
let(:document) { Nokogiri::XML(DOCUMENT) }
|
18
|
+
|
19
|
+
class ListItem
|
20
|
+
include DocumentBuilder::Model
|
21
|
+
property :name, type: TextProperty
|
22
|
+
end
|
23
|
+
|
24
|
+
class SomeDocument
|
25
|
+
include DocumentBuilder::Model
|
26
|
+
root "//root"
|
27
|
+
collection :collection, selector: "//collection//inner-list-item", type: ListItem
|
28
|
+
collection :outer_collection, selector: "outer-list-item", type: ListItem
|
29
|
+
property :property, selector: "//property", type: TextProperty
|
30
|
+
end
|
31
|
+
|
32
|
+
subject { SomeDocument.new(document) }
|
33
|
+
|
34
|
+
it 'returns the root' do
|
35
|
+
expect(subject.root).to eq "//root"
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns an innner collection' do
|
39
|
+
expect(subject.collection).to be_a DocumentBuilder::Collection
|
40
|
+
expect(subject.collection.first).to be_a ListItem
|
41
|
+
expect(subject.collection.first.name).to eq "Inner Item 1"
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns an outer collection' do
|
45
|
+
expect(subject.outer_collection).to be_a DocumentBuilder::Collection
|
46
|
+
expect(subject.outer_collection.first).to be_a ListItem
|
47
|
+
expect(subject.outer_collection.first.name).to eq "Outer Item 1"
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns a property' do
|
51
|
+
expect(subject.property).to eq "Some Property"
|
52
|
+
end
|
53
|
+
end
|
data/spec/fixtures/document.rb
CHANGED
@@ -1,46 +1,38 @@
|
|
1
1
|
module Document
|
2
2
|
class Category
|
3
3
|
include DocumentBuilder::Model
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
attribute :body, nil, DocumentBuilder::ChildAttribute
|
4
|
+
tag :domain, selector: 'domain'
|
5
|
+
tag :nicename, selector: 'nicename'
|
6
|
+
property :body, selector: 'category'
|
8
7
|
end
|
9
8
|
|
10
9
|
class Postmeta
|
11
10
|
include DocumentBuilder::Model
|
12
|
-
|
13
|
-
|
14
|
-
attribute :value, "wp:meta_value", DocumentBuilder::IntegerAttribute
|
15
|
-
end
|
16
|
-
|
17
|
-
class PostmetaCollection
|
18
|
-
include DocumentBuilder::Collection
|
19
|
-
xpath "item"
|
20
|
-
collection :postmeta, "//wp:postmeta", Postmeta
|
11
|
+
property :key, selector: "wp:meta_key"
|
12
|
+
property :value, selector: "wp:meta_value", type: IntegerProperty
|
21
13
|
end
|
22
14
|
|
23
15
|
class Post
|
24
16
|
include DocumentBuilder::Model
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
17
|
+
root "//item"
|
18
|
+
property :title, selector: "title"
|
19
|
+
property :link, selector: "link"
|
20
|
+
property :pub_date, selector: "pubDate", type: UtcTimeProperty
|
21
|
+
property :creator, selector: "dc:creator"
|
22
|
+
property :content, selector: "content:encoded"
|
23
|
+
property :excerpt, selector: "excerpt:encoded"
|
24
|
+
property :id, selector: "wp:post_id", type: IntegerProperty
|
25
|
+
property :post_date, selector: 'wp:post_date', type: TimeProperty
|
26
|
+
property :post_date_gmt, selector: 'wp:post_date_gmt', type: UtcTimeProperty
|
27
|
+
property :comment_status, selector: "wp:comment_status"
|
28
|
+
property :ping_status, selector: "wp:ping_status"
|
29
|
+
property :name, selector: 'wp:post_name'
|
30
|
+
property :status, selector: "wp:status"
|
31
|
+
property :parent, selector: "wp:post_parent", type: IntegerProperty
|
32
|
+
property :menu_order, selector: "wp:menu_order", type: IntegerProperty
|
33
|
+
property :type, selector: "wp:post_type"
|
34
|
+
property :is_sticky, selector: "wp:is_sticky", type: IntegerProperty
|
35
|
+
property :category, selector: "//category", type: Category
|
36
|
+
collection :postmetas, selector: '//wp:postmeta', type: Postmeta
|
45
37
|
end
|
46
38
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -45,6 +45,8 @@ describe Document::Post do
|
|
45
45
|
|
46
46
|
it 'has a category' do
|
47
47
|
expect(subject.category).to be_a Document::Category
|
48
|
+
expect(subject.category.domain).to eq "category"
|
49
|
+
expect(subject.category.body).to eq "Wrxer News"
|
48
50
|
end
|
49
51
|
|
50
52
|
it 'has is_sticky' do
|
@@ -53,6 +55,7 @@ describe Document::Post do
|
|
53
55
|
|
54
56
|
it 'has postmetas' do
|
55
57
|
expect(subject.postmetas.first).to be_a Document::Postmeta
|
58
|
+
expect(subject.postmetas.first.key).to_not eq nil
|
56
59
|
end
|
57
60
|
|
58
61
|
it 'does not have a not foo' do
|
@@ -61,7 +64,7 @@ describe Document::Post do
|
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
64
|
-
context "nil
|
67
|
+
context "nil property case" do
|
65
68
|
let(:filename) { fixture('missing_fields.xml') }
|
66
69
|
let(:document) { Nokogiri::XML(filename.read).xpath('//channel').at_xpath('item')}
|
67
70
|
subject { described_class.call(document) }
|
@@ -85,7 +88,7 @@ describe Document::Post do
|
|
85
88
|
subject { described_class.new(document) }
|
86
89
|
|
87
90
|
it 'returns nil for category' do
|
88
|
-
expect(subject.category).to
|
91
|
+
expect(subject.category).to be_a Document::Category
|
89
92
|
end
|
90
93
|
end
|
91
94
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: document_builder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Schmitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -111,11 +111,13 @@ files:
|
|
111
111
|
- Rakefile
|
112
112
|
- document_builder.gemspec
|
113
113
|
- lib/document_builder.rb
|
114
|
-
- lib/document_builder/attribute.rb
|
115
114
|
- lib/document_builder/coercion.rb
|
116
115
|
- lib/document_builder/collection.rb
|
117
116
|
- lib/document_builder/model.rb
|
117
|
+
- lib/document_builder/property.rb
|
118
|
+
- lib/document_builder/tag.rb
|
118
119
|
- lib/document_builder/version.rb
|
120
|
+
- spec/document_builder/model_spec.rb
|
119
121
|
- spec/document_builder_spec.rb
|
120
122
|
- spec/fixtures/document.rb
|
121
123
|
- spec/fixtures/missing_fields.xml
|
@@ -147,6 +149,7 @@ signing_key:
|
|
147
149
|
specification_version: 4
|
148
150
|
summary: A document builder for nokogiri documents.
|
149
151
|
test_files:
|
152
|
+
- spec/document_builder/model_spec.rb
|
150
153
|
- spec/document_builder_spec.rb
|
151
154
|
- spec/fixtures/document.rb
|
152
155
|
- spec/fixtures/missing_fields.xml
|