saper 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|