document_builder 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|