mechanize 2.14.1 → 2.14.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/lib/mechanize/directory_saver.rb +2 -1
  4. data/lib/mechanize/file_saver.rb +2 -0
  5. data/lib/mechanize/parser.rb +33 -3
  6. data/lib/mechanize/test_case.rb +2 -9
  7. data/lib/mechanize/version.rb +1 -1
  8. metadata +3 -172
  9. data/.autotest +0 -6
  10. data/.github/dependabot.yml +0 -11
  11. data/.github/workflows/ci.yml +0 -43
  12. data/.github/workflows/upstream.yml +0 -51
  13. data/.gitignore +0 -15
  14. data/.yardopts +0 -8
  15. data/Gemfile +0 -12
  16. data/Rakefile +0 -56
  17. data/examples/flickr_upload.rb +0 -22
  18. data/examples/latest_user_agents.rb +0 -100
  19. data/examples/mech-dump.rb +0 -5
  20. data/examples/proxy_req.rb +0 -7
  21. data/examples/rubygems.rb +0 -23
  22. data/examples/spider.rb +0 -22
  23. data/examples/wikipedia_links_to_philosophy.rb +0 -158
  24. data/mechanize.gemspec +0 -74
  25. data/test/data/htpasswd +0 -1
  26. data/test/data/server.crt +0 -16
  27. data/test/data/server.csr +0 -12
  28. data/test/data/server.key +0 -15
  29. data/test/data/server.pem +0 -15
  30. data/test/test_mechanize.rb +0 -1382
  31. data/test/test_mechanize_cookie.rb +0 -559
  32. data/test/test_mechanize_cookie_jar.rb +0 -615
  33. data/test/test_mechanize_directory_saver.rb +0 -60
  34. data/test/test_mechanize_download.rb +0 -102
  35. data/test/test_mechanize_element_not_found_error.rb +0 -16
  36. data/test/test_mechanize_file.rb +0 -118
  37. data/test/test_mechanize_file_connection.rb +0 -40
  38. data/test/test_mechanize_file_request.rb +0 -26
  39. data/test/test_mechanize_file_response.rb +0 -48
  40. data/test/test_mechanize_file_saver.rb +0 -22
  41. data/test/test_mechanize_form.rb +0 -1025
  42. data/test/test_mechanize_form_check_box.rb +0 -49
  43. data/test/test_mechanize_form_encoding.rb +0 -110
  44. data/test/test_mechanize_form_field.rb +0 -78
  45. data/test/test_mechanize_form_file_upload.rb +0 -21
  46. data/test/test_mechanize_form_image_button.rb +0 -13
  47. data/test/test_mechanize_form_keygen.rb +0 -34
  48. data/test/test_mechanize_form_multi_select_list.rb +0 -98
  49. data/test/test_mechanize_form_option.rb +0 -60
  50. data/test/test_mechanize_form_radio_button.rb +0 -96
  51. data/test/test_mechanize_form_select_list.rb +0 -81
  52. data/test/test_mechanize_form_textarea.rb +0 -53
  53. data/test/test_mechanize_headers.rb +0 -36
  54. data/test/test_mechanize_history.rb +0 -104
  55. data/test/test_mechanize_http_agent.rb +0 -2145
  56. data/test/test_mechanize_http_auth_challenge.rb +0 -64
  57. data/test/test_mechanize_http_auth_realm.rb +0 -56
  58. data/test/test_mechanize_http_auth_store.rb +0 -233
  59. data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
  60. data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
  61. data/test/test_mechanize_image.rb +0 -9
  62. data/test/test_mechanize_link.rb +0 -171
  63. data/test/test_mechanize_page.rb +0 -295
  64. data/test/test_mechanize_page_encoding.rb +0 -215
  65. data/test/test_mechanize_page_frame.rb +0 -17
  66. data/test/test_mechanize_page_image.rb +0 -191
  67. data/test/test_mechanize_page_link.rb +0 -377
  68. data/test/test_mechanize_page_meta_refresh.rb +0 -151
  69. data/test/test_mechanize_parser.rb +0 -316
  70. data/test/test_mechanize_pluggable_parser.rb +0 -68
  71. data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
  72. data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
  73. data/test/test_mechanize_response_read_error.rb +0 -29
  74. data/test/test_mechanize_subclass.rb +0 -23
  75. data/test/test_mechanize_util.rb +0 -144
  76. data/test/test_mechanize_xml_file.rb +0 -30
  77. data/test/test_multi_select.rb +0 -120
@@ -1,316 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeParser < Mechanize::TestCase
5
-
6
- class P
7
- include Mechanize::Parser
8
-
9
- attr_accessor :filename
10
- attr_accessor :response
11
- attr_accessor :uri
12
-
13
- def initialize
14
- @uri = URI 'http://example'
15
- @full_path = false
16
- end
17
- end
18
-
19
- def setup
20
- super
21
-
22
- @parser = P.new
23
- end
24
-
25
- def test_extract_filename
26
- @parser.response = {}
27
-
28
- assert_equal 'index.html', @parser.extract_filename
29
- end
30
-
31
- def test_extract_filename_content_disposition
32
- @parser.uri = URI 'http://example/foo'
33
-
34
- @parser.response = {
35
- 'content-disposition' => 'attachment; filename=genome.jpeg'
36
- }
37
-
38
- assert_equal 'genome.jpeg', @parser.extract_filename
39
- end
40
-
41
- def test_extract_filename_content_disposition_bad
42
- @parser.uri = URI 'http://example/foo'
43
-
44
- @parser.response = {
45
- 'content-disposition' => "inline; filename*=UTF-8''X%20Y.jpg"
46
- }
47
-
48
- assert_equal 'foo.html', @parser.extract_filename
49
-
50
- @parser.response = {
51
- 'content-disposition' => "inline; filename=\"\""
52
- }
53
-
54
- assert_equal 'foo.html', @parser.extract_filename
55
- end
56
-
57
- def test_extract_filename_content_disposition_path
58
- @parser.uri = URI 'http://example'
59
-
60
- @parser.response = {
61
- 'content-disposition' => 'attachment; filename="../genome.jpeg"'
62
- }
63
-
64
- assert_equal 'example/genome.jpeg', @parser.extract_filename(true)
65
-
66
- @parser.response = {
67
- 'content-disposition' => 'attachment; filename="foo/genome.jpeg"'
68
- }
69
-
70
- assert_equal 'example/genome.jpeg', @parser.extract_filename(true)
71
- end
72
-
73
- def test_extract_filename_content_disposition_path_windows
74
- @parser.uri = URI 'http://example'
75
-
76
- @parser.response = {
77
- 'content-disposition' => 'attachment; filename="..\\\\genome.jpeg"'
78
- }
79
-
80
- assert_equal 'example/genome.jpeg', @parser.extract_filename(true)
81
-
82
- @parser.response = {
83
- 'content-disposition' => 'attachment; filename="foo\\\\genome.jpeg"'
84
- }
85
-
86
- assert_equal 'example/genome.jpeg', @parser.extract_filename(true)
87
- end
88
-
89
- def test_extract_filename_content_disposition_full_path
90
- @parser.uri = URI 'http://example/foo'
91
-
92
- @parser.response = {
93
- 'content-disposition' => 'attachment; filename=genome.jpeg'
94
- }
95
-
96
- assert_equal 'example/genome.jpeg', @parser.extract_filename(true)
97
- end
98
-
99
- def test_extract_filename_content_disposition_quoted
100
- @parser.uri = URI 'http://example'
101
-
102
- @parser.response = {
103
- 'content-disposition' => 'attachment; filename="\"some \"file\""'
104
- }
105
-
106
- assert_equal '_some__file_', @parser.extract_filename
107
- end
108
-
109
- def test_extract_filename_content_disposition_special
110
- @parser.uri = URI 'http://example/foo'
111
-
112
- @parser.response = {
113
- 'content-disposition' => 'attachment; filename="/\\\\<>:\\"|?*"'
114
- }
115
-
116
- assert_equal '_______', @parser.extract_filename
117
-
118
- chars = (0..12).map { |c| c.chr }.join
119
- chars += "\\\r"
120
- chars += (14..31).map { |c| c.chr }.join
121
-
122
- @parser.response = {
123
- 'content-disposition' => "attachment; filename=\"#{chars}\""
124
- }
125
-
126
- assert_equal '_' * 32, @parser.extract_filename
127
- end
128
-
129
- def test_extract_filename_content_disposition_windows_special
130
- @parser.uri = URI 'http://example'
131
-
132
- windows_special = %w[
133
- AUX
134
- COM1
135
- COM2
136
- COM3
137
- COM4
138
- COM5
139
- COM6
140
- COM7
141
- COM8
142
- COM9
143
- CON
144
- LPT1
145
- LPT2
146
- LPT3
147
- LPT4
148
- LPT5
149
- LPT6
150
- LPT7
151
- LPT8
152
- LPT9
153
- NUL
154
- PRN
155
- ]
156
-
157
- windows_special.each do |special|
158
- @parser.response = {
159
- 'content-disposition' => "attachment; filename=#{special}"
160
- }
161
-
162
- assert_equal "_#{special}", @parser.extract_filename
163
- end
164
- end
165
-
166
- def test_extract_filename_content_disposition_empty
167
- @parser.uri = URI 'http://example'
168
-
169
- @parser.response = {
170
- 'content-disposition' => 'inline; filename="/"'
171
- }
172
-
173
- assert_equal '', @parser.extract_filename
174
- end
175
-
176
- def test_extract_filename_host
177
- @parser.response = {}
178
- @parser.uri = URI 'http://example'
179
-
180
- assert_equal 'example/index.html', @parser.extract_filename(true)
181
- end
182
-
183
- def test_extract_filename_special_character
184
- @parser.response = {}
185
-
186
- invisible = "\t\n\v\f\r"
187
-
188
- invisible.chars.each do |char|
189
- begin
190
- @parser.uri = URI "http://example/#{char}"
191
-
192
- assert_equal 'index.html', @parser.extract_filename, char.inspect
193
- rescue URI::InvalidURIError
194
- # ignore
195
- end
196
- end
197
-
198
- escaped = "<>\"\\|"
199
-
200
- escaped.chars.each do |char|
201
- escaped_char = CGI.escape char
202
-
203
- @parser.uri = URI "http://example/#{escaped_char}"
204
-
205
- assert_equal "#{escaped_char}.html", @parser.extract_filename, char
206
- end
207
-
208
- @parser.uri = URI "http://example/?"
209
-
210
- assert_equal 'index.html_', @parser.extract_filename, 'empty query'
211
-
212
- @parser.uri = URI "http://example/:"
213
-
214
- assert_equal '_.html', @parser.extract_filename, 'colon'
215
-
216
- @parser.uri = URI "http://example/*"
217
-
218
- assert_equal '_.html', @parser.extract_filename, 'asterisk'
219
- end
220
-
221
- def test_extract_filename_uri
222
- @parser.response = {}
223
- @parser.uri = URI 'http://example/foo'
224
-
225
- assert_equal 'foo.html', @parser.extract_filename
226
-
227
- @parser.uri += '/foo.jpg'
228
-
229
- assert_equal 'foo.jpg', @parser.extract_filename
230
- end
231
-
232
- def test_extract_filename_uri_full_path
233
- @parser.response = {}
234
- @parser.uri = URI 'http://example/foo'
235
-
236
- assert_equal 'example/foo.html', @parser.extract_filename(true)
237
-
238
- @parser.uri += '/foo.jpg'
239
-
240
- assert_equal 'example/foo.jpg', @parser.extract_filename(true)
241
- end
242
-
243
- def test_extract_filename_uri_query
244
- @parser.response = {}
245
- @parser.uri = URI 'http://example/?id=5'
246
-
247
- assert_equal 'index.html_id=5', @parser.extract_filename
248
-
249
- @parser.uri += '/foo.html?id=5'
250
-
251
- assert_equal 'foo.html_id=5', @parser.extract_filename
252
- end
253
-
254
- def test_extract_filename_uri_slash
255
- @parser.response = {}
256
- @parser.uri = URI 'http://example/foo/'
257
-
258
- assert_equal 'example/foo/index.html', @parser.extract_filename(true)
259
-
260
- @parser.uri += '/foo///'
261
-
262
- assert_equal 'example/foo/index.html', @parser.extract_filename(true)
263
- end
264
-
265
- def test_extract_filename_windows_special
266
- @parser.uri = URI 'http://example'
267
- @parser.response = {}
268
-
269
- windows_special = %w[
270
- AUX
271
- COM1
272
- COM2
273
- COM3
274
- COM4
275
- COM5
276
- COM6
277
- COM7
278
- COM8
279
- COM9
280
- CON
281
- LPT1
282
- LPT2
283
- LPT3
284
- LPT4
285
- LPT5
286
- LPT6
287
- LPT7
288
- LPT8
289
- LPT9
290
- NUL
291
- PRN
292
- ]
293
-
294
- windows_special.each do |special|
295
- @parser.uri += "/#{special}"
296
-
297
- assert_equal "_#{special}.html", @parser.extract_filename
298
- end
299
- end
300
-
301
- def test_fill_header
302
- @parser.fill_header 'a' => 'b'
303
-
304
- expected = { 'a' => 'b' }
305
-
306
- assert_equal expected, @parser.response
307
- end
308
-
309
- def test_fill_header_nil
310
- @parser.fill_header nil
311
-
312
- assert_empty @parser.response
313
- end
314
-
315
- end
316
-
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizePluggableParser < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @pp = @mech.pluggable_parser
10
- end
11
-
12
- def test_aref
13
- @pp['text/html'] = Mechanize::Download
14
-
15
- assert_equal Mechanize::Download, @pp['text/html']
16
- end
17
-
18
- def test_csv
19
- @pp.csv = Mechanize::Download
20
-
21
- assert_equal Mechanize::Download, @pp['text/csv']
22
- end
23
-
24
- def test_html
25
- assert_equal Mechanize::Page, @pp['text/html']
26
-
27
- @pp.html = Mechanize::Download
28
-
29
- assert_equal Mechanize::Download, @pp['text/html']
30
- end
31
-
32
- def test_parser
33
- assert_equal Mechanize::XmlFile, @pp.parser('text/xml')
34
- assert_equal Mechanize::File, @pp.parser(nil)
35
- end
36
-
37
- def test_parser_mime
38
- @pp['image/png'] = :png
39
-
40
- assert_equal :png, @pp.parser('x-image/x-png')
41
- assert_equal :png, @pp.parser('image/png')
42
- assert_equal Mechanize::Image, @pp.parser('image')
43
- end
44
-
45
- def test_parser_bogus
46
- assert_nil @pp['bogus']
47
-
48
- assert_equal Mechanize::File, @pp.parser('bogus')
49
- end
50
-
51
- def test_pdf
52
- @pp.pdf = Mechanize::Download
53
-
54
- assert_equal Mechanize::Download, @pp['application/pdf']
55
- end
56
-
57
- def test_xml
58
- assert_equal Mechanize::XmlFile, @pp['text/xml']
59
- assert_equal Mechanize::XmlFile, @pp['application/xml']
60
-
61
- @pp.xml = Mechanize::Download
62
-
63
- assert_equal Mechanize::Download, @pp['text/xml']
64
- assert_equal Mechanize::Download, @pp['application/xml']
65
- end
66
-
67
- end
68
-
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeRedirectLimitReachedError < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @error = Mechanize::RedirectLimitReachedError.new fake_page, 10
10
- end
11
-
12
- def test_message
13
- assert_equal 'Redirect limit of 10 reached', @error.message
14
- end
15
-
16
- def test_redirects
17
- assert_equal 10, @error.redirects
18
- end
19
-
20
- def test_response_code
21
- assert_equal 200, @error.response_code
22
- end
23
-
24
- end
25
-
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeRedirectNotGetOrHead < Mechanize::TestCase
5
-
6
- def test_to_s
7
- page = fake_page
8
-
9
- error = Mechanize::RedirectNotGetOrHeadError.new(page, :put)
10
-
11
- assert_match(/ PUT /, error.to_s)
12
- end
13
-
14
- end
15
-
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeResponseReadError < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- @error = 'error message'
10
- @response = Response.new
11
- @response['content-length'] = 3
12
- @body_io = StringIO.new 'body'
13
- end
14
-
15
- def test_force_parse
16
- @response['content-type'] = 'text/html'
17
- uri = URI 'http://example/'
18
-
19
- e = Mechanize::ResponseReadError.new @error, @response, @body_io, uri, @mech
20
-
21
- page = e.force_parse
22
-
23
- assert_kind_of Mechanize::Page, page
24
- assert_equal 'body', page.body
25
- assert_equal @mech, page.mech
26
- end
27
-
28
- end
29
-
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeSubclass < Mechanize::TestCase
5
-
6
- class Parent < Mechanize
7
- @html_parser = :parser
8
- @log = :log
9
- end
10
-
11
- class Child < Parent
12
- end
13
-
14
- def test_subclass_inherits_html_parser
15
- assert_equal :parser, Child.html_parser
16
- end
17
-
18
- def test_subclass_inherits_log
19
- assert_equal :log, Child.log
20
- end
21
-
22
- end
23
-
@@ -1,144 +0,0 @@
1
- # coding: utf-8
2
- # frozen_string_literal: true
3
-
4
- require 'mechanize/test_case'
5
-
6
- class TestMechanizeUtil < Mechanize::TestCase
7
-
8
- INPUTTED_VALUE = "テスト" # "test" in Japanese UTF-8 encoding
9
- CONTENT_ENCODING = 'Shift_JIS' # one of Japanese encoding
10
- ENCODED_VALUE = "\x83\x65\x83\x58\x83\x67".dup.force_encoding(::Encoding::SHIFT_JIS) # "test" in Japanese Shift_JIS encoding
11
-
12
- ENCODING_ERRORS = [EncodingError, Encoding::ConverterNotFoundError] # and so on
13
- ERROR_LOG_MESSAGE = /from_native_charset: Encoding::ConverterNotFoundError: form encoding: "UTF-eight"/
14
-
15
- INVALID_ENCODING = 'UTF-eight'
16
-
17
- def setup
18
- super
19
-
20
- @MU = Mechanize::Util
21
- @result = "not set"
22
- end
23
-
24
- def test_from_native_charset
25
- @result = @MU.from_native_charset(INPUTTED_VALUE, CONTENT_ENCODING)
26
- assert_equal ENCODED_VALUE, @result
27
- end
28
-
29
- def test_from_native_charset_returns_nil_when_no_string
30
- @result = @MU.from_native_charset(nil, CONTENT_ENCODING)
31
- assert_nil @result
32
- end
33
-
34
- def test_from_native_charset_doesnot_convert_when_no_encoding
35
- @result = @MU.from_native_charset(INPUTTED_VALUE, nil)
36
- refute_equal ENCODED_VALUE, @result
37
- assert_equal INPUTTED_VALUE, @result
38
- end
39
-
40
- def test_from_native_charset_doesnot_convert_when_not_nokogiri
41
- parser = Mechanize.html_parser
42
- Mechanize.html_parser = 'Another HTML Parser'
43
-
44
- @result = @MU.from_native_charset(INPUTTED_VALUE, CONTENT_ENCODING)
45
- refute_equal ENCODED_VALUE, @result
46
- assert_equal INPUTTED_VALUE, @result
47
- ensure
48
- Mechanize.html_parser = parser
49
- end
50
-
51
- def test_from_native_charset_raises_error_with_bad_encoding
52
- assert_raises(*ENCODING_ERRORS) do
53
- @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING)
54
- end
55
- end
56
-
57
- def test_from_native_charset_suppress_encoding_error_when_3rd_arg_is_true
58
- @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true)
59
-
60
- # HACK no assertion
61
- end
62
-
63
- def test_from_native_charset_doesnot_convert_when_encoding_error_raised_and_ignored
64
- @result = @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true)
65
-
66
- refute_equal ENCODED_VALUE, @result
67
- assert_equal INPUTTED_VALUE, @result
68
- end
69
-
70
- def test_from_native_charset_logs_form_when_encoding_error_raised
71
- sio = StringIO.new
72
- log = Logger.new(sio)
73
- log.level = Logger::DEBUG
74
-
75
- assert_raises(*ENCODING_ERRORS) do
76
- @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, nil, log)
77
- end
78
-
79
- assert_match ERROR_LOG_MESSAGE, sio.string
80
- end
81
-
82
- def test_from_native_charset_logs_form_when_encoding_error_is_ignored
83
- sio = StringIO.new
84
- log = Logger.new(sio)
85
- log.level = Logger::DEBUG
86
-
87
- @MU.from_native_charset(INPUTTED_VALUE, INVALID_ENCODING, true, log)
88
-
89
- assert_match ERROR_LOG_MESSAGE, sio.string
90
- end
91
-
92
- def test_self_html_unescape_entity
93
- assert_equal '&', @MU::html_unescape('&')
94
- assert_equal '&', @MU::html_unescape('&amp;')
95
- end
96
-
97
- def test_uri_escape
98
- assert_equal "%25", @MU.uri_escape("%")
99
- assert_equal "%", @MU.uri_escape("%", /[^%]/)
100
- end
101
-
102
- def test_build_query_string_simple
103
- input_params = [
104
- [:ids, 1],
105
- [:action, 'delete'],
106
- [:ids, 5],
107
- ]
108
-
109
- expected_params = [
110
- ['ids', '1'],
111
- ['action', 'delete'],
112
- ['ids', '5'],
113
- ]
114
-
115
- query = @MU.build_query_string(input_params)
116
-
117
- assert_equal expected_params, URI.decode_www_form(query)
118
- end
119
-
120
- def test_build_query_string_complex
121
- input_params = {
122
- number: 7,
123
- name: "\u{6B66}\u{8005}",
124
- "ids[]" => [1, 3, 5, 7],
125
- words: ["Sing", "Now!"],
126
- params: { x: "50%", y: "100%", t: [80, 160] },
127
- }
128
-
129
- expected_params = [
130
- ['number', '7'],
131
- ['name', "\u{6B66}\u{8005}"],
132
- ['ids[]', '1'], ['ids[]', '3'], ['ids[]', '5'], ['ids[]', '7'],
133
- ['words', 'Sing'], ['words', 'Now!'],
134
- ['params[x]', '50%'],
135
- ['params[y]', '100%'],
136
- ['params[t]', '80'], ['params[t]', '160'],
137
- ]
138
-
139
- query = @MU.build_query_string(input_params)
140
-
141
- assert_equal expected_params, URI.decode_www_form(query)
142
- end
143
- end
144
-
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'mechanize/test_case'
3
-
4
- class TestMechanizeXmlFile < Mechanize::TestCase
5
-
6
- def setup
7
- super
8
-
9
- uri = URI 'http://example.com/foo.xml'
10
- @xml = Mechanize::XmlFile.new uri, nil, <<-XML
11
- <languages>
12
- <language>Ruby</language>
13
- <language>Perl</language>
14
- </languages>
15
- XML
16
- end
17
-
18
- def test_xml
19
- assert_kind_of Nokogiri::XML::Document, @xml.xml
20
- end
21
-
22
- def test_search
23
- assert_equal ['Ruby', 'Perl'], @xml.search('language').map { |n| n.text }
24
- end
25
-
26
- def test_at
27
- assert_equal 'Perl', @xml.at('//language[2]').text
28
- end
29
-
30
- end