xml_dsl 0.3.1 → 0.3.2

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: 8039a8956aa2ed81f448ceb371bf92523f9f1a3c
4
- data.tar.gz: 5d8486f335d6a3fc412ce09ebe312a6738b187fe
3
+ metadata.gz: a06859b2ea2ebab29cd30ca0dd451005459ed911
4
+ data.tar.gz: 476df9143b24ecc659d2751d06d4b315216394c5
5
5
  SHA512:
6
- metadata.gz: f24e74b53fb2e66b325c032c749ff1795a6268fbc79f1ad2cb9a0c0c392266d774027ab0cb6d5a4b86951813b52d3f6cc8ea87720b57714dd29f4cf7787178e0
7
- data.tar.gz: 3981133746da9191c4b25555f65915257a3204772204a1289efb52e77e10e2f96d075b1e264a3d1721ced396bae67cd0c754e9c64fd041a97872e99fbdf69dc3
6
+ metadata.gz: 8803eeda3e875094fb8a52fed5bf224b5fd0b9f3eebf94f7c6f9632fa8d5be086871bc3e14a05872c0d19795ca6c804662cc98fde2f79fd75554c3db86384343
7
+ data.tar.gz: 20d55686eebf557caefd68da858ffd8215c1105ae8d53d9231d0d48309402a6cdb469313d58010f047b13d6667a7c28802ab485844b33f26c228a66316667950
data/README.md CHANGED
@@ -70,6 +70,16 @@ Then we can define our mapper as following
70
70
  # any length of root path can be provided
71
71
  define_xml_parser Hash, :root, :offer do
72
72
 
73
+ # Here is basic validation blocks
74
+ # They MUST return some bool (if block)
75
+ before_parse? do |node|
76
+ !node.search('magick').empty?
77
+ end
78
+
79
+ # Or just check for must_have key (or path to it)
80
+ before_parse? :jim
81
+ before_parse? [:areas, 'area[type=hobby]']
82
+
73
83
  # We can define a block to call every time an XmlDsl::ParseError os raised
74
84
  # it is raised if null: true is passed to field declaration, or manually via raise XmlDsl::ParseError
75
85
  error_handle do |e, node|
@@ -100,10 +110,28 @@ Then we can define our mapper as following
100
110
  0
101
111
  end
102
112
  end
113
+
114
+ # If something goes wrong - just raise XmlDsl::ParseError manually
115
+ field :fuu do |_, node|
116
+ raise XmlDsl::ParseError, 'FUUU' if node.search(:areas).length > 5
117
+ end
103
118
  end
104
119
  end
105
120
  ```
106
121
 
122
+ Then you can use your newly defined parser as you wish:
123
+ ```
124
+ parser = Parser.new(nifty_xml, some_logger_eg)
125
+
126
+ # just iterate with block
127
+ parser.iterate do |instance|
128
+ do_stuff_with_newly_mapped_instance_whatever(instance)
129
+ end
130
+
131
+ # or you can pass some accumulator for your instances to be put into
132
+ parser.iterate acc: []
133
+ ```
134
+
107
135
  ## Contributing
108
136
 
109
137
  Feel free to request for some features or fork - implement - pul request.
@@ -7,11 +7,11 @@ module XmlDsl
7
7
  @block = block if block_given?
8
8
  end
9
9
 
10
- def call(instance, node, parser)
10
+ def call(a, b = nil, c = nil)
11
11
  if block
12
- self.send method, *[instance, node, parser] + args, &block
12
+ self.send method, *[a, b, c].compact + args, &block
13
13
  else
14
- self.send method, *[instance, node, parser] + args
14
+ self.send method, *[a, b, c].compact + args
15
15
  end
16
16
  end
17
17
 
@@ -21,15 +21,7 @@ module XmlDsl
21
21
  instance[target] = parser.instance_exec instance, node, &block
22
22
  else
23
23
  raise ArgumentError, 'No source specified' if source.nil?
24
- source = case [source.class]
25
- when [Symbol]
26
- source.to_s
27
- when [Array]
28
- source.join('/')
29
- else
30
- source.to_s
31
- end
32
- instance[target] = node.search(source).send(getter).send(matcher)
24
+ instance[target] = node.search(convert_source(source)).send(getter).send(matcher)
33
25
  end
34
26
  if null
35
27
  raise XmlDsl::ParseError, "#{target} is empty. Node: #{node}" if instance[target].nil? || instance[target] == ""
@@ -39,5 +31,26 @@ module XmlDsl
39
31
  def error_handle(exception, node, parser, &block)
40
32
  parser.instance_exec exception, node, &block
41
33
  end
34
+
35
+ def before_parse?(node, parser, key = nil, &block)
36
+ if block_given?
37
+ parser.instance_exec node, &block
38
+ else
39
+ raise ArgumentError, 'Key to check is nil' if key.nil?
40
+ !node.search(convert_source(key)).empty?
41
+ end
42
+ end
43
+
44
+ private
45
+ def convert_source(source)
46
+ case [source.class]
47
+ when [Symbol]
48
+ source.to_s
49
+ when [Array]
50
+ source.join('/')
51
+ else
52
+ source.to_s
53
+ end
54
+ end
42
55
  end
43
56
  end
@@ -23,6 +23,11 @@ module XmlDsl
23
23
  raise ArgumentError, "If there is no @xml in parser, pass it to iterate" if xml_obj.nil?
24
24
  xml_obj.search(_xml_root_path).each do |node|
25
25
  begin
26
+ valid = _xml_parse_callbacks[:before_parsers].map do |bm|
27
+ bm.call node, self
28
+ end.reduce(true, :&)
29
+ next unless valid
30
+ # mapping
26
31
  instance = _xml_target_class.new
27
32
  _xml_parse_callbacks[:readers].each do |bm|
28
33
  bm.call instance, node, self
@@ -1,3 +1,3 @@
1
1
  module XmlDsl
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -28,14 +28,27 @@ module XmlDsl
28
28
  @owner.instance_variable_set :@xml_parser, self
29
29
  end
30
30
 
31
+ # Field for parse definition
32
+ # receives args: target, source = nil, getter: :text, matcher: :to_s, null: false
33
+ # or block with |instance, node|
31
34
  def field(*args, &block)
32
35
  callbacks[:readers] << XmlDsl::BlockMethod.new(:field, *args, &block)
33
36
  end
34
37
 
38
+ # Error handler for automatic or manually raised XmlDsl::ParseError exceptions
39
+ # receives block with two args error and node, that caused the error to occur
40
+ # block with |exception, node|
35
41
  def error_handle(*args, &block)
36
42
  callbacks[:error_handlers] << XmlDsl::BlockMethod.new(:error_handle, *args, &block)
37
43
  end
38
44
 
45
+ # Validation like block
46
+ # receives key: symbol, string, or array of similar
47
+ # returns bool if true - normal, false - skip this node
48
+ def before_parse?(*args, &block)
49
+ callbacks[:before_parsers] << XmlDsl::BlockMethod.new(:before_parse?, *args, &block)
50
+ end
51
+
39
52
  def setup_parser_instance(instance)
40
53
  state_lock.synchronize do
41
54
  instance.instance_variable_set :@_xml_root_path, root_path
@@ -35,7 +35,9 @@
35
35
  <area type="total">30</area>
36
36
  <area type="live">17</area>
37
37
  <area type="kitchen">7</area>
38
+ <area type="hobby">42</area>
38
39
  </areas>
39
40
  <magick>woodoo</magick>
41
+ <jim>Jarmush</jim>
40
42
  </offer>
41
43
  </root>
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'support/xml'
3
3
 
4
4
  describe 'Example Xml Mapper Spec' do
5
- context 'normal parser' do
5
+ context 'basic parser' do
6
6
  before(:each) do
7
7
  clazz = Class.new
8
8
  clazz.class_eval do
@@ -100,6 +100,37 @@ describe 'Example Xml Mapper Spec' do
100
100
  expect(@external_obj).to receive(:notify).with(kind_of(Nokogiri::XML::Element)).once
101
101
  @parser.iterate
102
102
  end
103
+ end
104
+
105
+ context 'Parser with before_parse validation (good)' do
106
+ before(:each) do
107
+ clazz = Class.new
108
+ @external_obj = double
109
+ clazz.class_eval do
110
+ attr_accessor :xml, :external
111
+ def initialize(xml, external)
112
+ self.xml = xml
113
+ self.external = external
114
+ end
115
+
116
+ define_xml_parser Hash, :root, :offer do
117
+
118
+ before_parse? do |node|
119
+ !node.search('magick').empty?
120
+ end
121
+
122
+ before_parse? :jim
123
+ before_parse? [:areas, 'area[type=hobby]']
124
+
125
+ field :id, :id, matcher: :to_i
126
+ field :minutes, :distance, matcher: :to_i
127
+ end
128
+ end
129
+ @parser = clazz.new some_xml, @external_obj
130
+ end
103
131
 
132
+ it 'returns only one object' do
133
+ expect(@parser.iterate(acc:[]).length).to eql(1)
134
+ end
104
135
  end
105
136
  end
@@ -52,6 +52,10 @@ describe XmlDsl do
52
52
  expect { in_definition { error_handle } }.to change(xml_parser.callbacks[:error_handlers], :length).by(1)
53
53
  end
54
54
 
55
+ it 'defining before_parse is put inside before_parsers' do
56
+ expect { in_definition { before_parse? {} } }.to change(xml_parser.callbacks[:before_parsers], :length).by(1)
57
+ end
58
+
55
59
  def in_definition(&block)
56
60
  xml_parser.instance_eval &block
57
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xml_dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladislav Bogomolov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-17 00:00:00.000000000 Z
11
+ date: 2014-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri