dozuki 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/CI ADDED
@@ -0,0 +1,13 @@
1
+ #!/bin/bash -lxe
2
+ [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
3
+ rvm use 1.9.2@dozuki
4
+
5
+ if [ `type -P bundle` ]
6
+ then
7
+ echo "BUNDLER DETECTED"
8
+ else
9
+ gem install bundler
10
+ fi
11
+
12
+ bundle install
13
+ rake
@@ -7,34 +7,35 @@ PATH
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- ZenTest (4.4.2)
10
+ ZenTest (4.5.0)
11
11
  archive-tar-minitar (0.5.2)
12
12
  autotest (4.4.6)
13
13
  ZenTest (>= 4.4.1)
14
14
  builder (3.0.0)
15
15
  columnize (0.3.2)
16
- cucumber (0.10.0)
16
+ cucumber (0.10.2)
17
17
  builder (>= 2.1.2)
18
- diff-lcs (~> 1.1.2)
19
- gherkin (~> 2.3.2)
20
- json (~> 1.4.6)
21
- term-ansicolor (~> 1.0.5)
18
+ diff-lcs (>= 1.1.2)
19
+ gherkin (>= 2.3.5)
20
+ json (>= 1.4.6)
21
+ term-ansicolor (>= 1.0.5)
22
22
  diff-lcs (1.1.2)
23
- gherkin (2.3.3)
24
- json (~> 1.4.6)
25
- json (1.4.6)
26
- linecache19 (0.5.11)
23
+ gherkin (2.3.6)
24
+ json (>= 1.4.6)
25
+ json (1.5.1)
26
+ linecache19 (0.5.12)
27
27
  ruby_core_source (>= 0.1.4)
28
28
  nokogiri (1.4.4)
29
- rspec (2.3.0)
30
- rspec-core (~> 2.3.0)
31
- rspec-expectations (~> 2.3.0)
32
- rspec-mocks (~> 2.3.0)
33
- rspec-core (2.3.1)
34
- rspec-expectations (2.3.0)
29
+ rake (0.8.7)
30
+ rspec (2.5.0)
31
+ rspec-core (~> 2.5.0)
32
+ rspec-expectations (~> 2.5.0)
33
+ rspec-mocks (~> 2.5.0)
34
+ rspec-core (2.5.1)
35
+ rspec-expectations (2.5.0)
35
36
  diff-lcs (~> 1.1.2)
36
- rspec-mocks (2.3.0)
37
- ruby-debug-base19 (0.11.24)
37
+ rspec-mocks (2.5.0)
38
+ ruby-debug-base19 (0.11.25)
38
39
  columnize (>= 0.3.1)
39
40
  linecache19 (>= 0.5.11)
40
41
  ruby_core_source (>= 0.1.4)
@@ -42,7 +43,7 @@ GEM
42
43
  columnize (>= 0.3.1)
43
44
  linecache19 (>= 0.5.11)
44
45
  ruby-debug-base19 (>= 0.11.19)
45
- ruby_core_source (0.1.4)
46
+ ruby_core_source (0.1.5)
46
47
  archive-tar-minitar (>= 0.5.2)
47
48
  term-ansicolor (1.0.5)
48
49
 
@@ -53,6 +54,6 @@ DEPENDENCIES
53
54
  autotest
54
55
  cucumber
55
56
  dozuki!
56
- nokogiri
57
+ rake
57
58
  rspec
58
59
  ruby-debug19
@@ -1,8 +1,10 @@
1
- = Dozuki
1
+ # Dozuki
2
2
 
3
3
  A Nokogiri wrapper that simplifies commonly occurring tasks.
4
4
 
5
- == What does it do?
5
+ [![Build Status](http://travis-ci.org/JamesAlmond/dozuki.png)](http://travis-ci.org/JamesAlmond/dozuki)
6
+
7
+ ## What does it do?
6
8
 
7
9
  Dozuki removes the repetitive tasks from parsing XML documents with XPaths such as:
8
10
 
@@ -14,73 +16,82 @@ Dozuki removes the repetitive tasks from parsing XML documents with XPaths such
14
16
 
15
17
  It's mainly sugar for reducing the amount of chaining on calls like:
16
18
 
17
- doc.xpath('/my/xpath').first.to_i
19
+ doc.xpath('/my/xpath').first.to_i
20
+
21
+ to:
18
22
 
19
- == How do I use it?
23
+ doc.int('/my/xpath')
20
24
 
21
- Parsing XML (currently only supports strings):
25
+ ## How do I use it?
22
26
 
23
- doc = Dozuki::XML.parse(xml_string)
27
+ The parse method supports all input parameters supported by [Nokogiri's
28
+ parse method](http://nokogiri.org/Nokogiri/XML/Document.html#parse):
29
+
30
+ # simple usage
31
+ doc = Dozuki::XML.parse(string_or_io)
32
+
33
+ # or the full parameter list
34
+ doc = Dozuki::XML.parse(string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML)
24
35
 
25
36
  This documents supports the Dozuki extensions for:
26
37
 
27
- === Extracting a single node
38
+ ### Extracting a single node
28
39
 
29
40
  The get methods takes an xpath and returns the first node that matches the xpath:
30
41
 
31
- doc.get('/my/xpath')
42
+ doc.get('/my/xpath')
32
43
 
33
44
  If the node can't be found then an exception is raised.
34
45
 
35
- === Extracting a single node of a certain type
46
+ ### Extracting a single node of a certain type
36
47
 
37
48
  The following methods take the first node that matches the xpath and returns the formatted result:
38
49
 
39
- doc.string('/my/xpath') # surrounding whitespace stripped
40
- doc.float('/my/xpath')
41
- doc.int('/my/xpath')
50
+ doc.string('/my/xpath') # surrounding whitespace stripped
51
+ doc.float('/my/xpath')
52
+ doc.int('/my/xpath')
42
53
 
43
54
  These functions are to replace calls using plain Nokogiri such as:
44
55
 
45
56
  doc.xpath('/my/xpath').first.to_i
46
57
 
47
- === Checking whether an element exists
58
+ ### Checking whether an element exists
48
59
 
49
- doc.exists?('/my/xpath')
60
+ doc.exists?('/my/xpath')
50
61
 
51
- === Iterating through nodes
62
+ ### Iterating through nodes
52
63
 
53
64
  Dozuki also provides a slightly more succinct way to 'each' an xpath:
54
65
 
55
- doc.each('/my/xpath') do |node|
56
- # do something
57
- end
66
+ doc.each('/my/xpath') do |node|
67
+ # do something
68
+ end
58
69
 
59
- === Iterating through node text and parsing
70
+ ## Iterating through node text and parsing
60
71
 
61
72
  There are also simple ways to extract formatted text of a series of nodes with an each
62
73
 
63
- doc.each('/my/xpath').as_string do |node|
64
- # string with surrounding whitespace stripped
65
- end
66
-
67
- doc.each('/my/xpath').as_int do |node|
68
- # int
69
- end
70
-
71
- doc.each('/my/xpath').as_float do |node|
72
- # float
73
- end
74
+ doc.each('/my/xpath').as_string do |node|
75
+ # string with surrounding whitespace stripped
76
+ end
77
+
78
+ doc.each('/my/xpath').as_int do |node|
79
+ # int
80
+ end
81
+
82
+ doc.each('/my/xpath').as_float do |node|
83
+ # float
84
+ end
74
85
 
75
- == Playing nicely with Nokogiri
86
+ ## Playing nicely with Nokogiri
76
87
 
77
88
  Dozuki will proxy any calls not recognised onto the underlying Nokogiri structure, including responds_to?, allowing you to treat it like any other Nokogiri document.
78
89
 
79
- == More documentation
90
+ ## More documentation
80
91
 
81
- More features are described in the.. {features}[https://github.com/jamesalmond/dozuki/tree/master/features]
92
+ More features are described in the.. [features](https://github.com/jamesalmond/dozuki/tree/master/features)
82
93
 
83
- == Contributing to Dozuki
94
+ ## Contributing to Dozuki
84
95
 
85
96
  * Fork the project.
86
97
  * Add tests that cover the new feature or bug fix.
@@ -88,13 +99,13 @@ More features are described in the.. {features}[https://github.com/jamesalmond/d
88
99
  * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
89
100
  * Send me a pull request. Bonus points for topic branches.
90
101
 
91
- == LICENSE:
102
+ ## LICENSE:
92
103
 
93
104
  (The MIT License)
94
105
 
95
106
  Copyright (c) 2010:
96
107
 
97
- * {James Almond}[http://jamesalmond.com]
108
+ * [James Almond](http://jamesalmond.com)
98
109
 
99
110
  Permission is hereby granted, free of charge, to any person obtaining
100
111
  a copy of this software and associated documentation files (the
@@ -113,4 +124,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
113
124
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
114
125
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
115
126
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
116
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
127
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,2 +1,19 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+ require 'cucumber'
7
+ require 'cucumber/rake/task'
8
+
9
+
10
+
11
+ desc "Run specs"
12
+ RSpec::Core::RakeTask.new :spec
13
+
14
+ desc "Run integrations"
15
+ Cucumber::Rake::Task.new(:features) do |t|
16
+ t.cucumber_opts = "features --format pretty"
17
+ end
18
+ task :default => [:spec, :features]
19
+
@@ -18,12 +18,13 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- {spec,features}/* .autotest`.split("\n")
19
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
20
  s.require_paths = ["lib"]
21
-
21
+
22
22
  s.add_dependency("nokogiri")
23
-
23
+
24
24
  s.add_development_dependency("rspec")
25
25
  s.add_development_dependency("cucumber")
26
26
  s.add_development_dependency("ruby-debug19")
27
27
  s.add_development_dependency("autotest")
28
-
28
+ s.add_development_dependency("rake")
29
+
29
30
  end
@@ -2,71 +2,43 @@ Feature: Iterating through nodes
2
2
  In order to provide simpler way of accessing groups of nods
3
3
  As a traverser
4
4
  I want to access nodes using the each method and an xpath
5
-
6
- Scenario: using each to traverse a document
7
- When I parse the XML:
5
+
6
+ Background:
7
+ Given I have parsed the XML:
8
8
  """
9
9
  <root>
10
10
  <name>St. George's Arms</name>
11
- <average_price>20.32</average_price>
12
- <number_of_beers>2</number_of_beers>
13
11
  <rooms>
14
12
  <room>SINGLE</room>
15
13
  <room>Double</room>
16
14
  </rooms>
15
+ <room_numbers>
16
+ <number>5</number>
17
+ <number>7</number>
18
+ </room_numbers>
19
+ <prices>
20
+ <price>53.50</price>
21
+ <price>799.78</price>
22
+ </prices>
17
23
  </root>
18
24
  """
19
- And I call "each('/root/rooms/room')" on the document and collect the results
25
+
26
+ Scenario: using each to traverse a document
27
+ When I call "each('/root/rooms/room')" on the document and collect the results
20
28
  Then the results should contain a node with the text "SINGLE"
21
29
  And the results should contain a node with the text "Double"
22
-
30
+
23
31
  Scenario: using each to traverse a document and getting the string elements
24
- When I parse the XML:
25
- """
26
- <root>
27
- <name>St. George's Arms</name>
28
- <average_price>20.32</average_price>
29
- <number_of_beers>2</number_of_beers>
30
- <rooms>
31
- <room>SINGLE</room>
32
- <room>Double</room>
33
- </rooms>
34
- </root>
35
- """
36
- And I call "each('/root/rooms/room').as_string" on the document and collect the results
32
+ When I call "each('/root/rooms/room').as_string" on the document and collect the results
37
33
  Then the results should contain "SINGLE"
38
34
  And the results should contain "Double"
39
-
35
+
40
36
  Scenario: using each to traverse a document and getting the integer elements
41
- When I parse the XML:
42
- """
43
- <root>
44
- <name>St. George's Arms</name>
45
- <average_price>20.32</average_price>
46
- <number_of_beers>2</number_of_beers>
47
- <rooms>
48
- <room>5</room>
49
- <room>7</room>
50
- </rooms>
51
- </root>
52
- """
53
- And I call "each('/root/rooms/room').as_int" on the document and collect the results
37
+ When I call "each('/root/room_numbers/number').as_int" on the document and collect the results
54
38
  Then the results should contain 5
55
- And the results should contain 5
56
-
39
+ And the results should contain 7
40
+
57
41
  Scenario: using each to traverse a document and getting the float elements
58
- When I parse the XML:
59
- """
60
- <root>
61
- <name>St. George's Arms</name>
62
- <average_price>20.32</average_price>
63
- <number_of_beers>2</number_of_beers>
64
- <rooms>
65
- <room>53.50</room>
66
- <room>799.78</room>
67
- </rooms>
68
- </root>
69
- """
70
- And I call "each('/root/rooms/room').as_float" on the document and collect the results
42
+ When I call "each('/root/prices/price').as_float" on the document and collect the results
71
43
  Then the results should contain 53.50
72
- And the results should contain 799.78
44
+ And the results should contain 799.78
@@ -2,8 +2,7 @@ Feature: Exists accessor
2
2
  In order to easily determine whether a node exists in a document
3
3
  As a traverser
4
4
  I want to check whether a node exists
5
-
6
-
5
+
7
6
  Scenario: the node exists
8
7
  When I parse the XML:
9
8
  """
@@ -15,7 +14,7 @@ Feature: Exists accessor
15
14
  """
16
15
  And I call "exists?('/root/number_of_beers')" on the document
17
16
  Then the result should be true
18
-
17
+
19
18
  Scenario: the node doesn't exist
20
19
  When I parse the XML:
21
20
  """
@@ -26,4 +25,4 @@ Feature: Exists accessor
26
25
  </root>
27
26
  """
28
27
  And I call "exists?('/root/food')" on the document
29
- Then the result should be false
28
+ Then the result should be false
@@ -2,43 +2,37 @@ Feature: Getting floats from the document
2
2
  In order to provide simpler way of getting floats from a node
3
3
  As a traverser
4
4
  I want to access nodes using the float method and an xpath
5
-
6
- Scenario: getting the float of a single node
7
- When I parse the XML:
5
+
6
+ Background:
7
+ Given I have parsed the XML:
8
8
  """
9
9
  <root>
10
10
  <name>St. George's Arms</name>
11
11
  <average_price>20.32</average_price>
12
+ <highest_price>
13
+ 30.33
14
+ </highest_price>
12
15
  <number_of_beers>2</number_of_beers>
13
16
  </root>
14
17
  """
15
- And I call "float('/root/average_price')" on the document
18
+
19
+ Scenario: getting the float of a single node
20
+ When I call "float('/root/average_price')" on the document
16
21
  Then the result should be 20.32
17
-
22
+
18
23
  Scenario: getting the float of a single node with whitespace
19
- When I parse the XML:
20
- """
21
- <root>
22
- <name>St. George's Arms</name>
23
- <average_price>
24
- 20.32
25
- </average_price>
26
- <number_of_beers>2</number_of_beers>
27
- </root>
28
- """
29
- And I call "float('/root/average_price')" on the document
30
- Then the result should be 20.32
31
-
24
+ When I call "float('/root/highest_price')" on the document
25
+ Then the result should be 30.33
26
+
27
+ Scenario: getting the int of a node that doesn't contain a float
28
+ When I call "float('/root/name')" on the document
29
+ Then it should raise an "InvalidFormat" error
30
+ And the error should have the value "St. George's Arms"
31
+ And the error should have the format "float"
32
+
32
33
  Scenario: getting a non-existent node
33
- When I parse the XML:
34
- """
35
- <root>
36
- <name>St. George's Arms</name>
37
- <average_price>20.32</average_price>
38
- <number_of_beers>2</number_of_beers>
39
- </root>
40
- """
41
- Then calling "float('//something/missing')" on the document should raise a "NotFound" error
34
+ When I call "float('//something/missing')" on the document
35
+ Then it should raise a "NotFound" error
42
36
  And the error should have the xpath "//something/missing"
43
37
  And the error should have a stored node
44
-
38
+