mechanize 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mechanize might be problematic. Click here for more details.
- data/CHANGELOG +17 -0
- data/NOTES +33 -0
- data/lib/mechanize.rb +2 -1
- data/lib/mechanize/form.rb +35 -6
- data/lib/mechanize/form_elements.rb +128 -26
- data/lib/mechanize/mech_version.rb +1 -1
- data/lib/mechanize/module.rb +6 -0
- data/test/htdocs/form_multi_select.html +16 -0
- data/test/htdocs/form_no_input_name.html +16 -0
- data/test/htdocs/form_select.html +16 -0
- data/test/htdocs/form_select_all.html +16 -0
- data/test/htdocs/form_select_none.html +16 -0
- data/test/htdocs/form_select_noopts.html +10 -0
- data/test/htdocs/form_set_fields.html +14 -0
- data/test/tc_form_no_inputname.rb +22 -0
- data/test/tc_forms.rb +1 -0
- data/test/tc_mech.rb +2 -4
- data/test/tc_multi_select.rb +113 -0
- data/test/tc_select.rb +104 -0
- data/test/tc_select_all.rb +23 -0
- data/test/tc_select_none.rb +23 -0
- data/test/tc_select_noopts.rb +23 -0
- data/test/tc_set_fields.rb +43 -0
- data/test/ts_mech.rb +7 -0
- metadata +114 -98
data/CHANGELOG
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
= Mechanize CHANGELOG
|
2
2
|
|
3
|
+
== 0.5.2
|
4
|
+
|
5
|
+
* Fixed a bug with input names that are nil
|
6
|
+
* Added a warning when using attr_finder because attr_finder will be deprecated
|
7
|
+
in 0.6.0 in favor of method calls. So this syntax:
|
8
|
+
@agent.links(:text => 'foo')
|
9
|
+
should be changed to this:
|
10
|
+
@agent.links.text('foo')
|
11
|
+
* Added support for selecting multiple options in select tags that support
|
12
|
+
multiple options. See WWW::Mechanize::MultiSelectList.
|
13
|
+
* New select list methods have been added, select_all, select_none.
|
14
|
+
* Options for select lists can now be "clicked" which toggles their selection,
|
15
|
+
they can be "selected" and "unselected". See WWW::Mechanize::Option
|
16
|
+
* Added a method to set multiple fields at the same time,
|
17
|
+
WWW::Mechanize::Form#set_fields. Which can be used like so:
|
18
|
+
form.set_fields( :foo => 'bar', :name => 'Aaron' )
|
19
|
+
|
3
20
|
== 0.5.1
|
4
21
|
|
5
22
|
* Fixed bug with file uploads
|
data/NOTES
CHANGED
@@ -1,5 +1,38 @@
|
|
1
1
|
= Mechanize Release Notes
|
2
2
|
|
3
|
+
== 0.5.2
|
4
|
+
|
5
|
+
This release comes with a few cool new features. First, support for select
|
6
|
+
lists which are "multi" has been added. This means that you can select
|
7
|
+
multiple values for a select list that has the "multiple" attribute. See
|
8
|
+
WWW::Mechanize::MultiSelectList for more information.
|
9
|
+
|
10
|
+
New methods for select lists have been added. You can use the select_all
|
11
|
+
method to select all options and select_none to select none to select no
|
12
|
+
options. Options can now be "selected" which selects an option, "unselected",
|
13
|
+
which unselects an option, and "clicked" which toggles the current status of
|
14
|
+
the option. What this means is that instead of having to select the first
|
15
|
+
option like this:
|
16
|
+
select_list.value = select_list.options.first.value
|
17
|
+
You can select the first option by just saying this:
|
18
|
+
select_list.options.first.select
|
19
|
+
Of course you can still set the select list to an arbitrary value by just
|
20
|
+
setting the value of the select list.
|
21
|
+
|
22
|
+
A new method has been added to Form so that multiple fields can be set at the
|
23
|
+
same time. To set 'foo', and 'name' at the same time on the form, you can do
|
24
|
+
the following:
|
25
|
+
form.set_fields( :foo => 'bar', :name => 'Aaron' )
|
26
|
+
Or to set the second fields named 'name' you can do the following:
|
27
|
+
form.set_fields( :name => ['Aaron', 1] )
|
28
|
+
|
29
|
+
Finally, attr_finder has been deprecated, and all syntax like this:
|
30
|
+
@agent.links(:text => 'foo')
|
31
|
+
needs to be changed to:
|
32
|
+
@agent.links.text('foo')
|
33
|
+
With this release you will just get a warning, and the code will be removed in
|
34
|
+
0.6.0.
|
35
|
+
|
3
36
|
== 0.5.1
|
4
37
|
|
5
38
|
This release is a small bugfix release. The main bug fixed in this release is
|
data/lib/mechanize.rb
CHANGED
@@ -384,9 +384,10 @@ class Mechanize
|
|
384
384
|
def self.build_query_string(parameters)
|
385
385
|
vals = []
|
386
386
|
parameters.each { |k,v|
|
387
|
+
next if k.nil?
|
387
388
|
vals <<
|
388
389
|
[WEBrick::HTTPUtils.escape_form(k),
|
389
|
-
WEBrick::HTTPUtils.escape_form(v)].join("=")
|
390
|
+
WEBrick::HTTPUtils.escape_form(v.to_s)].join("=")
|
390
391
|
}
|
391
392
|
|
392
393
|
vals.join("&")
|
data/lib/mechanize/form.rb
CHANGED
@@ -63,11 +63,11 @@ module WWW
|
|
63
63
|
|
64
64
|
fields().each do |f|
|
65
65
|
next unless f.value
|
66
|
-
query
|
66
|
+
query.push(*f.query_value)
|
67
67
|
end
|
68
68
|
|
69
69
|
checkboxes().each do |f|
|
70
|
-
query
|
70
|
+
query.push(*f.query_value) if f.checked
|
71
71
|
end
|
72
72
|
|
73
73
|
radio_groups = {}
|
@@ -82,14 +82,14 @@ module WWW
|
|
82
82
|
|
83
83
|
if checked.size == 1
|
84
84
|
f = checked.first
|
85
|
-
query
|
85
|
+
query.push(*f.query_value)
|
86
86
|
elsif checked.size > 1
|
87
87
|
raise "multiple radiobuttons are checked in the same group!"
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
@clicked_buttons.each { |b|
|
92
|
-
b.
|
92
|
+
query.push(*b.query_value)
|
93
93
|
}
|
94
94
|
|
95
95
|
query
|
@@ -136,9 +136,14 @@ module WWW
|
|
136
136
|
@checkboxes = WWW::Mechanize::List.new
|
137
137
|
|
138
138
|
@elements_node.each_recursive {|node|
|
139
|
+
type = (node.attributes['type'] || 'text').downcase
|
140
|
+
|
141
|
+
# Don't add fields that don't have a name
|
142
|
+
next if type != 'submit' && node.attributes['name'].nil?
|
143
|
+
|
139
144
|
case node.name.downcase
|
140
145
|
when 'input'
|
141
|
-
case
|
146
|
+
case type
|
142
147
|
when 'text', 'password', 'hidden', 'int'
|
143
148
|
@fields << Field.new(node.attributes['name'], node.attributes['value'] || '')
|
144
149
|
when 'radio'
|
@@ -155,7 +160,11 @@ module WWW
|
|
155
160
|
when 'textarea'
|
156
161
|
@fields << Field.new(node.attributes['name'], node.all_text)
|
157
162
|
when 'select'
|
158
|
-
|
163
|
+
if node.attributes.has_key? 'multiple'
|
164
|
+
@fields << MultiSelectList.new(node.attributes['name'], node)
|
165
|
+
else
|
166
|
+
@fields << SelectList.new(node.attributes['name'], node)
|
167
|
+
end
|
159
168
|
end
|
160
169
|
}
|
161
170
|
end
|
@@ -214,6 +223,26 @@ module WWW
|
|
214
223
|
fields.find { |f| f.name.eql? field_name }
|
215
224
|
end
|
216
225
|
|
226
|
+
# This method sets multiple fields on the form. It takes a list of field
|
227
|
+
# name, value pairs. If there is more than one field found with the
|
228
|
+
# same name, this method will set the first one found. If you want to
|
229
|
+
# set the value of a duplicate field, use a value which is an Array with
|
230
|
+
# the second value of the array as the index in to the form. The index
|
231
|
+
# is zero based. For example, to set the second field named 'foo', you
|
232
|
+
# could do the following:
|
233
|
+
# form.set_fields( :foo => ['bar', 1] )
|
234
|
+
def set_fields(fields = {})
|
235
|
+
fields.each do |k,v|
|
236
|
+
value = nil
|
237
|
+
index = 0
|
238
|
+
v.each do |val|
|
239
|
+
index = val.to_i unless value.nil?
|
240
|
+
value = val if value.nil?
|
241
|
+
end
|
242
|
+
self.fields.name(k.to_s).[](index).value = value
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
217
246
|
# Treat form fields like accessors.
|
218
247
|
def method_missing(id,*args)
|
219
248
|
method = id.to_s.gsub(/=$/, '')
|
@@ -16,6 +16,10 @@ module WWW
|
|
16
16
|
def inspect
|
17
17
|
"#{name} = #{@value}"
|
18
18
|
end
|
19
|
+
|
20
|
+
def query_value
|
21
|
+
[[@name, @value || '']]
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
# This class represents a file upload field found in a form. To use this
|
@@ -40,9 +44,6 @@ module WWW
|
|
40
44
|
|
41
45
|
# This class represents a Submit button in a form.
|
42
46
|
class Button < Field
|
43
|
-
def add_to_query(query)
|
44
|
-
query << [@name, @value || ''] if @name
|
45
|
-
end
|
46
47
|
end
|
47
48
|
|
48
49
|
# This class represents an image button in a form. Use the x and y methods
|
@@ -56,12 +57,10 @@ module WWW
|
|
56
57
|
super(name, value)
|
57
58
|
end
|
58
59
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
query << [@name + ".y", (@y || 0).to_s]
|
64
|
-
end
|
60
|
+
def query_value
|
61
|
+
super <<
|
62
|
+
[@name + ".x", (@x || 0).to_s] <<
|
63
|
+
[@name + ".y", (@y || 0).to_s]
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
@@ -79,50 +78,153 @@ module WWW
|
|
79
78
|
# This class represents a check box found in a Form. To activate the
|
80
79
|
# CheckBox in the Form, set the checked method to true.
|
81
80
|
class CheckBox < RadioButton
|
81
|
+
def query_value
|
82
|
+
[[@name, @value || "on"]]
|
83
|
+
end
|
82
84
|
end
|
83
85
|
|
84
|
-
# This class represents a select list
|
85
|
-
# value
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
86
|
+
# This class represents a select list where multiple values can be selected.
|
87
|
+
# MultiSelectList#value= accepts an array, and those values are used as
|
88
|
+
# values for the select list. For example, to select multiple values,
|
89
|
+
# simply do this:
|
90
|
+
# list.value = ['one', 'two']
|
91
|
+
# Single values are still supported, so these two are the same:
|
92
|
+
# list.value = ['one']
|
93
|
+
# list.value = 'one'
|
94
|
+
class MultiSelectList < Field
|
90
95
|
attr_accessor :options
|
91
96
|
|
92
97
|
def initialize(name, node)
|
93
|
-
value =
|
98
|
+
value = []
|
94
99
|
@options = WWW::Mechanize::List.new
|
95
100
|
|
96
101
|
# parse
|
97
102
|
node.each_recursive {|n|
|
98
103
|
if n.name.downcase == 'option'
|
99
|
-
option = Option.new(n)
|
104
|
+
option = Option.new(n, self)
|
100
105
|
@options << option
|
101
|
-
value = option.value if option.selected && value.nil?
|
102
106
|
end
|
103
107
|
}
|
104
|
-
value = @options.first.value if (value == nil && @options.first)
|
105
108
|
super(name, value)
|
106
109
|
end
|
107
110
|
|
108
|
-
|
111
|
+
def query_value
|
112
|
+
value.collect { |v| [name, v] }
|
113
|
+
end
|
114
|
+
|
115
|
+
# Select no options
|
116
|
+
def select_none
|
117
|
+
@value = []
|
118
|
+
options.each { |o| o.unselect }
|
119
|
+
end
|
120
|
+
|
121
|
+
# Select all options
|
122
|
+
def select_all
|
123
|
+
@value = []
|
124
|
+
options.each { |o| o.select }
|
125
|
+
end
|
126
|
+
|
127
|
+
# Get a list of all selected options
|
128
|
+
def selected_options
|
129
|
+
@options.find_all { |o| o.selected? }
|
130
|
+
end
|
131
|
+
|
132
|
+
def value=(values)
|
133
|
+
select_none
|
134
|
+
values.each do |value|
|
135
|
+
option = options.find { |o| o.value == value }
|
136
|
+
if option.nil?
|
137
|
+
@value.push(value)
|
138
|
+
else
|
139
|
+
option.select
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
109
143
|
|
110
|
-
def value
|
111
|
-
|
144
|
+
def value
|
145
|
+
value = []
|
146
|
+
value.push(*@value)
|
147
|
+
value.push(*selected_options.collect { |o| o.value })
|
148
|
+
value
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# This class represents a select list or drop down box in a Form. Set the
|
153
|
+
# value for the list by calling SelectList#value=. SelectList contains a
|
154
|
+
# list of Option that were found. After finding the correct option, set
|
155
|
+
# the select lists value to the option value:
|
156
|
+
# selectlist.value = selectlist.options.first.value
|
157
|
+
# Options can also be selected by "clicking" or selecting them. See Option
|
158
|
+
class SelectList < MultiSelectList
|
159
|
+
def initialize(name, node)
|
160
|
+
super(name, node)
|
161
|
+
if selected_options.length > 1
|
162
|
+
selected_options.reverse[1..selected_options.length].each do |o|
|
163
|
+
o.unselect
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def value
|
169
|
+
value = super
|
170
|
+
if value.length > 0
|
171
|
+
value.last
|
172
|
+
elsif @options.length > 0
|
173
|
+
@options.first.value
|
174
|
+
else
|
175
|
+
nil
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def value=(new)
|
180
|
+
if new.respond_to? :first
|
181
|
+
super([new.first])
|
182
|
+
else
|
183
|
+
super([new.to_s])
|
184
|
+
end
|
112
185
|
end
|
113
186
|
end
|
114
187
|
|
115
188
|
# This class contains option an option found within SelectList. A
|
116
|
-
# SelectList can have many Option classes associated with it.
|
189
|
+
# SelectList can have many Option classes associated with it. An option
|
190
|
+
# can be selected by calling Option#select, or Option#click. For example,
|
191
|
+
# select the first option in a list:
|
192
|
+
# select_list.first.select
|
117
193
|
class Option
|
118
|
-
attr_reader :value, :selected, :text
|
194
|
+
attr_reader :value, :selected, :text, :select_list
|
119
195
|
|
120
196
|
alias :to_s :value
|
197
|
+
alias :selected? :selected
|
121
198
|
|
122
|
-
def initialize(node)
|
199
|
+
def initialize(node, select_list)
|
123
200
|
@text = node.all_text
|
124
201
|
@value = node.attributes['value']
|
125
|
-
@selected = node.attributes
|
202
|
+
@selected = node.attributes.has_key?('selected') ? true : false
|
203
|
+
@select_list = select_list # The select list this option belongs to
|
204
|
+
end
|
205
|
+
|
206
|
+
# Select this option
|
207
|
+
def select
|
208
|
+
unselect_peers
|
209
|
+
@selected = true
|
210
|
+
end
|
211
|
+
|
212
|
+
# Unselect this option
|
213
|
+
def unselect
|
214
|
+
@selected = false
|
215
|
+
end
|
216
|
+
|
217
|
+
# Toggle the selection value of this option
|
218
|
+
def click
|
219
|
+
unselect_peers
|
220
|
+
@selected = !@selected
|
221
|
+
end
|
222
|
+
|
223
|
+
private
|
224
|
+
def unselect_peers
|
225
|
+
if @select_list.instance_of? WWW::Mechanize::SelectList
|
226
|
+
@select_list.select_none
|
227
|
+
end
|
126
228
|
end
|
127
229
|
end
|
128
230
|
end
|
data/lib/mechanize/module.rb
CHANGED
@@ -5,6 +5,12 @@ class Module # :nodoc:
|
|
5
5
|
if hash == nil
|
6
6
|
@#{sym.to_s}
|
7
7
|
else
|
8
|
+
err = []
|
9
|
+
hash.each \{ |k,v|
|
10
|
+
err << \"#\{k\}('#\{v\}')"
|
11
|
+
\}
|
12
|
+
warn("attr_finder will be deprecated in " +
|
13
|
+
"0.6.0. Please switch to: #\{err.join('.')\}")
|
8
14
|
@#{sym.to_s}.find_all do |t|
|
9
15
|
found = true
|
10
16
|
hash.each_key \{ |key|
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<form name="form1" method="post" action="/form_post">
|
4
|
+
<select name="list" multiple size="3">
|
5
|
+
<option value="1">Option 1</option>
|
6
|
+
<option value="2" selected>Option 2</option>
|
7
|
+
<option value="3">Option 3</option>
|
8
|
+
<option value="4">Option 4</option>
|
9
|
+
<option value="5">Option 5</option>
|
10
|
+
<option value="6">Option 6</option>
|
11
|
+
</select>
|
12
|
+
<br />
|
13
|
+
<input type="submit" value="Submit" />
|
14
|
+
</form>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<head><title>Input with no name</title></head>
|
3
|
+
<body>
|
4
|
+
<form name="test" action="/form_post" method="post">
|
5
|
+
<input type="text" /><br />
|
6
|
+
<input type="password" /><br />
|
7
|
+
<input type="hidden" /><br />
|
8
|
+
<input type="radio" /><br />
|
9
|
+
<input type="checkbox" /><br />
|
10
|
+
<input type="file" /><br />
|
11
|
+
<textarea></textarea>
|
12
|
+
<select></select>
|
13
|
+
<input type="submit" />
|
14
|
+
</form>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<form name="form1" method="post" action="/form_post">
|
4
|
+
<select name="list">
|
5
|
+
<option value="1">Option 1</option>
|
6
|
+
<option value="2" selected>Option 2</option>
|
7
|
+
<option value="3">Option 3</option>
|
8
|
+
<option value="4">Option 4</option>
|
9
|
+
<option value="5">Option 5</option>
|
10
|
+
<option value="6">Option 6</option>
|
11
|
+
</select>
|
12
|
+
<br />
|
13
|
+
<input type="submit" value="Submit" />
|
14
|
+
</form>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<form name="form1" method="post" action="/form_post">
|
4
|
+
<select name="list">
|
5
|
+
<option value="1" selected>Option 1</option>
|
6
|
+
<option value="2" selected>Option 2</option>
|
7
|
+
<option value="3" selected>Option 3</option>
|
8
|
+
<option value="4" selected>Option 4</option>
|
9
|
+
<option value="5" selected>Option 5</option>
|
10
|
+
<option value="6" selected>Option 6</option>
|
11
|
+
</select>
|
12
|
+
<br />
|
13
|
+
<input type="submit" value="Submit" />
|
14
|
+
</form>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<body>
|
3
|
+
<form name="form1" method="post" action="/form_post">
|
4
|
+
<select name="list">
|
5
|
+
<option value="1">Option 1</option>
|
6
|
+
<option value="2">Option 2</option>
|
7
|
+
<option value="3">Option 3</option>
|
8
|
+
<option value="4">Option 4</option>
|
9
|
+
<option value="5">Option 5</option>
|
10
|
+
<option value="6">Option 6</option>
|
11
|
+
</select>
|
12
|
+
<br />
|
13
|
+
<input type="submit" value="Submit" />
|
14
|
+
</form>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>HTML for tc_set_fields</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<form name="set_fields" method="post" action="/form_post">
|
7
|
+
<input type="text" name="first_name" /><br />
|
8
|
+
<input type="text" name="first_name" /><br />
|
9
|
+
<input type="text" name="gender" /><br />
|
10
|
+
<input type="text" name="green[eggs]" /><br />
|
11
|
+
<input type="submit" value="Submit" /><br />
|
12
|
+
</form>
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class FormNoInputNameTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_no_input_name
|
16
|
+
page = @agent.get("http://localhost:#{PORT}/form_no_input_name.html")
|
17
|
+
form = page.forms.first
|
18
|
+
assert_equal(0, form.fields.length)
|
19
|
+
assert_equal(0, form.radiobuttons.length)
|
20
|
+
assert_equal(0, form.checkboxes.length)
|
21
|
+
end
|
22
|
+
end
|
data/test/tc_forms.rb
CHANGED
@@ -158,6 +158,7 @@ class FormsMechTest < Test::Unit::TestCase
|
|
158
158
|
|
159
159
|
# Now set all the fields
|
160
160
|
post_form.fields.name(/country/).value = s.options[1]
|
161
|
+
assert_equal('CANADA', post_form.country)
|
161
162
|
page = @agent.submit(post_form, post_form.buttons.first)
|
162
163
|
|
163
164
|
# Check that the submitted fields exist
|
data/test/tc_mech.rb
CHANGED
@@ -69,7 +69,7 @@ class MechMethodsTest < Test::Unit::TestCase
|
|
69
69
|
search = page.forms.find { |f| f.name == "f" }
|
70
70
|
assert_not_nil(search)
|
71
71
|
assert_not_nil(search.fields.name('q').first)
|
72
|
-
assert_not_nil(search.fields(
|
72
|
+
assert_not_nil(search.fields.name('hl').first)
|
73
73
|
assert_not_nil(search.fields.find { |f| f.name == 'ie' })
|
74
74
|
end
|
75
75
|
|
@@ -90,12 +90,10 @@ class MechMethodsTest < Test::Unit::TestCase
|
|
90
90
|
find_orig = page.frames.find_all { |f| f.name == 'frame1' }
|
91
91
|
find1 = page.frames.with.name('frame1')
|
92
92
|
find2 = page.frames.name('frame1')
|
93
|
-
find3 = page.frames(:name => 'frame1')
|
94
93
|
|
95
|
-
find_orig.zip(find1, find2
|
94
|
+
find_orig.zip(find1, find2).each { |a,b,c|
|
96
95
|
assert_equal(a, b)
|
97
96
|
assert_equal(a, c)
|
98
|
-
assert_equal(a, d)
|
99
97
|
}
|
100
98
|
end
|
101
99
|
|
@@ -0,0 +1,113 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class MultiSelectTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_select_none
|
16
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
17
|
+
form = page.forms.first
|
18
|
+
form.fields.name('list').first.select_none
|
19
|
+
page = @agent.submit(form)
|
20
|
+
assert_equal(0, page.links.length)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_select_all
|
24
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
25
|
+
form = page.forms.first
|
26
|
+
form.fields.name('list').first.select_all
|
27
|
+
page = @agent.submit(form)
|
28
|
+
assert_equal(6, page.links.length)
|
29
|
+
assert_equal(1, page.links.text('list:1').length)
|
30
|
+
assert_equal(1, page.links.text('list:2').length)
|
31
|
+
assert_equal(1, page.links.text('list:3').length)
|
32
|
+
assert_equal(1, page.links.text('list:4').length)
|
33
|
+
assert_equal(1, page.links.text('list:5').length)
|
34
|
+
assert_equal(1, page.links.text('list:6').length)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_click_all
|
38
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
39
|
+
form = page.forms.first
|
40
|
+
form.fields.name('list').first.options.each { |o| o.click }
|
41
|
+
page = @agent.submit(form)
|
42
|
+
assert_equal(5, page.links.length)
|
43
|
+
assert_equal(1, page.links.text('list:1').length)
|
44
|
+
assert_equal(1, page.links.text('list:3').length)
|
45
|
+
assert_equal(1, page.links.text('list:4').length)
|
46
|
+
assert_equal(1, page.links.text('list:5').length)
|
47
|
+
assert_equal(1, page.links.text('list:6').length)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_select_default
|
51
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
52
|
+
form = page.forms.first
|
53
|
+
page = @agent.submit(form)
|
54
|
+
assert_equal(1, page.links.length)
|
55
|
+
assert_equal(1, page.links.text('list:2').length)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_select_one
|
59
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
60
|
+
form = page.forms.first
|
61
|
+
form.list = 'Aaron'
|
62
|
+
assert_equal(['Aaron'], form.list)
|
63
|
+
page = @agent.submit(form)
|
64
|
+
assert_equal(1, page.links.length)
|
65
|
+
assert_equal('list:Aaron', page.links.first.text)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_select_two
|
69
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
70
|
+
form = page.forms.first
|
71
|
+
form.list = ['1', 'Aaron']
|
72
|
+
page = @agent.submit(form)
|
73
|
+
assert_equal(2, page.links.length)
|
74
|
+
assert_equal(1, page.links.text('list:1').length)
|
75
|
+
assert_equal(1, page.links.text('list:Aaron').length)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_select_three
|
79
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
80
|
+
form = page.forms.first
|
81
|
+
form.list = ['1', '2', '3']
|
82
|
+
page = @agent.submit(form)
|
83
|
+
assert_equal(3, page.links.length)
|
84
|
+
assert_equal(1, page.links.text('list:1').length)
|
85
|
+
assert_equal(1, page.links.text('list:2').length)
|
86
|
+
assert_equal(1, page.links.text('list:3').length)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_select_three_twice
|
90
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
91
|
+
form = page.forms.first
|
92
|
+
form.list = ['1', '2', '3']
|
93
|
+
form.list = ['1', '2', '3']
|
94
|
+
page = @agent.submit(form)
|
95
|
+
assert_equal(3, page.links.length)
|
96
|
+
assert_equal(1, page.links.text('list:1').length)
|
97
|
+
assert_equal(1, page.links.text('list:2').length)
|
98
|
+
assert_equal(1, page.links.text('list:3').length)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_select_with_click
|
102
|
+
page = @agent.get("http://localhost:#{PORT}/form_multi_select.html")
|
103
|
+
form = page.forms.first
|
104
|
+
form.list = ['1', 'Aaron']
|
105
|
+
form.fields.name('list').first.options[3].select
|
106
|
+
assert_equal(['1', 'Aaron', '4'].sort, form.list.sort)
|
107
|
+
page = @agent.submit(form)
|
108
|
+
assert_equal(3, page.links.length)
|
109
|
+
assert_equal(1, page.links.text('list:1').length)
|
110
|
+
assert_equal(1, page.links.text('list:Aaron').length)
|
111
|
+
assert_equal(1, page.links.text('list:4').length)
|
112
|
+
end
|
113
|
+
end
|
data/test/tc_select.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class SelectTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/form_select.html")
|
14
|
+
@form = @page.forms.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_select_none
|
18
|
+
@form.fields.name('list').first.select_none
|
19
|
+
assert_equal('1', @form.list)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_select_all
|
23
|
+
@form.fields.name('list').first.select_all
|
24
|
+
assert_equal('6', @form.list)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_correct_class
|
28
|
+
assert_instance_of(WWW::Mechanize::SelectList,
|
29
|
+
@form.fields.name('list').first)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_click_all
|
33
|
+
@form.fields.name('list').first.options.each { |o| o.click }
|
34
|
+
option_list = @form.fields.name('list').first.options
|
35
|
+
assert_not_nil(option_list)
|
36
|
+
assert_equal(6, option_list.length)
|
37
|
+
assert_equal(option_list.last.value, @form.list)
|
38
|
+
page = @agent.submit(@form)
|
39
|
+
assert_equal(1, page.links.length)
|
40
|
+
assert_equal(1, page.links.text("list:#{option_list.last}").length)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_select_default
|
44
|
+
assert_equal("2", @form.list)
|
45
|
+
page = @agent.submit(@form)
|
46
|
+
assert_equal(1, page.links.length)
|
47
|
+
assert_equal(1, page.links.text('list:2').length)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_select_one
|
51
|
+
@form.list = 'Aaron'
|
52
|
+
assert_equal('Aaron', @form.list)
|
53
|
+
page = @agent.submit(@form)
|
54
|
+
assert_equal(1, page.links.length)
|
55
|
+
assert_equal('list:Aaron', page.links.first.text)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_select_two
|
59
|
+
@form.list = ['1', 'Aaron']
|
60
|
+
assert_equal('1', @form.list)
|
61
|
+
page = @agent.submit(@form)
|
62
|
+
assert_equal(1, page.links.length)
|
63
|
+
assert_equal(1, page.links.text('list:1').length)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_select_three
|
67
|
+
@form.list = ['1', '2', '3']
|
68
|
+
assert_equal('1', @form.list)
|
69
|
+
page = @agent.submit(@form)
|
70
|
+
assert_equal(1, page.links.length)
|
71
|
+
assert_equal(1, page.links.text('list:1').length)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_select_three_twice
|
75
|
+
@form.list = ['1', '2', '3']
|
76
|
+
@form.list = ['1', '2', '3']
|
77
|
+
assert_equal('1', @form.list)
|
78
|
+
page = @agent.submit(@form)
|
79
|
+
assert_equal(1, page.links.length)
|
80
|
+
assert_equal(1, page.links.text('list:1').length)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_select_with_click
|
84
|
+
@form.list = ['1', 'Aaron']
|
85
|
+
@form.fields.name('list').first.options[3].select
|
86
|
+
assert_equal('4', @form.list)
|
87
|
+
page = @agent.submit(@form)
|
88
|
+
assert_equal(1, page.links.length)
|
89
|
+
assert_equal(1, page.links.text('list:4').length)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_click_twice
|
93
|
+
list = @form.fields.name('list').first
|
94
|
+
list.options[0].click
|
95
|
+
assert_equal('1', @form.list)
|
96
|
+
list.options[1].click
|
97
|
+
assert_equal('2', @form.list)
|
98
|
+
list.options.last.click
|
99
|
+
assert_equal('6', @form.list)
|
100
|
+
assert_equal(1, list.selected_options.length)
|
101
|
+
list.select_all
|
102
|
+
assert_equal(1, list.selected_options.length)
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class SelectAllTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/form_select_all.html")
|
14
|
+
@form = @page.forms.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_select_default
|
18
|
+
assert_equal("6", @form.list)
|
19
|
+
page = @agent.submit(@form)
|
20
|
+
assert_equal(1, page.links.length)
|
21
|
+
assert_equal(1, page.links.text('list:6').length)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class SelectNoneTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/form_select_none.html")
|
14
|
+
@form = @page.forms.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_select_default
|
18
|
+
assert_equal("1", @form.list)
|
19
|
+
page = @agent.submit(@form)
|
20
|
+
assert_equal(1, page.links.length)
|
21
|
+
assert_equal(1, page.links.text('list:1').length)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class SelectNoOptionsTest < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/form_select_noopts.html")
|
14
|
+
@form = @page.forms.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_select_default
|
18
|
+
assert_not_nil(@form.fields.name('list').first)
|
19
|
+
assert_nil(@form.list)
|
20
|
+
page = @agent.submit(@form)
|
21
|
+
assert_equal(0, page.links.length)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mechanize'
|
6
|
+
require 'test_includes'
|
7
|
+
|
8
|
+
class TestSetFields < Test::Unit::TestCase
|
9
|
+
include TestMethods
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@agent = WWW::Mechanize.new
|
13
|
+
@page = @agent.get("http://localhost:#{PORT}/form_set_fields.html")
|
14
|
+
@form = @page.forms.first
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_set_no_fields
|
18
|
+
before = {}
|
19
|
+
@form.fields.each { |f| before[f.name] = f.value }
|
20
|
+
@form.set_fields
|
21
|
+
before.each { |k,v| assert_equal(v, @form.send(k)) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_set_one_field
|
25
|
+
@form.set_fields( :gender => 'male' )
|
26
|
+
assert_equal('male', @form.gender)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_set_many_fields
|
30
|
+
@form.set_fields( :gender => 'male',
|
31
|
+
:first_name => 'Aaron',
|
32
|
+
'green[eggs]' => 'Ham'
|
33
|
+
)
|
34
|
+
assert_equal('male', @form.gender)
|
35
|
+
assert_equal('Aaron', @form.first_name)
|
36
|
+
assert_equal('Ham', @form.fields.name('green[eggs]').first.value)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_set_second_field
|
40
|
+
@form.set_fields( :first_name => ['Aaron', 1] )
|
41
|
+
assert_equal('Aaron', @form.fields.name('first_name')[1].value)
|
42
|
+
end
|
43
|
+
end
|
data/test/ts_mech.rb
CHANGED
@@ -27,6 +27,13 @@ require 'tc_save_file'
|
|
27
27
|
require 'tc_post_form'
|
28
28
|
require 'tc_pluggable_parser'
|
29
29
|
require 'tc_page'
|
30
|
+
require 'tc_form_no_inputname'
|
31
|
+
require 'tc_multi_select'
|
32
|
+
require 'tc_select_all'
|
33
|
+
require 'tc_select_none'
|
34
|
+
require 'tc_select'
|
35
|
+
require 'tc_select_noopts'
|
36
|
+
require 'tc_set_fields'
|
30
37
|
#require 'tc_proxy'
|
31
38
|
#require 'tc_ssl_server'
|
32
39
|
|
metadata
CHANGED
@@ -3,11 +3,11 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: mechanize
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.5.
|
7
|
-
date: 2006-07
|
6
|
+
version: 0.5.2
|
7
|
+
date: 2006-08-07 00:00:00 -07:00
|
8
8
|
summary: Mechanize provides automated web-browsing
|
9
9
|
require_paths:
|
10
|
-
|
10
|
+
- lib
|
11
11
|
email: aaronp@rubyforge.org
|
12
12
|
homepage: mechanize.rubyforge.org
|
13
13
|
rubyforge_project: mechanize
|
@@ -18,112 +18,128 @@ bindir: bin
|
|
18
18
|
has_rdoc: true
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
20
|
requirements:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
25
24
|
version:
|
26
25
|
platform: ruby
|
27
26
|
signing_key:
|
28
27
|
cert_chain:
|
29
28
|
post_install_message:
|
30
29
|
authors:
|
31
|
-
|
30
|
+
- Aaron Patterson
|
32
31
|
files:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
32
|
+
- test/tc_mech.rb
|
33
|
+
- test/ts_mech.rb
|
34
|
+
- test/tc_links.rb
|
35
|
+
- test/tc_select_all.rb
|
36
|
+
- test/tc_page.rb
|
37
|
+
- test/test_includes.rb
|
38
|
+
- test/tc_watches.rb
|
39
|
+
- test/tc_cookies.rb
|
40
|
+
- test/proxy.rb
|
41
|
+
- test/data
|
42
|
+
- test/tc_cookie_jar.rb
|
43
|
+
- test/tc_forms.rb
|
44
|
+
- test/tc_select_none.rb
|
45
|
+
- test/tc_multi_select.rb
|
46
|
+
- test/tc_pluggable_parser.rb
|
47
|
+
- test/tc_select_noopts.rb
|
48
|
+
- test/ssl_server.rb
|
49
|
+
- test/parse.rb
|
50
|
+
- test/tc_post_form.rb
|
51
|
+
- test/tc_parsing.rb
|
52
|
+
- test/test_mech.rb
|
53
|
+
- test/tc_errors.rb
|
54
|
+
- test/tc_authenticate.rb
|
55
|
+
- test/README
|
56
|
+
- test/tc_form_no_inputname.rb
|
57
|
+
- test/tc_upload.rb
|
58
|
+
- test/tc_cookie_class.rb
|
59
|
+
- test/tc_set_fields.rb
|
60
|
+
- test/tc_select.rb
|
61
|
+
- test/server.rb
|
62
|
+
- test/htdocs
|
63
|
+
- test/tc_ssl_server.rb
|
64
|
+
- test/tc_proxy.rb
|
65
|
+
- test/tc_frames.rb
|
66
|
+
- test/tc_response_code.rb
|
67
|
+
- test/servlets.rb
|
68
|
+
- test/tc_save_file.rb
|
69
|
+
- test/data/server.key
|
70
|
+
- test/data/server.csr
|
71
|
+
- test/data/server.pem
|
72
|
+
- test/data/server.crt
|
73
|
+
- test/data/htpasswd
|
74
|
+
- test/htdocs/file_upload.html
|
75
|
+
- test/htdocs/iframe_test.html
|
76
|
+
- test/htdocs/form_select_all.html
|
77
|
+
- test/htdocs/form_no_action.html
|
78
|
+
- test/htdocs/form_test.html
|
79
|
+
- test/htdocs/bad_form_test.html
|
80
|
+
- test/htdocs/alt_text.html
|
81
|
+
- test/htdocs/frame_test.html
|
82
|
+
- test/htdocs/form_multi_select.html
|
83
|
+
- test/htdocs/form_set_fields.html
|
84
|
+
- test/htdocs/index.html
|
85
|
+
- test/htdocs/find_link.html
|
86
|
+
- test/htdocs/google.html
|
87
|
+
- test/htdocs/no_title_test.html
|
88
|
+
- test/htdocs/button.jpg
|
89
|
+
- test/htdocs/form_multival.html
|
90
|
+
- test/htdocs/form_select_none.html
|
91
|
+
- test/htdocs/form_select_noopts.html
|
92
|
+
- test/htdocs/form_select.html
|
93
|
+
- test/htdocs/form_no_input_name.html
|
94
|
+
- lib/mechanize.rb
|
95
|
+
- lib/mechanize
|
96
|
+
- lib/mechanize/errors.rb
|
97
|
+
- lib/mechanize/page.rb
|
98
|
+
- lib/mechanize/parsing.rb
|
99
|
+
- lib/mechanize/form_elements.rb
|
100
|
+
- lib/mechanize/net-overrides
|
101
|
+
- lib/mechanize/cookie.rb
|
102
|
+
- lib/mechanize/mech_version.rb
|
103
|
+
- lib/mechanize/list.rb
|
104
|
+
- lib/mechanize/module.rb
|
105
|
+
- lib/mechanize/pluggable_parsers.rb
|
106
|
+
- lib/mechanize/page_elements.rb
|
107
|
+
- lib/mechanize/form.rb
|
108
|
+
- lib/mechanize/net-overrides/net
|
109
|
+
- lib/mechanize/net-overrides/net/http.rb
|
110
|
+
- lib/mechanize/net-overrides/net/https.rb
|
111
|
+
- lib/mechanize/net-overrides/net/protocol.rb
|
112
|
+
- README
|
113
|
+
- EXAMPLES
|
114
|
+
- CHANGELOG
|
115
|
+
- LICENSE
|
116
|
+
- NOTES
|
104
117
|
test_files: []
|
118
|
+
|
105
119
|
rdoc_options:
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
120
|
+
- --main
|
121
|
+
- README
|
122
|
+
- --title
|
123
|
+
- "'WWW::Mechanize RDoc'"
|
110
124
|
extra_rdoc_files:
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
125
|
+
- README
|
126
|
+
- EXAMPLES
|
127
|
+
- CHANGELOG
|
128
|
+
- LICENSE
|
129
|
+
- NOTES
|
116
130
|
executables: []
|
131
|
+
|
117
132
|
extensions: []
|
133
|
+
|
118
134
|
requirements: []
|
135
|
+
|
119
136
|
dependencies:
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
version:
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: ruby-web
|
139
|
+
version_requirement:
|
140
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 1.1.0
|
145
|
+
version:
|