traverse 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in traversable.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Traverse
2
+
3
+ Traverse is a simple tool that makes it easy to traverse XML.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'run the spec'
4
+ task "spec" do
5
+ load './spec/spec.rb'
6
+ end
@@ -0,0 +1,3 @@
1
+ module Traverse
2
+ VERSION = "0.0.1"
3
+ end
data/lib/traverse.rb ADDED
@@ -0,0 +1,69 @@
1
+ require "traverse/version"
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+
5
+ module Traverse
6
+ class Document
7
+ def initialize document
8
+ if document.is_a? String
9
+ begin
10
+ @document = Nokogiri::XML(document)
11
+ rescue
12
+ return nil
13
+ end
14
+ else
15
+ @document = document
16
+ end
17
+
18
+ if text_node?
19
+ define_singleton_method "text" do
20
+ @document.children.first.content
21
+ end
22
+ else
23
+ @document.children.reject do |child|
24
+ child.is_a? Nokogiri::XML::Text
25
+ end.group_by(&:name).each do |name, children|
26
+ if children.count == 1
27
+ define_singleton_method "#{name}" do
28
+ Document.new children.first
29
+ end
30
+ else
31
+ define_singleton_method "#{name}s" do
32
+ children.map { |child| Document.new child }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def [] attr
40
+ @document.get_attribute attr
41
+ end
42
+
43
+ private
44
+ def method_missing m, *args, &block
45
+ self[m] or super
46
+ end
47
+
48
+ def text_node?
49
+ num_children = @document.children.count
50
+ return false unless num_children == 1
51
+
52
+ @document.children.first.is_a? Nokogiri::XML::Text
53
+ end
54
+ end
55
+
56
+ module Proxy
57
+ private
58
+ def proxy *args
59
+ if args.empty?
60
+ @proxy
61
+ else
62
+ @proxy = args.first
63
+ def method_missing m
64
+ @proxy.send m
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
data/spec/spec.rb ADDED
@@ -0,0 +1,91 @@
1
+ $:.push '../'
2
+ require 'traverse'
3
+
4
+ gem 'minitest'
5
+ require 'minitest/autorun'
6
+ require 'minitest/pride'
7
+
8
+ xml = %{
9
+ <book title="Vineland" author="Thomas Pynchon">
10
+ <author name="Thomas Pynchon">
11
+ <book title="V" />
12
+ <book title="The Crying of Lot 49" />
13
+ <book title="Gravity's Rainbow" />
14
+ <book title="Slow Learner" />
15
+ <book title="Vineland" />
16
+ <book title="Mason &amp; Dixon" />
17
+ <book title="Against the Day" />
18
+ <book title="Inherent Vice" />
19
+ </author>
20
+ <epigraph author="Johnny Copeland">
21
+ Every dog has his day,
22
+ and a good dog
23
+ just might have two days.
24
+ </epigraph>
25
+ <quotations>
26
+ <quotation>
27
+ Up and down that street, she remembered, television screens had
28
+ flickered silent blue in the darkness. Strange loud birds, not of the
29
+ neighborhood, were attracted, some content to perch in the palm
30
+ trees, keeping silence and an eye out for the rats who lived in the
31
+ fronds, others flying by close to windows, seeking an angle to sit
32
+ and view the picture from. When the commercials came on, the birds,
33
+ with voices otherworldly pure, would sing back at them, sometimes
34
+ even when none were on.
35
+ </quotation>
36
+ <quotation>
37
+ Takeshi recognized his acquaintance Minoru, a government bomb-squad
38
+ expert. Not a genius, exactly, more like an idiot savant with X-ray
39
+ vision.
40
+ </quotation>
41
+ </quotes>
42
+ <review reviewer="Salman Rushdie">
43
+ What is interesting is to have before us, at the end of the Greed
44
+ Decade, that rarest of birds: a major political novel about what
45
+ America has been doing to itself, to its children, all these many
46
+ years.
47
+ </review>
48
+ <text text="seriously, who writes XML like this">
49
+ I mean, rilly.
50
+ </text>
51
+ </book>
52
+ }
53
+
54
+ describe Traverse::Document do
55
+ before do
56
+ @doc = Traverse::Document.new xml
57
+ end
58
+
59
+ it "helps you access attributes" do
60
+ @doc.book.title.must_equal "Vineland"
61
+ end
62
+
63
+ it "also helps you access attributes shadowed by children" do
64
+ @doc.book.author.wont_equal "Thomas Pynchon"
65
+ @doc.book['author'].must_equal "Thomas Pynchon"
66
+ @doc.book.author.name.must_equal "Thomas Pynchon"
67
+ end
68
+
69
+ it "helps you get at child nodes" do
70
+ @doc.book.review.reviewer.must_equal "Salman Rushdie"
71
+ @doc.book.epigraph.author.must_equal "Johnny Copeland"
72
+ end
73
+
74
+ it "knows when a node contains only text" do
75
+ assert @doc.book.epigraph.send(:text_node?)
76
+ end
77
+
78
+ it "handles annoying text nodes transparently" do
79
+ @doc.book.epigraph.text.must_match(/Every dog has his day/)
80
+ @doc.book.review.text.must_match(/that rarest of birds/)
81
+ end
82
+
83
+ it "nevertheless handles attributes named 'text'" do
84
+ @doc.book.text['text'].must_match(/seriously/)
85
+ @doc.book.text.text.must_match(/rilly/)
86
+ end
87
+
88
+ it "knows to collect children with the same name" do
89
+ @doc.book.author.books.count.must_equal 8
90
+ end
91
+ end
data/traverse.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "traverse/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "traverse"
7
+ s.version = Traverse::VERSION
8
+ s.authors = ["happy4crazy"]
9
+ s.email = ["alan.m.odonnell@gmail.com"]
10
+ s.homepage = "https://github.com/happy4crazy/traverse"
11
+ s.summary = %q{Easily traverse an XML document.}
12
+ s.description = %q{Easily traverse an XML document.}
13
+
14
+ s.rubyforge_project = "traverse"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'nokogiri', '~> 1.5'
22
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: traverse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - happy4crazy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-02 00:00:00.000000000 -04:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: nokogiri
17
+ requirement: &2164471840 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '1.5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2164471840
26
+ description: Easily traverse an XML document.
27
+ email:
28
+ - alan.m.odonnell@gmail.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - README.md
36
+ - Rakefile
37
+ - lib/traverse.rb
38
+ - lib/traverse/version.rb
39
+ - spec/spec.rb
40
+ - traverse.gemspec
41
+ has_rdoc: true
42
+ homepage: https://github.com/happy4crazy/traverse
43
+ licenses: []
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project: traverse
62
+ rubygems_version: 1.6.2
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Easily traverse an XML document.
66
+ test_files:
67
+ - spec/spec.rb