sax-machine 0.0.16 → 1.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.
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "SAXMachine inheritance" do
4
+ before do
5
+ class A
6
+ include SAXMachine
7
+ element :title
8
+ end
9
+
10
+ class B < A
11
+ element :b
12
+ end
13
+
14
+ class C < B
15
+ element :c
16
+ end
17
+
18
+ xml = "<top><title>Test</title><b>Matched!</b><c>And Again</c></top>"
19
+ @a = A.new
20
+ @a.parse xml
21
+ @b = B.new
22
+ @b.parse xml
23
+ @c = C.new
24
+ @c.parse xml
25
+ end
26
+
27
+ after do
28
+ Object.send(:remove_const, :A)
29
+ Object.send(:remove_const, :B)
30
+ Object.send(:remove_const, :C)
31
+ end
32
+
33
+ it { expect(@a).to be_a(A) }
34
+ it { expect(@a).not_to be_a(B) }
35
+ it { expect(@a).to be_a(SAXMachine) }
36
+ it { expect(@a.title).to eq("Test") }
37
+ it { expect(@b).to be_a(A) }
38
+ it { expect(@b).to be_a(B) }
39
+ it { expect(@b).to be_a(SAXMachine) }
40
+ it { expect(@b.title).to eq("Test") }
41
+ it { expect(@b.b).to eq("Matched!") }
42
+ it { expect(@c).to be_a(A) }
43
+ it { expect(@c).to be_a(B) }
44
+ it { expect(@c).to be_a(C) }
45
+ it { expect(@c).to be_a(SAXMachine) }
46
+ it { expect(@c.title).to eq("Test") }
47
+ it { expect(@c.b).to eq("Matched!") }
48
+ it { expect(@c.c).to eq("And Again") }
49
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,22 @@
1
- require 'date'
1
+ begin
2
+ require 'simplecov'
3
+ require 'coveralls'
2
4
 
3
- # gem install redgreen for colored test output
4
- begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ Coveralls::SimpleCov::Formatter
8
+ ]
5
9
 
6
- path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
7
- $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
10
+ SimpleCov.start do
11
+ add_filter '/spec/'
12
+ end
13
+ rescue LoadError
14
+ end
8
15
 
9
- require "lib/sax-machine"
16
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/sax-machine')
17
+ SAXMachine.handler = ENV['HANDLER'].to_sym if ENV['HANDLER']
10
18
 
11
- # Spec::Runner.configure do |config|
12
- # end
19
+ RSpec.configure do |config|
20
+ config.run_all_when_everything_filtered = true
21
+ config.filter_run :focus
22
+ end
metadata CHANGED
@@ -1,94 +1,98 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: sax-machine
3
- version: !ruby/object:Gem::Version
4
- hash: 63
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 16
10
- version: 0.0.16
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.2
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Paul Dix
8
+ - Julien Kirch
9
+ - Ezekiel Templin
10
+ - Dmitry Krasnoukhov
14
11
  autorequire:
15
12
  bindir: bin
16
13
  cert_chain: []
17
-
18
- date: 2009-01-13 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: nokogiri
14
+ date: 2015-04-19 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '3.0'
23
+ type: :development
23
24
  prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ">"
28
- - !ruby/object:Gem::Version
29
- hash: 31
30
- segments:
31
- - 0
32
- - 0
33
- - 0
34
- version: 0.0.0
35
- type: :runtime
36
- version_requirements: *id001
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
37
30
  description:
38
31
  email: paul@pauldix.net
39
32
  executables: []
40
-
41
33
  extensions: []
42
-
43
34
  extra_rdoc_files: []
44
-
45
- files:
35
+ files:
36
+ - ".gitignore"
37
+ - ".rspec"
38
+ - ".travis.yml"
39
+ - Gemfile
40
+ - Guardfile
41
+ - HISTORY.md
42
+ - README.md
43
+ - Rakefile
46
44
  - lib/sax-machine.rb
45
+ - lib/sax-machine/config/sax_ancestor.rb
46
+ - lib/sax-machine/config/sax_attribute.rb
47
+ - lib/sax-machine/config/sax_collection.rb
48
+ - lib/sax-machine/config/sax_element.rb
49
+ - lib/sax-machine/config/sax_element_value.rb
50
+ - lib/sax-machine/handlers/sax_abstract_handler.rb
51
+ - lib/sax-machine/handlers/sax_nokogiri_handler.rb
52
+ - lib/sax-machine/handlers/sax_oga_handler.rb
53
+ - lib/sax-machine/handlers/sax_ox_handler.rb
47
54
  - lib/sax-machine/sax_config.rb
48
- - lib/sax-machine/sax_collection_config.rb
49
- - lib/sax-machine/sax_element_config.rb
55
+ - lib/sax-machine/sax_configure.rb
50
56
  - lib/sax-machine/sax_document.rb
51
- - lib/sax-machine/sax_handler.rb
52
- - README.textile
53
- - Rakefile
54
- - .rspec
55
- - Gemfile
56
- - Gemfile.lock
57
- - spec/spec_helper.rb
57
+ - lib/sax-machine/version.rb
58
+ - sax-machine.gemspec
59
+ - spec/fixtures/atom-content.html
60
+ - spec/fixtures/atom.xml
61
+ - spec/sax-machine/sax_activerecord_spec.rb
62
+ - spec/sax-machine/sax_configure_spec.rb
58
63
  - spec/sax-machine/sax_document_spec.rb
59
- has_rdoc: true
64
+ - spec/sax-machine/sax_include_spec.rb
65
+ - spec/spec_helper.rb
60
66
  homepage: http://github.com/pauldix/sax-machine
61
- licenses: []
62
-
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
63
70
  post_install_message:
64
71
  rdoc_options: []
65
-
66
- require_paths:
72
+ require_paths:
67
73
  - lib
68
- required_ruby_version: !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
71
76
  - - ">="
72
- - !ruby/object:Gem::Version
73
- hash: 3
74
- segments:
75
- - 0
76
- version: "0"
77
- required_rubygems_version: !ruby/object:Gem::Requirement
78
- none: false
79
- requirements:
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
80
81
  - - ">="
81
- - !ruby/object:Gem::Version
82
- hash: 3
83
- segments:
84
- - 0
85
- version: "0"
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
86
84
  requirements: []
87
-
88
85
  rubyforge_project:
89
- rubygems_version: 1.3.7
86
+ rubygems_version: 2.2.2
90
87
  signing_key:
91
- specification_version: 2
92
- summary: Declarative SAX Parsing with Nokogiri
93
- test_files: []
94
-
88
+ specification_version: 4
89
+ summary: Declarative SAX Parsing with Nokogiri, Ox or Oga
90
+ test_files:
91
+ - spec/fixtures/atom-content.html
92
+ - spec/fixtures/atom.xml
93
+ - spec/sax-machine/sax_activerecord_spec.rb
94
+ - spec/sax-machine/sax_configure_spec.rb
95
+ - spec/sax-machine/sax_document_spec.rb
96
+ - spec/sax-machine/sax_include_spec.rb
97
+ - spec/spec_helper.rb
98
+ has_rdoc:
data/Gemfile.lock DELETED
@@ -1,20 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- diff-lcs (1.1.2)
5
- nokogiri (1.4.4)
6
- rspec (2.4.0)
7
- rspec-core (~> 2.4.0)
8
- rspec-expectations (~> 2.4.0)
9
- rspec-mocks (~> 2.4.0)
10
- rspec-core (2.4.0)
11
- rspec-expectations (2.4.0)
12
- diff-lcs (~> 1.1.2)
13
- rspec-mocks (2.4.0)
14
-
15
- PLATFORMS
16
- ruby
17
-
18
- DEPENDENCIES
19
- nokogiri (>= 1.4.4)
20
- rspec (>= 2.4.0)
data/README.textile DELETED
@@ -1,87 +0,0 @@
1
- h1. SAX Machine
2
-
3
- "http://github.com/pauldix/sax-machine/wikis":http://github.com/pauldix/sax-machine/wikis
4
-
5
- "http://github.com/pauldix/sax-machine/tree/master":http://github.com/pauldix/sax-machine/tree/master
6
-
7
- h2. Description
8
-
9
- A declarative SAX parsing library backed by Nokogiri
10
-
11
- h2. Usage
12
-
13
- <pre>
14
- require 'sax-machine'
15
-
16
- # Class for parsing an atom entry out of a feedburner atom feed
17
- class AtomEntry
18
- include SAXMachine
19
- element :title
20
- # the :as argument makes this available through atom_entry.author instead of .name
21
- element :name, :as => :author
22
- element "feedburner:origLink", :as => :url
23
- element :summary
24
- element :content
25
- element :published
26
- end
27
-
28
- # Class for parsing Atom feeds
29
- class Atom
30
- include SAXMachine
31
- element :title
32
- # the :with argument means that you only match a link tag that has an attribute of :type => "text/html"
33
- # the :value argument means that instead of setting the value to the text between the tag,
34
- # it sets it to the attribute value of :href
35
- element :link, :value => :href, :as => :url, :with => {:type => "text/html"}
36
- element :link, :value => :href, :as => :feed_url, :with => {:type => "application/atom+xml"}
37
- elements :entry, :as => :entries, :class => AtomEntry
38
- end
39
-
40
- # you can then parse like this
41
- feed = Atom.parse(xml_text)
42
- # then you're ready to rock
43
- feed.title # => whatever the title of the blog is
44
- feed.url # => the main url of the blog
45
- feed.feed_url # => goes to the feedburner feed
46
-
47
- feed.entries.first.title # => title of the first entry
48
- feed.entries.first.author # => the author of the first entry
49
- feed.entries.first.url # => the permalink on the blog for this entry
50
- # etc ...
51
-
52
- # you can also use the elements method without specifying a class like so
53
- class SomeServiceResponse
54
- elements :message, :as => :messages
55
- end
56
-
57
- response = SomeServiceResponse.parse("<response><message>hi</message><message>world</message></response>")
58
- response.messages.first # => "hi"
59
- response.messages.last # => "world"
60
- </pre>
61
-
62
- h2. LICENSE
63
-
64
- (The MIT License)
65
-
66
- Copyright (c) 2009:
67
-
68
- "Paul Dix":http://pauldix.net
69
-
70
- Permission is hereby granted, free of charge, to any person obtaining
71
- a copy of this software and associated documentation files (the
72
- 'Software'), to deal in the Software without restriction, including
73
- without limitation the rights to use, copy, modify, merge, publish,
74
- distribute, sublicense, and/or sell copies of the Software, and to
75
- permit persons to whom the Software is furnished to do so, subject to
76
- the following conditions:
77
-
78
- The above copyright notice and this permission notice shall be
79
- included in all copies or substantial portions of the Software.
80
-
81
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
82
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
83
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
84
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
85
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
86
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
87
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,45 +0,0 @@
1
- module SAXMachine
2
- class SAXConfig
3
-
4
- class CollectionConfig
5
- attr_reader :name
6
-
7
- def initialize(name, options)
8
- @name = name.to_s
9
- @class = options[:class]
10
- @as = options[:as].to_s
11
-
12
- if options.has_key?(:with)
13
- # for faster comparisons later
14
- @with = options[:with].to_a.flatten.collect {|o| o.to_s}
15
- else
16
- @with = nil
17
- end
18
- end
19
-
20
- def accessor
21
- as
22
- end
23
-
24
- def attrs_match?(attrs)
25
- if @with
26
- @with == (@with & attrs)
27
- else
28
- true
29
- end
30
- end
31
-
32
- def data_class
33
- @class || @name
34
- end
35
-
36
- protected
37
-
38
- def as
39
- @as
40
- end
41
-
42
- end
43
-
44
- end
45
- end
@@ -1,65 +0,0 @@
1
- module SAXMachine
2
- class SAXConfig
3
-
4
- class ElementConfig
5
- attr_reader :name, :setter, :data_class, :collection
6
-
7
- def initialize(name, options)
8
- @name = name.to_s
9
-
10
- if options.has_key?(:with)
11
- # for faster comparisons later
12
- @with = options[:with].to_a.flatten.collect {|o| o.to_s}
13
- else
14
- @with = nil
15
- end
16
-
17
- if options.has_key?(:value)
18
- @value = options[:value].to_s
19
- else
20
- @value = nil
21
- end
22
-
23
- @as = options[:as]
24
- @collection = options[:collection]
25
-
26
- if @collection
27
- @setter = "add_#{options[:as]}"
28
- else
29
- @setter = "#{@as}="
30
- end
31
- @data_class = options[:class]
32
- @required = options[:required]
33
- end
34
-
35
- def column
36
- @as || @name.to_sym
37
- end
38
-
39
- def required?
40
- @required
41
- end
42
-
43
- def value_from_attrs(attrs)
44
- attrs.index(@value) ? attrs[attrs.index(@value) + 1] : nil
45
- end
46
-
47
- def attrs_match?(attrs)
48
- if @with
49
- @with == (@with & attrs)
50
- else
51
- true
52
- end
53
- end
54
-
55
- def has_value_and_attrs_match?(attrs)
56
- !@value.nil? && attrs_match?(attrs)
57
- end
58
-
59
- def collection?
60
- @collection
61
- end
62
- end
63
-
64
- end
65
- end
@@ -1,67 +0,0 @@
1
- require "nokogiri"
2
-
3
- module SAXMachine
4
- class SAXHandler < Nokogiri::XML::SAX::Document
5
- attr_reader :stack
6
-
7
- def initialize(object)
8
- @stack = [[object, nil, ""]]
9
- @parsed_configs = {}
10
- end
11
-
12
- def characters(string)
13
- object, config, value = stack.last
14
- value << string
15
- end
16
-
17
- def cdata_block(string)
18
- characters(string)
19
- end
20
-
21
- def start_element(name, attrs = [])
22
- attrs.flatten!
23
- object, config, value = stack.last
24
- sax_config = object.class.respond_to?(:sax_config) ? object.class.sax_config : nil
25
-
26
- if sax_config
27
- if collection_config = sax_config.collection_config(name, attrs)
28
- stack.push [object = collection_config.data_class.new, collection_config, ""]
29
- object, sax_config, is_collection = object, object.class.sax_config, true
30
- end
31
- sax_config.element_configs_for_attribute(name, attrs).each do |ec|
32
- unless parsed_config?(object, ec)
33
- object.send(ec.setter, ec.value_from_attrs(attrs))
34
- mark_as_parsed(object, ec)
35
- end
36
- end
37
- if !collection_config && element_config = sax_config.element_config_for_tag(name, attrs)
38
- stack.push [element_config.data_class ? element_config.data_class.new : object, element_config, ""]
39
- end
40
- end
41
- end
42
-
43
- def end_element(name)
44
- (object, tag_config, _), (element, config, value) = stack[-2..-1]
45
- return unless stack.size > 1 && config && config.name.to_s == name.to_s
46
-
47
- unless parsed_config?(object, config)
48
- if config.respond_to?(:accessor)
49
- object.send(config.accessor) << element
50
- else
51
- value = config.data_class ? element : value
52
- object.send(config.setter, value) unless value == ""
53
- mark_as_parsed(object, config)
54
- end
55
- end
56
- stack.pop
57
- end
58
-
59
- def mark_as_parsed(object, element_config)
60
- @parsed_configs[[object.object_id, element_config.object_id]] = true unless element_config.collection?
61
- end
62
-
63
- def parsed_config?(object, element_config)
64
- @parsed_configs[[object.object_id, element_config.object_id]]
65
- end
66
- end
67
- end