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.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/Rakefile +6 -6
- data/bin/saper +17 -36
- data/lib/saper.rb +63 -20
- data/lib/saper/actions/append_with.rb +1 -1
- data/lib/saper/actions/convert_to_html.rb +1 -1
- data/lib/saper/actions/convert_to_json.rb +6 -2
- data/lib/saper/actions/convert_to_markdown.rb +1 -1
- data/lib/saper/actions/convert_to_time.rb +38 -1
- data/lib/saper/actions/convert_to_xml.rb +1 -1
- data/lib/saper/actions/create_atom.rb +6 -2
- data/lib/saper/actions/fetch.rb +3 -2
- data/lib/saper/actions/fetch_with_token.rb +18 -0
- data/lib/saper/actions/find.rb +1 -1
- data/lib/saper/actions/find_first.rb +1 -1
- data/lib/saper/actions/get_attribute.rb +7 -2
- data/lib/saper/actions/get_contents.rb +1 -1
- data/lib/saper/actions/get_text.rb +1 -1
- data/lib/saper/actions/nothing.rb +11 -0
- data/lib/saper/actions/prepend_with.rb +2 -2
- data/lib/saper/actions/remove_after.rb +2 -2
- data/lib/saper/actions/remove_before.rb +2 -2
- data/lib/saper/actions/remove_matching.rb +2 -2
- data/lib/saper/actions/remove_tags.rb +1 -1
- data/lib/saper/actions/replace.rb +1 -1
- data/lib/saper/actions/run_recipe.rb +2 -2
- data/lib/saper/actions/run_recipe_and_save.rb +3 -3
- data/lib/saper/actions/save.rb +2 -2
- data/lib/saper/actions/select_matching.rb +2 -2
- data/lib/saper/actions/set_input.rb +1 -1
- data/lib/saper/actions/skip_tags.rb +1 -1
- data/lib/saper/actions/split.rb +1 -1
- data/lib/saper/arguments/attribute.rb +6 -0
- data/lib/saper/arguments/recipe.rb +12 -6
- data/lib/saper/arguments/service.rb +12 -0
- data/lib/saper/arguments/text.rb +1 -0
- data/lib/saper/arguments/timezone.rb +2 -1
- data/lib/saper/arguments/url.rb +12 -0
- data/lib/saper/arguments/variable.rb +2 -1
- data/lib/saper/arguments/xpath.rb +2 -1
- data/lib/saper/core/action.rb +43 -13
- data/lib/saper/core/argument.rb +30 -14
- data/lib/saper/core/browser.rb +29 -28
- data/lib/saper/core/dsl.rb +14 -16
- data/lib/saper/core/error.rb +1 -1
- data/lib/saper/core/item.rb +2 -2
- data/lib/saper/core/keychain.rb +58 -5
- data/lib/saper/core/namespace.rb +15 -18
- data/lib/saper/core/recipe.rb +53 -12
- data/lib/saper/core/result.rb +72 -0
- data/lib/saper/core/runtime.rb +44 -177
- data/lib/saper/core/stack.rb +57 -0
- data/lib/saper/items/atom.rb +18 -1
- data/lib/saper/items/document.rb +39 -19
- data/lib/saper/items/html.rb +52 -7
- data/lib/saper/items/json.rb +19 -1
- data/lib/saper/items/markdown.rb +14 -4
- data/lib/saper/items/nothing.rb +6 -0
- data/lib/saper/items/text.rb +28 -3
- data/lib/saper/items/time.rb +25 -2
- data/lib/saper/items/url.rb +8 -2
- data/lib/saper/items/xml.rb +51 -11
- data/lib/{lib → saper/patches}/mechanize.rb +0 -0
- data/lib/{lib → saper/patches}/nokogiri.rb +0 -0
- data/lib/saper/version.rb +2 -2
- data/spec/actions/append_with_spec.rb +29 -52
- data/spec/actions/convert_to_html_spec.rb +13 -30
- data/spec/actions/convert_to_json_spec.rb +13 -30
- data/spec/actions/convert_to_markdown_spec.rb +17 -19
- data/spec/actions/convert_to_time_spec.rb +25 -43
- data/spec/actions/convert_to_xml_spec.rb +15 -11
- data/spec/actions/create_atom_spec.rb +11 -19
- data/spec/actions/fetch_spec.rb +3 -8
- data/spec/actions/find_first_spec.rb +38 -40
- data/spec/actions/find_spec.rb +23 -39
- data/spec/actions/get_attribute_spec.rb +30 -3
- data/spec/actions/{get_contents.rb → get_contents_spec.rb} +0 -0
- data/spec/actions/{get_text.rb → get_text_spec.rb} +0 -0
- data/spec/actions/nothing_spec.rb +7 -0
- data/spec/actions/prepend_with_spec.rb +31 -18
- data/spec/actions/{remove_after.rb → remove_after_spec.rb} +0 -0
- data/spec/actions/{remove_before.rb → remove_before_spec.rb} +0 -0
- data/spec/actions/remove_matching_spec.rb +7 -0
- data/spec/actions/remove_tags_spec.rb +7 -0
- data/spec/actions/run_recipe_and_save_spec.rb +7 -0
- data/spec/actions/run_recipe_spec.rb +7 -0
- data/spec/arguments/attribute_spec.rb +7 -0
- data/spec/arguments/recipe_spec.rb +7 -0
- data/spec/arguments/text_spec.rb +7 -0
- data/spec/arguments/timezone_spec.rb +7 -0
- data/spec/arguments/variable_spec.rb +7 -0
- data/spec/arguments/xpath_spec.rb +7 -0
- data/spec/core/action_spec.rb +13 -142
- data/spec/core/argument_spec.rb +38 -71
- data/spec/core/browser_spec.rb +18 -3
- data/spec/core/dsl_spec.rb +1 -1
- data/spec/core/item_spec.rb +1 -1
- data/spec/core/namespace_spec.rb +0 -11
- data/spec/core/recipe_spec.rb +54 -77
- data/spec/core/result_spec.rb +7 -0
- data/spec/core/runtime_spec.rb +20 -151
- data/spec/core/stack_spec.rb +7 -0
- data/spec/integration/simple_invalid_spec.rb +39 -0
- data/spec/integration/simple_valid_spec.rb +39 -0
- data/spec/items/atom_spec.rb +6 -1
- data/spec/items/document_spec.rb +93 -15
- data/spec/items/html_spec.rb +45 -28
- data/spec/items/json_spec.rb +10 -10
- data/spec/items/markdown_spec.rb +24 -3
- data/spec/items/nothing_spec.rb +1 -1
- data/spec/items/text_spec.rb +13 -41
- data/spec/items/time_spec.rb +25 -4
- data/spec/items/url_spec.rb +1 -7
- data/spec/items/xml_spec.rb +46 -39
- data/spec/spec_helper.rb +2 -21
- metadata +63 -60
- data/lib/lib/json_search.rb +0 -54
- data/spec/actions/run_recipe_and_save_spec.tmp.rb +0 -52
- data/spec/actions/run_recipe_spec.tmp.rb +0 -53
@@ -5,8 +5,8 @@ module Saper
|
|
5
5
|
argument :recipe
|
6
6
|
accepts :anything, :returns => Proc.new { |instance| nil } # TODO
|
7
7
|
|
8
|
-
run do |input, subrecipe|
|
9
|
-
|
8
|
+
run do |runtime, input, subrecipe|
|
9
|
+
subrecipe.run(input).to_saper
|
10
10
|
end
|
11
11
|
|
12
12
|
# Overrides default logic
|
@@ -6,9 +6,9 @@ module Saper
|
|
6
6
|
argument :recipe
|
7
7
|
accepts :anything
|
8
8
|
|
9
|
-
run do |input, variable, subrecipe|
|
10
|
-
result =
|
11
|
-
|
9
|
+
run do |runtime, input, variable, subrecipe|
|
10
|
+
result = subrecipe.run(input).to_saper
|
11
|
+
runtime[variable] = result unless result.nil?
|
12
12
|
input
|
13
13
|
end
|
14
14
|
|
data/lib/saper/actions/save.rb
CHANGED
data/lib/saper/actions/split.rb
CHANGED
@@ -8,7 +8,7 @@ module Saper
|
|
8
8
|
accepts :document, :returns => :text
|
9
9
|
accepts :html, :returns => :html
|
10
10
|
|
11
|
-
run do |input, separator|
|
11
|
+
run do |runtime, input, separator|
|
12
12
|
case input
|
13
13
|
when Items::HTML
|
14
14
|
input.inner_html.split(separator).map { |string| Item.new(:text, string).to_html }
|
@@ -1,19 +1,24 @@
|
|
1
1
|
module Saper
|
2
2
|
module Arguments
|
3
3
|
class Recipe < Argument
|
4
|
-
|
4
|
+
|
5
|
+
# @todo
|
5
6
|
def valid?(value)
|
6
|
-
value.is_a?(Symbol) || value.is_a?(String)
|
7
|
+
value.is_a?(Symbol) || value.is_a?(String) || value.is_a?(Numeric)
|
7
8
|
end
|
8
9
|
|
10
|
+
# @todo
|
9
11
|
def normalize(value)
|
10
12
|
if value.is_a?(Recipe)
|
11
13
|
return value
|
12
14
|
end
|
13
|
-
if value.is_a?(
|
14
|
-
value = value.
|
15
|
+
if value.is_a?(Symbol)
|
16
|
+
value = value.to_s
|
17
|
+
end
|
18
|
+
if value.is_a?(Numeric)
|
19
|
+
value = value.to_s
|
15
20
|
end
|
16
|
-
unless value.is_a?(
|
21
|
+
unless value.is_a?(String)
|
17
22
|
raise InvalidArgument
|
18
23
|
end
|
19
24
|
if action.nil?
|
@@ -28,11 +33,12 @@ module Saper
|
|
28
33
|
value
|
29
34
|
end
|
30
35
|
|
31
|
-
#
|
36
|
+
# @todo
|
32
37
|
def serialize
|
33
38
|
value.id
|
34
39
|
end
|
35
40
|
|
41
|
+
# @todo
|
36
42
|
def to_string
|
37
43
|
value.id.inspect
|
38
44
|
end
|
data/lib/saper/arguments/text.rb
CHANGED
data/lib/saper/core/action.rb
CHANGED
@@ -52,7 +52,7 @@ module Saper
|
|
52
52
|
return @types.nil? ? [] : @types.keys
|
53
53
|
end
|
54
54
|
if input == :anything
|
55
|
-
return
|
55
|
+
return @types = {}
|
56
56
|
end
|
57
57
|
output = options[:returns] || input
|
58
58
|
unless Item.exists?(input)
|
@@ -65,11 +65,35 @@ module Saper
|
|
65
65
|
@types[input] = output
|
66
66
|
end
|
67
67
|
|
68
|
+
# Returns `true` if action accepts no input.
|
69
|
+
# @return [Boolean]
|
70
|
+
def self.accepts_nothing?
|
71
|
+
@types.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns `true` if action accepts at least some kind of input.
|
75
|
+
# @return [Boolean]
|
76
|
+
def self.accepts_something?
|
77
|
+
!accepts_nothing? && !accepts_anything?
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns `true` if action accepts any kind of input.
|
81
|
+
# @return [Boolean]
|
82
|
+
def self.accepts_anything?
|
83
|
+
@types.empty?
|
84
|
+
end
|
85
|
+
|
68
86
|
# Returns `true` if action accepts specified type as input.
|
69
87
|
# @param type [Symbol]
|
70
88
|
# @return [Boolean]
|
71
89
|
def self.accepts?(type)
|
72
|
-
|
90
|
+
if accepts_nothing?
|
91
|
+
return false
|
92
|
+
end
|
93
|
+
if accepts_anything?
|
94
|
+
return true
|
95
|
+
end
|
96
|
+
accepts.include?(type)
|
73
97
|
end
|
74
98
|
|
75
99
|
# Saves Proc that encapsulates action logic and will be used later for data processing.
|
@@ -116,8 +140,12 @@ module Saper
|
|
116
140
|
end
|
117
141
|
end
|
118
142
|
|
143
|
+
# @todo
|
119
144
|
attr_reader :options
|
120
145
|
|
146
|
+
# @todo
|
147
|
+
attr_reader :arguments
|
148
|
+
|
121
149
|
# Returns a new instance of Saper::Action.
|
122
150
|
# @return [Saper::Action]
|
123
151
|
def initialize(*args)
|
@@ -139,24 +167,26 @@ module Saper
|
|
139
167
|
# @param input [object] input
|
140
168
|
# @return [void] depends on action type
|
141
169
|
def run(input = nil, runtime = nil)
|
170
|
+
runtime ||= Runtime.new
|
171
|
+
input = validate_input(input)
|
172
|
+
block.call(runtime, input, *args)
|
173
|
+
end
|
174
|
+
|
175
|
+
# @todo
|
176
|
+
def validate_input(input)
|
177
|
+
unless self.class.accepts_something?
|
178
|
+
return input
|
179
|
+
end
|
142
180
|
unless input.is_a?(Item)
|
143
181
|
input = self.class.accepts.map { |type| Item.try(type, input) }.compact.first
|
144
182
|
end
|
145
183
|
if input.nil?
|
146
|
-
input
|
184
|
+
raise(InvalidInput, input)
|
147
185
|
end
|
148
186
|
unless self.class.accepts?(input.type)
|
149
187
|
raise(InvalidInput, input)
|
150
188
|
end
|
151
|
-
|
152
|
-
begin
|
153
|
-
block.call(input, *args)
|
154
|
-
rescue NameError
|
155
|
-
raise RuntimeMissing
|
156
|
-
end
|
157
|
-
else
|
158
|
-
runtime.instance_exec(input, *args, &self.block)
|
159
|
-
end
|
189
|
+
input
|
160
190
|
end
|
161
191
|
|
162
192
|
# Returns human readable action name.
|
@@ -198,7 +228,7 @@ module Saper
|
|
198
228
|
# Returns Proc that encapsulates action logic (i.e. processes data).
|
199
229
|
# @return [Proc]
|
200
230
|
def block
|
201
|
-
self.class.run || Proc.new { |input, *args| input }
|
231
|
+
self.class.run || Proc.new { |runtime, input, *args| input }
|
202
232
|
end
|
203
233
|
|
204
234
|
# Returns string representation of Action.
|
data/lib/saper/core/argument.rb
CHANGED
@@ -43,7 +43,11 @@ module Saper
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
#
|
46
|
+
# Returns a new instacne of Saper::Argument.
|
47
|
+
# @option opts[Object] :value
|
48
|
+
# @option opts[Saper::Action] :action
|
49
|
+
# @option opts[Boolean] :optional
|
50
|
+
# @return [Saper::Argument]
|
47
51
|
def initialize(opts = {})
|
48
52
|
@value = nil
|
49
53
|
@opts = opts
|
@@ -52,7 +56,9 @@ module Saper
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
55
|
-
#
|
59
|
+
# Sets new value and returns self.
|
60
|
+
# @param value [Object]
|
61
|
+
# @return [self]
|
56
62
|
def set(value)
|
57
63
|
unless valid?(value)
|
58
64
|
raise InvalidArgument, value
|
@@ -62,42 +68,52 @@ module Saper
|
|
62
68
|
self
|
63
69
|
end
|
64
70
|
|
65
|
-
#
|
71
|
+
# Returns true if supplied value is accepted by this argument type. Subclasses should override this method.
|
72
|
+
# @param value [Object]
|
73
|
+
# @return [Boolean]
|
66
74
|
def valid?(value)
|
67
75
|
true
|
68
76
|
end
|
69
77
|
|
70
|
-
#
|
78
|
+
# Returns normalized value.
|
79
|
+
# Subclasses should overrid this method. Subclasses may override this method.
|
80
|
+
# @param value [Object]
|
81
|
+
# @param value [Object]
|
71
82
|
def normalize(value)
|
72
83
|
value
|
73
84
|
end
|
74
85
|
|
75
|
-
#
|
86
|
+
# Returns argument value. Subclasses may override this method.
|
87
|
+
# @return [Object]
|
76
88
|
def value
|
77
89
|
@value
|
78
90
|
end
|
79
91
|
|
80
|
-
#
|
92
|
+
# Returns serialized representation of argument's value. Subclasses may override this method.
|
81
93
|
def serialize
|
82
94
|
value
|
83
95
|
end
|
84
96
|
|
85
|
-
#
|
97
|
+
# Returns true if argument value is mandatory.
|
98
|
+
# @return [Boolean]
|
86
99
|
def mandatory?
|
87
100
|
not optional?
|
88
101
|
end
|
89
102
|
|
90
|
-
#
|
91
|
-
|
92
|
-
@opts[:action]
|
93
|
-
end
|
94
|
-
|
95
|
-
# @todo
|
103
|
+
# Returns true if argument value is optional.
|
104
|
+
# @return [Boolean]
|
96
105
|
def optional?
|
97
106
|
@opts[:optional] == true
|
98
107
|
end
|
99
108
|
|
100
|
-
#
|
109
|
+
# Returns parent Action instance that this Argument belongs to.
|
110
|
+
# @return [Saper::Action]
|
111
|
+
def action
|
112
|
+
@opts[:action]
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns String representation of argument's value.
|
116
|
+
# @return [String]
|
101
117
|
def to_string
|
102
118
|
value.to_s.inspect
|
103
119
|
end
|