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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWNiNzZjNjY4MzVhMmNiNTZmOGRhMWEyODE4ZWZkZjM1MGVkYWZjZQ==
4
+ ZGFkOWQ4NTM0NDI2ZTFiZDk0ZjczODgwYWQ2OWI4YmI4N2FjZDM0Mg==
5
5
  data.tar.gz: !binary |-
6
- Yjk4MTRiZjdjOTk1ZDQ5YjJjMTA3NzUyM2UyZmNjYmQyYTRkMWRkYg==
6
+ NjkyNGU1MmIwMDZkYTZiZWJhNjg2Njg3MTMxNWVkY2QzOTFiODcxNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDg0NjMwZjU4ZWYzMThhOTRmMzQ1MmMyODc4MTQ5YTQwMTJkMGI5MmQyNjQy
10
- MmNlNTk1ZTI5N2EzOWEzZWZjOTc0Yjk2YWRkYTg0YjlkODQ4NzM4NjMzMDRi
11
- NTU4MTU1YzRjN2Q3ZjcxYjBmYTUxMTU5MDU2ZDFkN2E4ZTkwOGU=
9
+ NzRkNzY1YTIyZjg1MzQ3NGVmY2ZjMzEyNjFhYmRlNmFlMjU0YWJmZThlYWRk
10
+ YmQ4ZTJiMTgwZDhmYzQ1ODJhMjgzZWJmZjg2ODhkNDM3YzU1ZDMzNWI2M2Nh
11
+ ZjNjMjFiY2IwOWYxNzkxMjgyN2VkNmM3ZTYzNzU4Mzk0ODIyMzc=
12
12
  data.tar.gz: !binary |-
13
- NWJlMjNhYjEwZTdmMTUyYmU4Y2I2N2U1NzAyZTRmNGQ2ZjBlYzVmYjA1MGZm
14
- ZmRmNjkwYWYzYTllYTgxYWFiOTI5ZTljYzBkZjMwNTY5NTJjYmFkNWIwOTg1
15
- OTdkMGZmMGQ2Zjc1MGI4MWE0YjlhN2E1ZGMzN2E0MTk0MTIwNWE=
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
- module Document
31
- class Category
32
- include DocumentBuilder::Model
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
- ### Using Model Objects
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
- # Read an xml file
81
- url = "https://raw.githubusercontent.com/bullfight/wrxer/master/spec/fixtures/wrx.xml"
82
- uri = URI.parse(url)
83
-
84
- uri.open do |file|
85
- document = Nokogiri::XML(file.read).xpath('//channel').at_xpath('item')}
86
- end
87
-
88
- post = Document::Post.call(document)
89
-
90
- => #<Wrxer::Post:0x3fd4799693ac> Attributes: {
91
- "title": "Welcome To Wrxer News.",
92
- "link": "https://wrxernews.wordpress.com/2007/11/17/welcome-to-wrxer-news/",
93
- "pub_date": "2007-11-17 21:30:51 +0000",
94
- "creator": "wrxernews",
95
- "content": "Welcome to <strong>Wrxer News</strong> - The most up-to-date and reliable source for Wrxer news.",
96
- "excerpt": "Excerpt Text",
97
- "id": 3,
98
- "published_at": "2007-11-17 21:30:51 -0800",
99
- "comment_status": "open",
100
- "ping_status": "open",
101
- "name": "welcome-to-wrxer-news",
102
- "status": "publish",
103
- "parent": 0,
104
- "menu_order": 0,
105
- "type": "post",
106
- "is_sticky": 0,
107
- "category": {
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
- post.title
120
- => "Welcome To Wrxer News."
74
+
75
+ some_document.property
76
+ => "Some Property"
121
77
  ```
122
78
 
123
79
  ## Contributing
@@ -4,9 +4,10 @@ require 'active_support/time'
4
4
  require 'json'
5
5
 
6
6
  require 'document_builder/coercion'
7
- require 'document_builder/attribute'
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 xpath(value)
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
- class UtcTimeAttribute
49
- include Coercion
50
- def self.coerce(document)
51
- Time.use_zone("UTC") do
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
- def self.coerce(document)
65
- document.value
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
- class ChildAttribute
70
- include Coercion
71
- def self.call(document, params = {})
72
- child = document.children
73
- child.empty? ? nil : self.coerce(child)
31
+ class TimeProperty
32
+ include Coercion
33
+ def self.coerce(document)
34
+ Time.parse(document.text)
35
+ end
74
36
  end
75
37
 
76
- def self.coerce(document)
77
- document.text
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
- module Collection
3
- module ClassMethods
4
- def call(document, params = {})
5
- root = @xpath || params[:xpath]
6
- unless document.name == root
7
- document = document.xpath(root)
8
- end
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 self.included(base)
24
- base.extend(ClassMethods)
25
- base.class_eval do
26
- include Model
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(&block)
36
- document.xpath(collection.xpath).each do |item|
37
- block.call(
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 data
44
- lazy
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)}> { data: #{data} } }"
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
- { data: data }
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 attribute(name, xpath = nil, coercion = TextAttribute)
5
- @attributes ||= []
6
- @attributes << Attribute.new(name, xpath || name.to_s, coercion)
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
- attributes.select { |item| item.name == key.to_sym}.first.call(document)
76
+ get_attribute(key)
34
77
  end
35
78
 
36
79
  def method_missing(name, *args)
37
- attributes.select { |item| item.name == name }.first.call(document)
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
- value = key.call(document)
57
- acc[key.name] = value.respond_to?(:to_hash) ? value.to_hash : value
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
@@ -1,3 +1,3 @@
1
1
  module DocumentBuilder
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  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
@@ -1,46 +1,38 @@
1
1
  module Document
2
2
  class Category
3
3
  include DocumentBuilder::Model
4
- xpath 'category'
5
- attribute :domain, 'domain', DocumentBuilder::ElementAttribute
6
- attribute :nicename, 'nicename', DocumentBuilder::ElementAttribute
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
- xpath 'postmeta'
13
- attribute :key, "wp:meta_key"
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
- xpath "item"
26
- attribute :title
27
- attribute :link
28
- attribute :pub_date, "pubDate", DocumentBuilder::UtcTimeAttribute
29
- attribute :creator, "dc:creator"
30
- attribute :content, "content:encoded"
31
- attribute :excerpt, "excerpt:encoded"
32
- attribute :id, "wp:post_id", DocumentBuilder::IntegerAttribute
33
- attribute :post_date, 'wp:post_date', DocumentBuilder::TimeAttribute
34
- attribute :post_date_gmt, 'wp:post_date_gmt', DocumentBuilder::UtcTimeAttribute
35
- attribute :comment_status, "wp:comment_status"
36
- attribute :ping_status, "wp:ping_status"
37
- attribute :name, 'wp:post_name'
38
- attribute :status, "wp:status"
39
- attribute :parent, "wp:post_parent", DocumentBuilder::IntegerAttribute
40
- attribute :menu_order, "wp:menu_order", DocumentBuilder::IntegerAttribute
41
- attribute :type, "wp:post_type"
42
- attribute :is_sticky, "wp:is_sticky", DocumentBuilder::IntegerAttribute
43
- attribute :category, "category", Category
44
- attribute :postmetas, 'item', PostmetaCollection
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
@@ -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 attribute case" do
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 eq nil
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.1.2
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-04-09 00:00:00.000000000 Z
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
@@ -1,7 +0,0 @@
1
- module DocumentBuilder
2
- class Attribute < Struct.new(:name, :xpath, :coercion)
3
- def call(document, params = {})
4
- coercion.call(document, { xpath: xpath })
5
- end
6
- end
7
- end