saxy 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e902b0cd867994419869833857f4c96bb6427f17
4
- data.tar.gz: f4e5babf7a86675953869fbec446404fceb9ea0a
3
+ metadata.gz: 7aece0820f9857b94f42d54164325ea667652065
4
+ data.tar.gz: 3c98297e4859dd500d6ec283a164e694119943fb
5
5
  SHA512:
6
- metadata.gz: aebfd829d32a73141a4c289cc4f557ed6c2c647248b659bbc037d9bca1e58196394dd42c9439841262062c29dfb49af953ce7e9cde99179d9ce5e1be2c87962d
7
- data.tar.gz: c3d2f658bae270cc76da97881037fb598eb2b254760f349c304fc6943409c9fa1913d2cb65d3bada50c223354e49eed2a4183b5869f7d8b0c7a1debadfc08954
6
+ metadata.gz: 1cd890ce2423a1b7e19f7a5350e49d04b2863a1e0b03940a996aa33a9d998e5aa238b05200af20dc7466c9337269c260dd03ba7157ca9d8a16170248352b4fe0
7
+ data.tar.gz: 9d24f74bbd19185bfab0c164652c845befaf7be740264a21f32ecb979e7a6530d6c5ca7f077d57c8c408f5ba475c4bb183eee2bb3db0a0c57d4c8d81ea2c380f
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2012-2014 Monterail.com LLC
3
+ Copyright (c) 2012-2016 Humante LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,12 +1,14 @@
1
1
  # Saxy
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/saxy.svg)](https://badge.fury.io/rb/saxy)
4
- [![Build Status](https://api.travis-ci.org/monterail/saxy.svg)](http://travis-ci.org/monterail/saxy)
4
+ [![Build Status](https://api.travis-ci.org/humante/saxy.svg)](http://travis-ci.org/humante/saxy)
5
5
 
6
6
  Memory-efficient XML parser. Finds object definitions in XML and translates them into Ruby objects.
7
7
 
8
8
  It uses SAX parser under the hood, which means that it doesn't load the whole XML file into memory. It goes once through it and yields objects along the way.
9
9
 
10
+ In result the memory footprint of the parser remains small and more or less constant irrespective of the size of the XML file, be it few KB or hundreds of GB.
11
+
10
12
  ## Installation
11
13
 
12
14
  Add this line to your application's Gemfile:
@@ -40,71 +42,82 @@ See `ruby-1.9.2` branch. Install with:
40
42
 
41
43
  Assume the XML file:
42
44
 
43
- <?xml version='1.0' encoding='UTF-8'?>
44
- <webstore>
45
- <name>Amazon</name>
46
- <products>
47
- <product>
48
- <name>Kindle - The world's best-selling e-reader.</name>
49
- <images>
50
- <thumbSize width="80" height="60">http://amazon.com/kindle_thumb.jpg</thumbSize>
51
- </images>
52
- </product>
53
- <product>
54
- <name>Kindle Touch - Simple-to-use touchscreen with built-in WIFI.</name>
55
- <images>
56
- <thumbSize width="120" height="90">http://amazon.com/kindle_touch_thumb.jpg</thumbSize>
57
- </images>
58
- </product>
59
- </products>
60
- </webstore>
45
+ ````xml
46
+ <?xml version='1.0' encoding='UTF-8'?>
47
+ <webstore>
48
+ <name>Amazon</name>
49
+ <products>
50
+ <product>
51
+ <name>Kindle - The world's best-selling e-reader.</name>
52
+ <images>
53
+ <thumbSize width="80" height="60">http://amazon.com/kindle_thumb.jpg</thumbSize>
54
+ </images>
55
+ </product>
56
+ <product>
57
+ <name>Kindle Touch - Simple-to-use touchscreen with built-in WIFI.</name>
58
+ <images>
59
+ <thumbSize width="120" height="90">http://amazon.com/kindle_touch_thumb.jpg</thumbSize>
60
+ </images>
61
+ </product>
62
+ </products>
63
+ </webstore>
64
+ ````
61
65
 
62
66
  You instantiate the parser by passing path to XML file or an IO-like object and object-identyfing tag name as its arguments.
63
67
 
64
- The following will parse the XML, find product definitions (inside `<product>` and `</product>` tags), build `Hash`s and yield them inside the block.
65
- Tag attributes become object attributes and attributes' name are underscored.
68
+ The following will parse the XML, find product definitions (inside `<product>` and `</product>` tags), build `Hash`es and yield them inside the block.
66
69
 
67
70
  Usage with a file path:
68
71
 
69
- Saxy.parse("filename.xml", "product").each do |product|
70
- puts product[:name]
71
- puts product[:images][:thumb_size][:contents]
72
- puts "#{product[:images][:thumb_size][:width]}x#{product[:images][:thumb_size][:height]}"
73
- end
74
-
75
- # =>
76
- Kindle - The world's best-selling e-reader.
77
- http://amazon.com/kindle_thumb.jpg
78
- 80x60
79
- Kindle Touch - Simple-to-use touchscreen with built-in WIFI.
80
- http://amazon.com/kindle_touch_thumb.jpg
81
- 120x90
82
-
83
- Usage with an IO-like object `ARGF`:
84
-
85
- # > cat filename.xml | ruby this_script.rb
86
- Saxy.parse(ARGF, "product").each do |product|
87
- puts product.name
88
- end
89
-
90
- # =>
91
- Kindle - The world's best-selling e-reader.
72
+ ````ruby
73
+ Saxy.parse("filename.xml", "product").each do |product|
74
+ puts product[:name]
75
+ puts product[:images][:thumb_size][:contents]
76
+ puts "#{product[:images][:thumb_size][:width]}x#{product[:images][:thumb_size][:height]}"
77
+ end
78
+
79
+ # =>
80
+ "Kindle - The world's best-selling e-reader."
81
+ "http://amazon.com/kindle_thumb.jpg"
82
+ "80x60"
83
+ "Kindle Touch - Simple-to-use touchscreen with built-in WIFI."
84
+ "http://amazon.com/kindle_touch_thumb.jpg"
85
+ "120x90"
86
+ ````
87
+
88
+ Usage with an IO-like object `ARGF` or `$stdin`:
89
+
90
+ ````ruby
91
+ # > cat filename.xml | ruby this_script.rb
92
+ Saxy.parse(ARGF, "product").each do |product|
93
+ puts product.name
94
+ end
95
+
96
+ # =>
97
+ "Kindle - The world's best-selling e-reader."
98
+ ````
92
99
 
93
100
  Saxy supports Enumerable, so you can use its goodies to your comfort without building intermediate arrays:
94
101
 
95
- Saxy.parse("filename.xml", "product").map do |object|
96
- # map yielded Hash to ActiveRecord instances, etc.
97
- end
102
+ ````ruby
103
+ Saxy.parse("filename.xml", "product").map do |object|
104
+ # map yielded Hash to ActiveRecord instances, etc.
105
+ end
106
+ ````
98
107
 
99
108
  You can also grab an Enumerator for external use (e.g. lazy evaluation, etc.):
100
109
 
101
- enumerator = Saxy.parse("filename.xml", "product").each
102
- lazy = Saxy.parse("filename.xml", "product").lazy # Ruby 2.0
110
+ ````ruby
111
+ enumerator = Saxy.parse("filename.xml", "product").each
112
+ lazy = Saxy.parse("filename.xml", "product").lazy # Ruby 2.0
113
+ ````
103
114
 
104
115
  Multiple definitions of child objects are grouped in arrays:
105
116
 
106
- webstore = Saxy.parse("filename.xml", "webstore").first
107
- webstore[:products][:product].size # => 2
117
+ ````ruby
118
+ webstore = Saxy.parse("filename.xml", "webstore").first
119
+ webstore[:products][:product].size # => 2
120
+ ````
108
121
 
109
122
  ## Contributing
110
123
 
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/string/inflections'
2
-
3
1
  module Saxy
4
2
  class Element
5
3
  attr_reader :attributes, :value
@@ -33,7 +31,18 @@ module Saxy
33
31
  end
34
32
 
35
33
  def attribute_name(name)
36
- name.underscore.to_sym
34
+ underscore(name).to_sym
35
+ end
36
+
37
+ private
38
+
39
+ def underscore(word)
40
+ word = word.dup
41
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
42
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
43
+ word.tr!("-", "_")
44
+ word.downcase!
45
+ word
37
46
  end
38
47
  end
39
48
  end
@@ -1,3 +1,3 @@
1
1
  module Saxy
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
6
6
  gem.email = ["michal.szajbe@gmail.com"]
7
7
  gem.description = %q{Saxy finds object definitions in XML files and translates them into Ruby objects. It uses SAX parser under the hood, which means that it doesn't load the whole XML file into memory. It goes once though it and yields objects along the way.}
8
8
  gem.summary = %q{Memory-efficient XML parser. Finds object definitions and translates them into Ruby objects.}
9
- gem.homepage = "http://github.com/monterail/saxy"
9
+ gem.homepage = "http://github.com/humante/saxy"
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.required_ruby_version = ">= 1.9.3"
19
19
 
20
- gem.add_dependency "activesupport"
21
20
  gem.add_dependency "nokogiri"
21
+
22
22
  gem.add_development_dependency "rspec"
23
23
  end
@@ -5,26 +5,26 @@ describe Saxy::Element do
5
5
 
6
6
  it "should not append empty string as value" do
7
7
  element.append_value("")
8
- element.value.should be_nil
8
+ expect(element.value).to be_nil
9
9
  end
10
10
 
11
11
  it "should append stripped value" do
12
12
  element.append_value(" foo ")
13
13
  element.append_value(" bar ")
14
- element.value.should == "foobar"
14
+ expect(element.value).to eq("foobar")
15
15
  end
16
16
 
17
17
  it "should dump as string when no attributes are set" do
18
- element.stub(:value).and_return("foo")
19
- element.to_h.should == "foo"
18
+ expect(element).to receive(:value).and_return("foo")
19
+ expect(element.to_h).to eq("foo")
20
20
  end
21
21
 
22
22
  it "should dump as object when attributes are set" do
23
- element.stub(:attributes).and_return("foo" => 1, "bar" => 2)
23
+ expect(element).to receive(:attributes).at_least(:once).and_return("foo" => 1, "bar" => 2)
24
24
  object = element.to_h
25
25
 
26
- object[:foo].should == 1
27
- object[:bar].should == 2
26
+ expect(object[:foo]).to eq(1)
27
+ expect(object[:bar]).to eq(2)
28
28
  end
29
29
 
30
30
  it "should dump as object with value when attributes and contents are set" do
@@ -32,18 +32,18 @@ describe Saxy::Element do
32
32
  element.append_value("value")
33
33
  object = element.to_h
34
34
 
35
- object[:foo].should == "bar"
36
- object[:contents].should == "value"
35
+ expect(object[:foo]).to eq("bar")
36
+ expect(object[:contents]).to eq("value")
37
37
  end
38
38
 
39
39
  it "should add attributes under underscored names" do
40
40
  element.set_attribute("FooBar", "baz")
41
- element.to_h[:foo_bar].should == "baz"
41
+ expect(element.to_h[:foo_bar]).to eq("baz")
42
42
  end
43
43
 
44
44
  it "should create array if adding multiple attributtes with the same name" do
45
45
  element.set_attribute("foo", "bar")
46
46
  element.set_attribute("foo", "baz")
47
- element.to_h[:foo].should == ["bar", "baz"]
47
+ expect(element.to_h[:foo]).to eq(["bar", "baz"])
48
48
  end
49
49
  end
@@ -10,43 +10,43 @@ describe Saxy::Parser do
10
10
  it "should accept string filename for parsing" do
11
11
  xml_file = fixture_file("webstore.xml")
12
12
  parser = Saxy::Parser.new(xml_file, "product")
13
- parser.each.to_a.size.should == 2
13
+ expect(parser.each.to_a.size).to eq(2)
14
14
  end
15
15
 
16
16
  it "should accept IO for parsing" do
17
17
  parser = Saxy::Parser.new(file_io, "product")
18
- parser.each.to_a.size.should == 2
18
+ expect(parser.each.to_a.size).to eq(2)
19
19
  end
20
20
 
21
21
  it "should accept an IO-like for parsing" do
22
22
  parser = Saxy::Parser.new(io_like, "product")
23
- parser.each.to_a.size.should == 2
23
+ expect(parser.each.to_a.size).to eq(2)
24
24
  end
25
25
 
26
26
  it "should have empty tag stack" do
27
- parser.tags.should == %w( )
27
+ expect(parser.tags).to eq(%w( ))
28
28
  end
29
29
 
30
30
  it "should push/pop tag names on/from tag stack when going down/up the XML tree" do
31
- parser.tags.should == %w( )
31
+ expect(parser.tags).to eq(%w( ))
32
32
 
33
33
  parser.start_element('webstore')
34
- parser.tags.should == %w( webstore )
34
+ expect(parser.tags).to eq(%w( webstore ))
35
35
 
36
36
  parser.start_element('products')
37
- parser.tags.should == %w( webstore products )
37
+ expect(parser.tags).to eq(%w( webstore products ))
38
38
 
39
39
  parser.start_element('product')
40
- parser.tags.should == %w( webstore products product )
40
+ expect(parser.tags).to eq(%w( webstore products product ))
41
41
 
42
42
  parser.end_element('product')
43
- parser.tags.should == %w( webstore products )
43
+ expect(parser.tags).to eq(%w( webstore products ))
44
44
 
45
45
  parser.end_element('products')
46
- parser.tags.should == %w( webstore )
46
+ expect(parser.tags).to eq(%w( webstore ))
47
47
 
48
48
  parser.end_element('webstore')
49
- parser.tags.should == %w( )
49
+ expect(parser.tags).to eq(%w( ))
50
50
  end
51
51
 
52
52
  context "when detecting object tag opening" do
@@ -55,7 +55,7 @@ describe Saxy::Parser do
55
55
  end
56
56
 
57
57
  it "should add new element to stack" do
58
- parser.elements.size.should == 1
58
+ expect(parser.elements.size).to eq(1)
59
59
  end
60
60
  end
61
61
 
@@ -65,14 +65,14 @@ describe Saxy::Parser do
65
65
  end
66
66
 
67
67
  it "should not add new element to stack" do
68
- parser.elements.should be_empty
68
+ expect(parser.elements).to be_empty
69
69
  end
70
70
  end
71
71
 
72
72
  context "with non-empty element stack" do
73
73
  before do
74
74
  parser.start_element("product")
75
- parser.elements.should_not be_empty
75
+ expect(parser.elements).to_not be_empty
76
76
  end
77
77
 
78
78
  context "when detecting object tag opening" do
@@ -81,7 +81,7 @@ describe Saxy::Parser do
81
81
  end
82
82
 
83
83
  it "should add new element to stack" do
84
- parser.elements.size.should == 2
84
+ expect(parser.elements.size).to eq(2)
85
85
  end
86
86
  end
87
87
 
@@ -91,7 +91,7 @@ describe Saxy::Parser do
91
91
  end
92
92
 
93
93
  it "should not add new element to stack" do
94
- parser.elements.size.should == 2
94
+ expect(parser.elements.size).to eq(2)
95
95
  end
96
96
  end
97
97
 
@@ -101,36 +101,36 @@ describe Saxy::Parser do
101
101
  end
102
102
 
103
103
  it "should pop element from stack" do
104
- parser.elements.should be_empty
104
+ expect(parser.elements).to be_empty
105
105
  end
106
106
  end
107
107
 
108
108
  context "with callback defined" do
109
109
  before do
110
110
  @callback = lambda { |object| object }
111
- parser.stub(:callback).and_return(@callback)
111
+ allow(parser).to receive(:callback).and_return(@callback)
112
112
  end
113
113
 
114
114
  it "should yield the object inside the callback after detecting object tag closing" do
115
- @callback.should_receive(:call).with(parser.current_element.to_h)
115
+ expect(@callback).to receive(:call).with(parser.current_element.to_h)
116
116
  parser.end_element("product")
117
117
  end
118
118
 
119
119
  it "should not yield the object inside the callback after detecting other tag closing" do
120
120
  parser.start_element("other")
121
- @callback.should_not_receive(:call)
121
+ expect(@callback).to_not receive(:call)
122
122
  parser.end_element("other")
123
123
  end
124
124
  end
125
125
 
126
126
  it "should append cdata block's contents to top element's value when detecting cdata block" do
127
- parser.current_element.should_receive(:append_value).with("foo")
127
+ expect(parser.current_element).to receive(:append_value).with("foo")
128
128
  parser.cdata_block("foo")
129
129
  end
130
130
 
131
131
  it "should append characters to top element's value when detecting characters block" do
132
- parser.current_element.should_receive(:append_value).with("foo")
133
- parser.current_element.should_receive(:append_value).with("bar")
132
+ expect(parser.current_element).to receive(:append_value).with("foo")
133
+ expect(parser.current_element).to receive(:append_value).with("bar")
134
134
  parser.characters("foo")
135
135
  parser.characters("bar")
136
136
  end
@@ -138,7 +138,7 @@ describe Saxy::Parser do
138
138
  it "should set element's attribute after processing tags" do
139
139
  element = parser.current_element
140
140
 
141
- element.should_receive(:set_attribute).with("foo", "bar")
141
+ expect(element).to receive(:set_attribute).with("foo", "bar")
142
142
 
143
143
  parser.start_element("foo")
144
144
  parser.characters("bar")
@@ -147,16 +147,16 @@ describe Saxy::Parser do
147
147
 
148
148
  it "should set element's attributes when opening tag with attributes" do
149
149
  parser.start_element("foo", [["bar", "baz"]])
150
- parser.current_element.to_h[:bar].should == "baz"
150
+ expect(parser.current_element.to_h[:bar]).to eq("baz")
151
151
  end
152
152
  end
153
153
 
154
154
  it "should raise Saxy::ParsingError on error" do
155
- lambda { parser.error("Error message.") }.should raise_error(Saxy::ParsingError, "Error message.")
155
+ expect { parser.error("Error message.") }.to raise_error(Saxy::ParsingError, "Error message.")
156
156
  end
157
157
 
158
158
  it "should return Enumerator when calling #each without a block" do
159
- parser.each.should be_instance_of Enumerator
159
+ expect(parser.each).to be_an(Enumerator)
160
160
  end
161
161
 
162
162
  end
@@ -9,29 +9,29 @@ describe Saxy do
9
9
  arr
10
10
  end
11
11
 
12
- products[0][:uid].should == "FFCF177"
13
- products[0][:name].should == "Kindle"
14
- products[0][:description].should == "The world's best-selling e-reader."
15
- products[0][:price].should == "$109"
16
- products[0][:images][:thumb].should == "http://amazon.com/kindle_thumb.jpg"
17
- products[0][:images][:large].should == "http://amazon.com/kindle.jpg"
12
+ expect(products[0][:uid]).to eq("FFCF177")
13
+ expect(products[0][:name]).to eq("Kindle")
14
+ expect(products[0][:description]).to eq("The world's best-selling e-reader.")
15
+ expect(products[0][:price]).to eq("$109")
16
+ expect(products[0][:images][:thumb]).to eq("http://amazon.com/kindle_thumb.jpg")
17
+ expect(products[0][:images][:large]).to eq("http://amazon.com/kindle.jpg")
18
18
 
19
- products[1][:uid].should == "YD26NT"
20
- products[1][:name].should == "Kindle Touch"
21
- products[1][:description].should == "Simple-to-use touchscreen with built-in WIFI."
22
- products[1][:price].should == "$79"
23
- products[1][:images][:thumb].should == "http://amazon.com/kindle_touch_thumb.jpg"
24
- products[1][:images][:large].should == "http://amazon.com/kindle_touch.jpg"
19
+ expect(products[1][:uid]).to eq("YD26NT")
20
+ expect(products[1][:name]).to eq("Kindle Touch")
21
+ expect(products[1][:description]).to eq("Simple-to-use touchscreen with built-in WIFI.")
22
+ expect(products[1][:price]).to eq("$79")
23
+ expect(products[1][:images][:thumb]).to eq("http://amazon.com/kindle_touch_thumb.jpg")
24
+ expect(products[1][:images][:large]).to eq("http://amazon.com/kindle_touch.jpg")
25
25
  end
26
26
 
27
27
  it "should group multiple definitions of child objects into arrays" do
28
28
  webstore = Saxy.parse(fixture_file("webstore.xml"), "webstore").first
29
29
 
30
- webstore[:products][:product].should be_instance_of Array
31
- webstore[:products][:product].size.should == 2
30
+ expect(webstore[:products][:product]).to be_an(Array)
31
+ expect(webstore[:products][:product].size).to eq(2)
32
32
  end
33
33
 
34
34
  it "should return Enumerator when calling #parse without a block" do
35
- Saxy.parse(fixture_file("webstore.xml"), "product").each.should be_instance_of Enumerator
35
+ expect(Saxy.parse(fixture_file("webstore.xml"), "product").each).to be_an(Enumerator)
36
36
  end
37
37
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michał Szajbe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-19 00:00:00.000000000 Z
11
+ date: 2016-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activesupport
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: nokogiri
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -82,7 +68,7 @@ files:
82
68
  - spec/saxy/parser_spec.rb
83
69
  - spec/saxy_spec.rb
84
70
  - spec/spec_helper.rb
85
- homepage: http://github.com/monterail/saxy
71
+ homepage: http://github.com/humante/saxy
86
72
  licenses: []
87
73
  metadata: {}
88
74
  post_install_message:
@@ -101,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
87
  version: '0'
102
88
  requirements: []
103
89
  rubyforge_project:
104
- rubygems_version: 2.4.8
90
+ rubygems_version: 2.5.1
105
91
  signing_key:
106
92
  specification_version: 4
107
93
  summary: Memory-efficient XML parser. Finds object definitions and translates them