saper 0.5.1 → 0.5.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.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/Rakefile +6 -6
  4. data/bin/saper +17 -36
  5. data/lib/saper.rb +63 -20
  6. data/lib/saper/actions/append_with.rb +1 -1
  7. data/lib/saper/actions/convert_to_html.rb +1 -1
  8. data/lib/saper/actions/convert_to_json.rb +6 -2
  9. data/lib/saper/actions/convert_to_markdown.rb +1 -1
  10. data/lib/saper/actions/convert_to_time.rb +38 -1
  11. data/lib/saper/actions/convert_to_xml.rb +1 -1
  12. data/lib/saper/actions/create_atom.rb +6 -2
  13. data/lib/saper/actions/fetch.rb +3 -2
  14. data/lib/saper/actions/fetch_with_token.rb +18 -0
  15. data/lib/saper/actions/find.rb +1 -1
  16. data/lib/saper/actions/find_first.rb +1 -1
  17. data/lib/saper/actions/get_attribute.rb +7 -2
  18. data/lib/saper/actions/get_contents.rb +1 -1
  19. data/lib/saper/actions/get_text.rb +1 -1
  20. data/lib/saper/actions/nothing.rb +11 -0
  21. data/lib/saper/actions/prepend_with.rb +2 -2
  22. data/lib/saper/actions/remove_after.rb +2 -2
  23. data/lib/saper/actions/remove_before.rb +2 -2
  24. data/lib/saper/actions/remove_matching.rb +2 -2
  25. data/lib/saper/actions/remove_tags.rb +1 -1
  26. data/lib/saper/actions/replace.rb +1 -1
  27. data/lib/saper/actions/run_recipe.rb +2 -2
  28. data/lib/saper/actions/run_recipe_and_save.rb +3 -3
  29. data/lib/saper/actions/save.rb +2 -2
  30. data/lib/saper/actions/select_matching.rb +2 -2
  31. data/lib/saper/actions/set_input.rb +1 -1
  32. data/lib/saper/actions/skip_tags.rb +1 -1
  33. data/lib/saper/actions/split.rb +1 -1
  34. data/lib/saper/arguments/attribute.rb +6 -0
  35. data/lib/saper/arguments/recipe.rb +12 -6
  36. data/lib/saper/arguments/service.rb +12 -0
  37. data/lib/saper/arguments/text.rb +1 -0
  38. data/lib/saper/arguments/timezone.rb +2 -1
  39. data/lib/saper/arguments/url.rb +12 -0
  40. data/lib/saper/arguments/variable.rb +2 -1
  41. data/lib/saper/arguments/xpath.rb +2 -1
  42. data/lib/saper/core/action.rb +43 -13
  43. data/lib/saper/core/argument.rb +30 -14
  44. data/lib/saper/core/browser.rb +29 -28
  45. data/lib/saper/core/dsl.rb +14 -16
  46. data/lib/saper/core/error.rb +1 -1
  47. data/lib/saper/core/item.rb +2 -2
  48. data/lib/saper/core/keychain.rb +58 -5
  49. data/lib/saper/core/namespace.rb +15 -18
  50. data/lib/saper/core/recipe.rb +53 -12
  51. data/lib/saper/core/result.rb +72 -0
  52. data/lib/saper/core/runtime.rb +44 -177
  53. data/lib/saper/core/stack.rb +57 -0
  54. data/lib/saper/items/atom.rb +18 -1
  55. data/lib/saper/items/document.rb +39 -19
  56. data/lib/saper/items/html.rb +52 -7
  57. data/lib/saper/items/json.rb +19 -1
  58. data/lib/saper/items/markdown.rb +14 -4
  59. data/lib/saper/items/nothing.rb +6 -0
  60. data/lib/saper/items/text.rb +28 -3
  61. data/lib/saper/items/time.rb +25 -2
  62. data/lib/saper/items/url.rb +8 -2
  63. data/lib/saper/items/xml.rb +51 -11
  64. data/lib/{lib → saper/patches}/mechanize.rb +0 -0
  65. data/lib/{lib → saper/patches}/nokogiri.rb +0 -0
  66. data/lib/saper/version.rb +2 -2
  67. data/spec/actions/append_with_spec.rb +29 -52
  68. data/spec/actions/convert_to_html_spec.rb +13 -30
  69. data/spec/actions/convert_to_json_spec.rb +13 -30
  70. data/spec/actions/convert_to_markdown_spec.rb +17 -19
  71. data/spec/actions/convert_to_time_spec.rb +25 -43
  72. data/spec/actions/convert_to_xml_spec.rb +15 -11
  73. data/spec/actions/create_atom_spec.rb +11 -19
  74. data/spec/actions/fetch_spec.rb +3 -8
  75. data/spec/actions/find_first_spec.rb +38 -40
  76. data/spec/actions/find_spec.rb +23 -39
  77. data/spec/actions/get_attribute_spec.rb +30 -3
  78. data/spec/actions/{get_contents.rb → get_contents_spec.rb} +0 -0
  79. data/spec/actions/{get_text.rb → get_text_spec.rb} +0 -0
  80. data/spec/actions/nothing_spec.rb +7 -0
  81. data/spec/actions/prepend_with_spec.rb +31 -18
  82. data/spec/actions/{remove_after.rb → remove_after_spec.rb} +0 -0
  83. data/spec/actions/{remove_before.rb → remove_before_spec.rb} +0 -0
  84. data/spec/actions/remove_matching_spec.rb +7 -0
  85. data/spec/actions/remove_tags_spec.rb +7 -0
  86. data/spec/actions/run_recipe_and_save_spec.rb +7 -0
  87. data/spec/actions/run_recipe_spec.rb +7 -0
  88. data/spec/arguments/attribute_spec.rb +7 -0
  89. data/spec/arguments/recipe_spec.rb +7 -0
  90. data/spec/arguments/text_spec.rb +7 -0
  91. data/spec/arguments/timezone_spec.rb +7 -0
  92. data/spec/arguments/variable_spec.rb +7 -0
  93. data/spec/arguments/xpath_spec.rb +7 -0
  94. data/spec/core/action_spec.rb +13 -142
  95. data/spec/core/argument_spec.rb +38 -71
  96. data/spec/core/browser_spec.rb +18 -3
  97. data/spec/core/dsl_spec.rb +1 -1
  98. data/spec/core/item_spec.rb +1 -1
  99. data/spec/core/namespace_spec.rb +0 -11
  100. data/spec/core/recipe_spec.rb +54 -77
  101. data/spec/core/result_spec.rb +7 -0
  102. data/spec/core/runtime_spec.rb +20 -151
  103. data/spec/core/stack_spec.rb +7 -0
  104. data/spec/integration/simple_invalid_spec.rb +39 -0
  105. data/spec/integration/simple_valid_spec.rb +39 -0
  106. data/spec/items/atom_spec.rb +6 -1
  107. data/spec/items/document_spec.rb +93 -15
  108. data/spec/items/html_spec.rb +45 -28
  109. data/spec/items/json_spec.rb +10 -10
  110. data/spec/items/markdown_spec.rb +24 -3
  111. data/spec/items/nothing_spec.rb +1 -1
  112. data/spec/items/text_spec.rb +13 -41
  113. data/spec/items/time_spec.rb +25 -4
  114. data/spec/items/url_spec.rb +1 -7
  115. data/spec/items/xml_spec.rb +46 -39
  116. data/spec/spec_helper.rb +2 -21
  117. metadata +63 -60
  118. data/lib/lib/json_search.rb +0 -54
  119. data/spec/actions/run_recipe_and_save_spec.tmp.rb +0 -52
  120. data/spec/actions/run_recipe_spec.tmp.rb +0 -53
@@ -1,7 +1,22 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe Saper::Browser do
4
-
5
- it # TODO
6
-
4
+ let :subject do
5
+ Saper::Browser.new
6
+ end
7
+ it "#history returns an empty array by default" do
8
+ subject.history.must_equal []
9
+ end
10
+ it "#headers returns an empty Hash by default" do
11
+ subject.headers.must_equal({})
12
+ end
13
+ it "#received returns zero by default" do
14
+ subject.received.must_equal 0
15
+ end
16
+ it "#sent returns zero by default" do
17
+ subject.sent.must_equal 0
18
+ end
19
+ it "#agent returns User-Agent string" do
20
+ subject.agent.must_include 'Mozilla'
21
+ end
7
22
  end
@@ -1,7 +1,7 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe Saper::DSL::Recipe do
4
-
4
+
5
5
  it # TODO
6
6
 
7
7
  end
@@ -2,6 +2,6 @@ require './spec/spec_helper'
2
2
 
3
3
  describe Saper::Item do
4
4
 
5
- it # TODO
5
+ it #TODO
6
6
 
7
7
  end
@@ -2,17 +2,6 @@ require './spec/spec_helper'
2
2
 
3
3
  describe Saper::Namespace do
4
4
 
5
- let(:namespace) do
6
- Saper::Namespace.parse do |ns|
7
- recipe :child do
8
- prepend_with 'test-'
9
- end
10
- recipe :parent do
11
- run_recipe_and_save :variable, :child
12
- end
13
- end
14
- end
15
-
16
5
  it # TODO
17
6
 
18
7
  end
@@ -1,81 +1,58 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe Saper::Recipe do
4
-
5
- context ".unserialize(Hash)" do
6
- it "returns a Recipe" do
7
- Saper::Recipe.unserialize({ :id => 0 }).should be_a(Saper::Recipe)
8
- end
9
- end
10
-
11
- context ".unserialize(Array)" do
12
- it "returns an Array" do
13
- Saper::Recipe.unserialize([{ :id => 0 }, { :id => 1 }]).should be_a(Array)
14
- end
15
- end
16
-
17
- context ".unserialize(nil)" do
18
- it "raises InvalidRecipe" do
19
- expect { Saper::Recipe.unserialize("invalid argument") }.to raise_error(Saper::InvalidRecipe)
20
- end
21
- end
22
-
23
- context "#id" do
24
- it "returns recipe ID" do
25
- subject.id.should be_a(String)
26
- end
27
- end
28
-
29
- context "#actions" do
30
- it "returns an empty array by default" do
31
- subject.actions.should == []
32
- end
33
- end
34
-
35
- let(:action) do
36
- Saper::Action.new(:append_with, "!")
37
- end
38
-
39
- context "#<<" do
40
- it "returns self with valid action" do
41
- (subject << action).should be_a(Saper::Recipe)
42
- end
43
- it "raises ActionExpected with invalid argument" do
44
- expect { subject << 'not an action' }.to raise_error(Saper::ActionExpected)
45
- end
46
- end
47
-
48
- context "#push" do
49
- it "returns self with valid action" do
50
- subject.push(action).should be_a(Saper::Recipe)
51
- end
52
- it "raises ActionExpected with invalid argument" do
53
- expect { subject.push('not an action') }.to raise_error(Saper::ActionExpected)
54
- end
55
- end
56
-
57
- context "#run" do
58
- it "returns self" do
59
- subject.run.should be_a(Saper::Runtime)
60
- end
61
- end
62
-
63
- context "#serialize" do
64
- it "returns a Hash" do
65
- subject.serialize.should be_a(Hash)
66
- end
67
- end
68
-
69
- context "#to_string" do
70
- it "returns a string" do
71
- subject.to_string.should be_a(String)
72
- end
73
- end
74
-
75
- context "#to_json" do
76
- it "returns a string" do
77
- subject.to_json.should be_a(String)
78
- end
79
- end
80
-
4
+ let :subject do
5
+ Saper::Recipe.new
6
+ end
7
+ it ".unserialize returns a Recipe when supplied with a valid Hash" do
8
+ Saper::Recipe.unserialize({ :id => 0 }).must_be_kind_of(Saper::Recipe)
9
+ end
10
+ it ".unserialize returns an Array when supplied with a valid Array" do
11
+ Saper::Recipe.unserialize([{ :id => 0 }, { :id => 1 }]).must_be_kind_of(Array)
12
+ end
13
+ it ".unserialize raises InvalidRecipe when supplied with nil" do
14
+ lambda { Saper::Recipe.unserialize(nil) }.must_raise(Saper::InvalidRecipe)
15
+ end
16
+ it "#id returns recipe ID" do
17
+ subject.id.must_be_kind_of(String)
18
+ end
19
+ it "#actions returns an empty array by default" do
20
+ subject.actions.must_equal []
21
+ end
22
+ it "#<< returns self when supplied with a valid action" do
23
+ (Saper::Recipe.new << Saper::Action.new(:nothing)).must_be_kind_of(Saper::Recipe)
24
+ end
25
+ it "#<< raises ActionExpected when supplied with an invalid argument" do
26
+ lambda { Saper::Recipe.new << 'not an action' }.must_raise(Saper::ActionExpected)
27
+ end
28
+ it "#push returns self when supplied with a valid action" do
29
+ Saper::Recipe.new.push(Saper::Action.new(:nothing)).must_be_kind_of(Saper::Recipe)
30
+ end
31
+ it "#push raises ActionExpected when supplied with an invalid argument" do
32
+ lambda { Saper::Recipe.new.push('not an action') }.must_raise(Saper::ActionExpected)
33
+ end
34
+ it "#empty? returns true by default" do
35
+ subject.must_be :empty?
36
+ end
37
+ it "#multiple? returns false by default" do
38
+ subject.wont_be :multiple?
39
+ end
40
+ it "#input_required returns empty array by default" do
41
+ subject.input_required.must_equal []
42
+ end
43
+ it "#input_required? returns false by default" do
44
+ subject.wont_be :input_required?
45
+ end
46
+ it"#run returns Result instance" do
47
+ subject.run.must_be_kind_of(Saper::Result)
48
+ end
49
+ it "#serialize returns a Hash" do
50
+ subject.serialize.must_be_kind_of(Hash)
51
+ end
52
+ it "#to_string returns a string" do
53
+ subject.to_string.must_be_kind_of(String)
54
+ end
55
+ it "#to_json returns a string" do
56
+ subject.to_json.must_be_kind_of(String)
57
+ end
81
58
  end
@@ -0,0 +1,7 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Saper::Result do
4
+
5
+ it # TODO
6
+
7
+ end
@@ -1,165 +1,34 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe Saper::Runtime do
4
-
5
- context "#browser" do
6
- it "returns Browser instance" do
7
- subject.browser.should be_a(Saper::Browser)
8
- end
4
+ let :subject do
5
+ Saper::Runtime.new
9
6
  end
10
-
11
- context "#bytes_received" do
12
- it "returns zero by default" do
13
- subject.bytes_received.should == 0
14
- end
7
+ it "#browser returns Browser instance" do
8
+ subject.browser.must_be_kind_of(Saper::Browser)
15
9
  end
16
-
17
- context "#bytes_sent" do
18
- it "returns zero by default" do
19
- subject.bytes_sent.should == 0
20
- end
10
+ it "#bytes_received returns zero by default" do
11
+ subject.bytes_received.must_equal 0
21
12
  end
22
-
23
- context "#http_requests" do
24
- it "returns zero by default" do
25
- subject.http_requests.should == 0
26
- end
13
+ it "#bytes_sent returns zero by default" do
14
+ subject.bytes_sent.must_equal 0
27
15
  end
28
-
29
- context "#keychain" do
30
- it "returns Keychain instance" do
31
- subject.keychain.should be_a(Saper::Keychain)
32
- end
16
+ it "#http_requests returns zero by default" do
17
+ subject.http_requests.must_equal 0
33
18
  end
34
-
35
- context "#credentials" do
36
- it "returns nil if serivce not found" do
37
- subject.credentials(:services).should == nil
38
- end
19
+ it "#keychain returns Keychain instance" do
20
+ subject.keychain.must_be_kind_of(Saper::Keychain)
39
21
  end
40
-
41
- #context "#namespace" do
42
- # it "returns nil" do
43
- # subject.namespace.should be_nil
44
- # end
45
- #end
46
-
47
- context "#depth" do
48
- it "returns zero by default" do
49
- subject.depth.should == 0
50
- end
22
+ it "#credentials returns empty hash if service not found" do
23
+ subject.credentials(:services).must_equal({})
51
24
  end
52
-
53
- context "#descendants" do
54
- it "returns self by default" do
55
- subject.descendants.should == [subject]
56
- end
25
+ it "#[] returns nil if variable is not defined" do
26
+ subject[:varname].must_be_nil
57
27
  end
58
-
59
- context "#results" do
60
- it "returns nil by default" do
61
- subject.results.should == nil
62
- end
28
+ it "#[]= stores variale value" do
29
+ Saper::Runtime.new { |r| r[:var] = 'A' }[:var].must_equal 'A'
63
30
  end
64
-
65
- context "#results" do
66
- it "returns input by default" do
67
- Saper::Runtime.new([], "input").results.should == "input"
68
- end
31
+ it "#variables returns list of variable names" do
32
+ Saper::Runtime.new { |r| r[:var] = 'B' }.variables.must_equal({ :var => 'B' })
69
33
  end
70
-
71
- context "#[]" do
72
- it "returns nil if variable is not defined" do
73
- subject[:varname].should be_nil
74
- end
75
- end
76
-
77
- context "#[]=" do
78
- it "stores variale value" do
79
- subject[:var] = 'OK'; subject[:var].should == 'OK'
80
- end
81
- end
82
-
83
- context "#variables" do
84
- it "returns list of variable names" do
85
- subject[:var] = 'OK'; subject.variables.should == { :var => 'OK' }
86
- end
87
- end
88
-
89
- let(:simple_recipe) do
90
- Saper::Recipe.parse do
91
- convert_to_html
92
- find_first "p"
93
- get_contents
94
- append_with "!"
95
- end
96
- end
97
-
98
- context "#results" do
99
- context "with failed single-output recipe" do
100
- it "returns nil" do
101
- Saper::Runtime.new(simple_recipe, nil).results.should == nil
102
- end
103
- end
104
- context "with successful single-output recipe" do
105
- it "returns result" do
106
- Saper::Runtime.new(simple_recipe, "<p>a</p><p>b</p>").results.should == "a!"
107
- end
108
- end
109
- end
110
-
111
- let(:multiple_recipe) do
112
- Saper::Recipe.parse do
113
- convert_to_html
114
- find "p"
115
- get_contents
116
- append_with "!"
117
- end
118
- end
119
-
120
- context "#results" do
121
- context "with failed multiple-output recipe" do
122
- it "returns empty array" do
123
- Saper::Runtime.new(multiple_recipe, nil).results.should == []
124
- end
125
- end
126
- context "with successful multiple-output recipe" do
127
- it "returns array with results" do
128
- Saper::Runtime.new(multiple_recipe, "<p>a</p><p>b</p>").results.should == ["a!", "b!"]
129
- end
130
- end
131
- end
132
-
133
- let(:namespaced_recipes) do
134
- Saper::Namespace.parse do |ns|
135
- recipe :child_multiple do
136
- find "p"
137
- get_contents
138
- end
139
- recipe :child_single do
140
- find_first "p"
141
- get_contents
142
- end
143
- recipe :parent_multiple do
144
- run_recipe :child_multiple
145
- end
146
- recipe :parent_single do
147
- run_recipe :child_single
148
- end
149
- end
150
- end
151
-
152
- context "#results" do
153
- context "with embedded multiple-output recipe" do
154
- it "returns correct ouput" do
155
- Saper::Runtime.new(namespaced_recipes[:parent_multiple], "<p>a</p><p>b</p>").results.should == ['a', 'b']
156
- end
157
- end
158
- context "with embedded single-output recipe" do
159
- it "returns correct ouput" do
160
- Saper::Runtime.new(namespaced_recipes[:parent_single], "<p>a</p><p>b</p>").results.should == 'a'
161
- end
162
- end
163
- end
164
-
165
34
  end
@@ -0,0 +1,7 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Saper::Stack do
4
+
5
+ it # TODO
6
+
7
+ end
@@ -0,0 +1,39 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe "Simple Invalid Recipe" do
4
+ let :recipe do
5
+ Saper::Recipe.parse do
6
+ set_input "<p>one</p><p>two</p>"
7
+ convert_to_html
8
+ append_with "!"
9
+ prepend_with "!"
10
+ end
11
+ end
12
+ let :result do
13
+ recipe.run
14
+ end
15
+ it "returns Result" do
16
+ result.must_be_instance_of(Saper::Result)
17
+ end
18
+ it "#multiple? returns false" do
19
+ result.wont_be :multiple?
20
+ end
21
+ it "#success? returns false" do
22
+ result.wont_be :success?
23
+ end
24
+ it "#failure? returns true" do
25
+ result.must_be :failure?
26
+ end
27
+ it "#size returns 1" do
28
+ result.size.must_equal 1
29
+ end
30
+ it "#to_native returns nil" do
31
+ result.to_native.must_be_nil
32
+ end
33
+ it "#to_saper returns Saper::Items::Nothing" do
34
+ result.to_saper.must_be_instance_of Saper::Items::Nothing
35
+ end
36
+ it "#to_json returns valid String" do
37
+ result.to_json.must_equal 'null'
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe "Simple Valid Recipe" do
4
+ let :recipe do
5
+ Saper::Recipe.parse do
6
+ set_input "<p>one</p><p>two</p>"
7
+ convert_to_html
8
+ find "p"
9
+ get_contents
10
+ end
11
+ end
12
+ let :result do
13
+ recipe.run
14
+ end
15
+ it "returns Result" do
16
+ result.must_be_instance_of(Saper::Result)
17
+ end
18
+ it "#multiple? returns true" do
19
+ result.must_be :multiple?
20
+ end
21
+ it "#success? returns true" do
22
+ result.must_be :success?
23
+ end
24
+ it "#failure? returns false" do
25
+ result.wont_be :failure?
26
+ end
27
+ it "#size returns 2" do
28
+ result.size.must_equal 2
29
+ end
30
+ it "#to_native returns valid Array" do
31
+ result.to_native.must_equal ["one","two"]
32
+ end
33
+ it "#to_saper returns valid Array" do
34
+ result.to_saper.must_equal [Saper::Items::Text.new("one"),Saper::Items::Text.new("two")]
35
+ end
36
+ it "#to_json returns valid String" do
37
+ result.to_json.must_equal '["one","two"]'
38
+ end
39
+ end