tweetwine 0.2.12 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/CHANGELOG.rdoc +7 -0
  2. data/Gemfile +17 -0
  3. data/README.md +57 -47
  4. data/Rakefile +17 -26
  5. data/bin/tweetwine +11 -12
  6. data/contrib/tweetwine-completion.bash +2 -3
  7. data/example/application_behavior_example.rb +173 -0
  8. data/example/example_helper.rb +44 -28
  9. data/example/fixture/config.yaml +8 -0
  10. data/example/fixture/shorten_rubygems.html +5 -0
  11. data/example/fixture/shorten_rubylang.html +5 -0
  12. data/example/fixture/update_utf8.json +1 -0
  13. data/example/fixture/update_with_urls.json +1 -0
  14. data/example/fixture/{update.json → update_without_urls.json} +0 -0
  15. data/example/search_statuses_example.rb +49 -16
  16. data/example/show_followers_example.rb +7 -8
  17. data/example/show_friends_example.rb +7 -8
  18. data/example/show_home_example.rb +19 -16
  19. data/example/show_mentions_example.rb +8 -9
  20. data/example/show_user_example.rb +16 -13
  21. data/example/update_status_example.rb +143 -26
  22. data/example/use_http_proxy_example.rb +40 -20
  23. data/lib/tweetwine/basic_object.rb +19 -0
  24. data/lib/tweetwine/character_encoding.rb +59 -0
  25. data/lib/tweetwine/cli.rb +354 -230
  26. data/lib/tweetwine/config.rb +65 -0
  27. data/lib/tweetwine/http.rb +120 -0
  28. data/lib/tweetwine/oauth.rb +104 -0
  29. data/lib/tweetwine/obfuscate.rb +21 -0
  30. data/lib/tweetwine/option_parser.rb +31 -0
  31. data/lib/tweetwine/promise.rb +39 -0
  32. data/lib/tweetwine/twitter.rb +211 -0
  33. data/lib/tweetwine/{io.rb → ui.rb} +30 -21
  34. data/lib/tweetwine/url_shortener.rb +15 -9
  35. data/lib/tweetwine/util.rb +30 -15
  36. data/lib/tweetwine.rb +72 -12
  37. data/man/tweetwine.7 +43 -69
  38. data/man/tweetwine.7.ronn +57 -47
  39. data/test/character_encoding_test.rb +87 -0
  40. data/test/cli_test.rb +19 -6
  41. data/test/config_test.rb +244 -0
  42. data/test/fixture/oauth.rb +21 -0
  43. data/test/fixture/test_config.yaml +4 -4
  44. data/test/http_test.rb +199 -0
  45. data/test/oauth_test.rb +77 -0
  46. data/test/obfuscate_test.rb +16 -0
  47. data/test/option_parser_test.rb +60 -0
  48. data/test/promise_test.rb +56 -0
  49. data/test/test_helper.rb +76 -8
  50. data/test/twitter_test.rb +625 -0
  51. data/test/{io_test.rb → ui_test.rb} +92 -74
  52. data/test/url_shortener_test.rb +115 -135
  53. data/test/util_test.rb +136 -85
  54. data/tweetwine.gemspec +53 -0
  55. metadata +112 -56
  56. data/example/show_metadata_example.rb +0 -86
  57. data/lib/tweetwine/client.rb +0 -187
  58. data/lib/tweetwine/meta.rb +0 -5
  59. data/lib/tweetwine/options.rb +0 -24
  60. data/lib/tweetwine/retrying_http.rb +0 -99
  61. data/lib/tweetwine/startup_config.rb +0 -50
  62. data/man/tweetwine.1 +0 -109
  63. data/man/tweetwine.1.ronn +0 -69
  64. data/test/client_test.rb +0 -544
  65. data/test/options_test.rb +0 -45
  66. data/test/retrying_http_test.rb +0 -147
  67. data/test/startup_config_test.rb +0 -162
@@ -2,64 +2,82 @@
2
2
 
3
3
  require "test_helper"
4
4
 
5
- module Tweetwine
5
+ module Tweetwine::Test
6
6
 
7
- class IOTest < TweetwineTestCase
8
- context "An IO instance" do
7
+ class UITest < UnitTestCase
8
+ context "a UI instance" do
9
9
  setup do
10
- @input = mock()
11
- @output = mock()
12
- @io = IO.new({ :input => @input, :output => @output })
10
+ @in = mock
11
+ @out = mock
12
+ @err = mock
13
+ @ui = UI.new({ :in => @in, :out => @out, :err => @err })
13
14
  end
14
15
 
15
16
  should "output prompt and return input as trimmed" do
16
- @output.expects(:print).with("The answer: ")
17
- @input.expects(:gets).returns(" 42 ")
18
- assert_equal "42", @io.prompt("The answer")
17
+ @out.expects(:print).with("The answer: ")
18
+ @in.expects(:gets).returns(" 42 ")
19
+ assert_equal "42", @ui.prompt("The answer")
19
20
  end
20
21
 
21
22
  should "output info message" do
22
- @output.expects(:puts).with("foo")
23
- @io.info("foo")
23
+ @out.expects(:puts).with("foo")
24
+ @ui.info("foo")
25
+ end
26
+
27
+ should "output info message in process style when given a block" do
28
+ inform = sequence('inform')
29
+ @out.expects(:print).with("processing...").in_sequence(inform)
30
+ @out.expects(:puts).with(" done.").in_sequence(inform)
31
+ @ui.info("processing...") { true }
32
+ end
33
+
34
+ should "output empty line as info message" do
35
+ @out.expects(:puts).with("\n")
36
+ @ui.info
24
37
  end
25
38
 
26
39
  should "output warning message" do
27
- @output.expects(:puts).with("Warning: monkey patching ahead")
28
- @io.warn("monkey patching ahead")
40
+ @out.expects(:puts).with("Warning: monkey patching ahead")
41
+ @ui.warn("monkey patching ahead")
42
+ end
43
+
44
+ should "output error message" do
45
+ @err.expects(:puts).with("ERROR: Invalid monkey patch")
46
+ @ui.error("Invalid monkey patch")
29
47
  end
30
48
 
31
49
  should "confirm action, with positive answer" do
32
- @output.expects(:print).with("Fire nukes? [yN] ")
33
- @input.expects(:gets).returns("y")
34
- assert_equal true, @io.confirm("Fire nukes?")
50
+ @out.expects(:print).with("Fire nukes? [yN] ")
51
+ @in.expects(:gets).returns("y")
52
+ assert_equal true, @ui.confirm("Fire nukes?")
35
53
  end
36
54
 
37
55
  should "confirm action, with negative answer" do
38
- @output.expects(:print).with("Fire nukes? [yN] ")
39
- @input.expects(:gets).returns("n")
40
- assert_equal false, @io.confirm("Fire nukes?")
56
+ @out.expects(:print).with("Fire nukes? [yN] ")
57
+ @in.expects(:gets).returns("n")
58
+ assert_equal false, @ui.confirm("Fire nukes?")
41
59
  end
42
60
 
43
61
  should "confirm action, with default answer" do
44
- @output.expects(:print).with("Fire nukes? [yN] ")
45
- @input.expects(:gets).returns("")
46
- assert_equal false, @io.confirm("Fire nukes?")
62
+ @out.expects(:print).with("Fire nukes? [yN] ")
63
+ @in.expects(:gets).returns("")
64
+ assert_equal false, @ui.confirm("Fire nukes?")
47
65
  end
48
66
 
49
67
  context "with colorization disabled" do
50
68
  setup do
51
- @io = IO.new({ :input => @input, :output => @output, :colors => false })
69
+ @ui = UI.new({:in => @in, :out => @out, :colors => false })
52
70
  end
53
71
 
54
72
  should "output a record as user info when no status is given" do
55
73
  from_user = "fooman"
56
74
  record = { :from_user => from_user }
57
- @output.expects(:puts).with(<<-END
75
+ @out.expects(:puts).with(<<-END
58
76
  #{from_user}
59
77
 
60
78
  END
61
79
  )
62
- @io.show_record(record)
80
+ @ui.show_record(record)
63
81
  end
64
82
 
65
83
  should "output a record as status info when status is given, without in-reply info" do
@@ -72,13 +90,13 @@ class IOTest < TweetwineTestCase
72
90
  :to_user => nil
73
91
  }
74
92
  Util.expects(:humanize_time_diff).returns([2, "secs"])
75
- @output.expects(:puts).with(<<-END
93
+ @out.expects(:puts).with(<<-END
76
94
  #{from_user}, 2 secs ago:
77
95
  #{status}
78
96
 
79
97
  END
80
98
  )
81
- @io.show_record(record)
99
+ @ui.show_record(record)
82
100
  end
83
101
 
84
102
  should "output a record as status info when status is given, with in-reply info" do
@@ -92,13 +110,13 @@ class IOTest < TweetwineTestCase
92
110
  :to_user => to_user
93
111
  }
94
112
  Util.expects(:humanize_time_diff).returns([2, "secs"])
95
- @output.expects(:puts).with(<<-END
113
+ @out.expects(:puts).with(<<-END
96
114
  #{from_user}, in reply to #{to_user}, 2 secs ago:
97
115
  #{status}
98
116
 
99
117
  END
100
118
  )
101
- @io.show_record(record)
119
+ @ui.show_record(record)
102
120
  end
103
121
 
104
122
 
@@ -113,41 +131,41 @@ class IOTest < TweetwineTestCase
113
131
  :to_user => nil
114
132
  }
115
133
  Util.expects(:humanize_time_diff).returns([2, "secs"])
116
- @output.expects(:puts).with(<<-END
134
+ @out.expects(:puts).with(<<-END
117
135
  #{from_user}, 2 secs ago:
118
136
  #{unescaped_status}
119
137
 
120
138
  END
121
139
  )
122
- @io.show_record(record)
140
+ @ui.show_record(record)
123
141
  end
124
142
 
125
143
  should "output a preview of a status" do
126
144
  status = "@nick, check http://bit.ly/18rU_Vx"
127
- @output.expects(:puts).with(<<-END
145
+ @out.expects(:puts).with(<<-END
128
146
 
129
147
  #{status}
130
148
 
131
149
  END
132
150
  )
133
- @io.show_status_preview(status)
151
+ @ui.show_status_preview(status)
134
152
  end
135
153
  end
136
154
 
137
155
  context "with colorization enabled" do
138
156
  setup do
139
- @io = IO.new({ :input => @input, :output => @output, :colors => true })
157
+ @ui = UI.new({:in => @in, :out => @out, :colors => true})
140
158
  end
141
159
 
142
160
  should "output a record as user info when no status is given" do
143
161
  from_user = "fooman"
144
162
  record = { :from_user => from_user }
145
- @output.expects(:puts).with(<<-END
163
+ @out.expects(:puts).with(<<-END
146
164
  \e[32m#{from_user}\e[0m
147
165
 
148
166
  END
149
167
  )
150
- @io.show_record(record)
168
+ @ui.show_record(record)
151
169
  end
152
170
 
153
171
  should "output a record as status info when status is given, without in-reply info" do
@@ -160,13 +178,13 @@ class IOTest < TweetwineTestCase
160
178
  :to_user => nil
161
179
  }
162
180
  Util.expects(:humanize_time_diff).returns([2, "secs"])
163
- @output.expects(:puts).with(<<-END
181
+ @out.expects(:puts).with(<<-END
164
182
  \e[32m#{from_user}\e[0m, 2 secs ago:
165
183
  #{status}
166
184
 
167
185
  END
168
186
  )
169
- @io.show_record(record)
187
+ @ui.show_record(record)
170
188
  end
171
189
 
172
190
  should "output a record as status info when status is given, with in-reply info" do
@@ -179,24 +197,24 @@ class IOTest < TweetwineTestCase
179
197
  :to_user => to_user
180
198
  }
181
199
  Util.expects(:humanize_time_diff).returns([2, "secs"])
182
- @output.expects(:puts).with(<<-END
200
+ @out.expects(:puts).with(<<-END
183
201
  \e[32m#{from_user}\e[0m, in reply to \e[32m#{to_user}\e[0m, 2 secs ago:
184
202
  \e[33m@#{to_user}\e[0m! How are you doing?
185
203
 
186
204
  END
187
205
  )
188
- @io.show_record(record)
206
+ @ui.show_record(record)
189
207
  end
190
208
 
191
209
  should "output a preview of a status" do
192
210
  status = "@nick, check http://bit.ly/18rU_Vx"
193
- @output.expects(:puts).with(<<-END
211
+ @out.expects(:puts).with(<<-END
194
212
 
195
213
  \e[33m@nick\e[0m, check \e[36mhttp://bit.ly/18rU_Vx\e[0m
196
214
 
197
215
  END
198
216
  )
199
- @io.show_status_preview(status)
217
+ @ui.show_status_preview(status)
200
218
  end
201
219
 
202
220
  should "highlight hashtags in a status" do
@@ -209,13 +227,13 @@ class IOTest < TweetwineTestCase
209
227
  :to_user => nil
210
228
  }
211
229
  Util.expects(:humanize_time_diff).returns([2, "secs"])
212
- @output.expects(:puts).with(<<-END
230
+ @out.expects(:puts).with(<<-END
213
231
  \e[32m#{from_user}\e[0m, 2 secs ago:
214
232
  Lulz, so happy! \e[35m#{hashtags[0]}\e[0m \e[35m#{hashtags[1]}\e[0m
215
233
 
216
234
  END
217
235
  )
218
- @io.show_record(record)
236
+ @ui.show_record(record)
219
237
  end
220
238
 
221
239
  %w{http://is.gd/1qLk3 http://is.gd/1qLk3?id=foo}.each do |url|
@@ -228,13 +246,13 @@ Lulz, so happy! \e[35m#{hashtags[0]}\e[0m \e[35m#{hashtags[1]}\e[0m
228
246
  :to_user => nil
229
247
  }
230
248
  Util.expects(:humanize_time_diff).returns([2, "secs"])
231
- @output.expects(:puts).with(<<-END
249
+ @out.expects(:puts).with(<<-END
232
250
  \e[32m#{from_user}\e[0m, 2 secs ago:
233
251
  New Rails³ - \e[36m#{url}\e[0m
234
252
 
235
253
  END
236
254
  )
237
- @io.show_record(record)
255
+ @ui.show_record(record)
238
256
  end
239
257
  end
240
258
 
@@ -251,13 +269,13 @@ New Rails³ - \e[36m#{url}\e[0m
251
269
  :to_user => nil
252
270
  }
253
271
  Util.expects(:humanize_time_diff).returns([2, "secs"])
254
- @output.expects(:puts).with(<<-END
272
+ @out.expects(:puts).with(<<-END
255
273
  \e[32m#{from_user}\e[0m, 2 secs ago:
256
274
  Links: \e[36m#{first_url}\e[0m and \e[36m#{second_url}\e[0m np
257
275
 
258
276
  END
259
277
  )
260
- @io.show_record(record)
278
+ @ui.show_record(record)
261
279
  end
262
280
  end
263
281
 
@@ -271,13 +289,13 @@ Links: \e[36m#{first_url}\e[0m and \e[36m#{second_url}\e[0m np
271
289
  :to_user => nil
272
290
  }
273
291
  Util.expects(:humanize_time_diff).returns([2, "secs"])
274
- @output.expects(:puts).with(<<-END
292
+ @out.expects(:puts).with(<<-END
275
293
  \e[32m#{from_user}\e[0m, 2 secs ago:
276
294
  I salute you \e[33m#{users[0]}\e[0m, \e[33m#{users[1]}\e[0m, and \e[33m#{users[2]}\e[0m!
277
295
 
278
296
  END
279
297
  )
280
- @io.show_record(record)
298
+ @ui.show_record(record)
281
299
  end
282
300
 
283
301
  should "not highlight email addresses as usernames in a status" do
@@ -291,50 +309,50 @@ I salute you \e[33m#{users[0]}\e[0m, \e[33m#{users[1]}\e[0m, and \e[33m#{users[2
291
309
  :to_user => nil
292
310
  }
293
311
  Util.expects(:humanize_time_diff).returns([2, "secs"])
294
- @output.expects(:puts).with(<<-END
312
+ @out.expects(:puts).with(<<-END
295
313
  \e[32m#{from_user}\e[0m, 2 secs ago:
296
314
  Hi, \e[33m#{users[0]}\e[0m! You should notify \e[33m#{users[1]}\e[0m, #{email}
297
315
 
298
316
  END
299
317
  )
300
- @io.show_record(record)
318
+ @ui.show_record(record)
301
319
  end
302
320
  end
303
321
  end
304
322
 
305
- context "Username regex" do
323
+ context "username regex" do
306
324
  should "match a proper username reference" do
307
- assert_full_match IO::USERNAME_REGEX, "@nick"
308
- assert_full_match IO::USERNAME_REGEX, "@nick_man"
309
- assert_full_match IO::USERNAME_REGEX, "@nick"
310
- assert_full_match IO::USERNAME_REGEX, " @nick"
325
+ assert_full_match UI::USERNAME_REGEX, "@nick"
326
+ assert_full_match UI::USERNAME_REGEX, "@nick_man"
327
+ assert_full_match UI::USERNAME_REGEX, "@nick"
328
+ assert_full_match UI::USERNAME_REGEX, " @nick"
311
329
  end
312
330
 
313
331
  should "not match an inproper username reference" do
314
- assert_no_full_match IO::USERNAME_REGEX, "@"
315
- assert_no_full_match IO::USERNAME_REGEX, "nick"
316
- assert_no_full_match IO::USERNAME_REGEX, "-@nick"
317
- assert_no_full_match IO::USERNAME_REGEX, "@nick-man"
318
- assert_no_full_match IO::USERNAME_REGEX, "@nick "
319
- assert_no_full_match IO::USERNAME_REGEX, " @nick "
320
- assert_no_full_match IO::USERNAME_REGEX, "man @nick"
321
- assert_no_full_match IO::USERNAME_REGEX, "man@nick"
332
+ assert_no_full_match UI::USERNAME_REGEX, "@"
333
+ assert_no_full_match UI::USERNAME_REGEX, "nick"
334
+ assert_no_full_match UI::USERNAME_REGEX, "-@nick"
335
+ assert_no_full_match UI::USERNAME_REGEX, "@nick-man"
336
+ assert_no_full_match UI::USERNAME_REGEX, "@nick "
337
+ assert_no_full_match UI::USERNAME_REGEX, " @nick "
338
+ assert_no_full_match UI::USERNAME_REGEX, "man @nick"
339
+ assert_no_full_match UI::USERNAME_REGEX, "man@nick"
322
340
  end
323
341
  end
324
342
 
325
- context "Hashtag regex" do
343
+ context "hashtag regex" do
326
344
  should "match a proper hashtag reference" do
327
- assert_full_match IO::HASHTAG_REGEX, "#mayhem"
328
- assert_full_match IO::HASHTAG_REGEX, "#friday_mayhem"
329
- assert_full_match IO::HASHTAG_REGEX, "#friday-mayhem"
345
+ assert_full_match UI::HASHTAG_REGEX, "#mayhem"
346
+ assert_full_match UI::HASHTAG_REGEX, "#friday_mayhem"
347
+ assert_full_match UI::HASHTAG_REGEX, "#friday-mayhem"
330
348
  end
331
349
 
332
350
  should "not match an inproper hashtag reference" do
333
- assert_no_full_match IO::USERNAME_REGEX, "#"
334
- assert_no_full_match IO::USERNAME_REGEX, "mayhem"
335
- assert_no_full_match IO::USERNAME_REGEX, " #mayhem"
336
- assert_no_full_match IO::USERNAME_REGEX, "#mayhem "
337
- assert_no_full_match IO::USERNAME_REGEX, " #mayhem "
351
+ assert_no_full_match UI::USERNAME_REGEX, "#"
352
+ assert_no_full_match UI::USERNAME_REGEX, "mayhem"
353
+ assert_no_full_match UI::USERNAME_REGEX, " #mayhem"
354
+ assert_no_full_match UI::USERNAME_REGEX, "#mayhem "
355
+ assert_no_full_match UI::USERNAME_REGEX, " #mayhem "
338
356
  end
339
357
  end
340
358
  end
@@ -2,159 +2,139 @@
2
2
 
3
3
  require "test_helper"
4
4
 
5
- module Tweetwine
5
+ module Tweetwine::Test
6
6
 
7
- class UrlShortenerTest < TweetwineTestCase
8
- context "An UrlShortener instance" do
9
- setup do
10
- @http_client = mock()
7
+ class UrlShortenerTest < UnitTestCase
8
+ setup do
9
+ mock_http
10
+ end
11
+
12
+ context "for initialization" do
13
+ should "raise exception if service should be disabled" do
14
+ assert_raise(RuntimeError) do
15
+ UrlShortener.new(
16
+ :disable => true,
17
+ :service_url => "http://shorten.it/create",
18
+ :url_param_name => "url",
19
+ :xpath_selector => "//input[@id='short_url']/@value")
20
+ end
11
21
  end
12
22
 
13
- context "upon initialization" do
14
- should "raise exception if service URL is not given" do
15
- assert_raise(ArgumentError) do
16
- UrlShortener.new(
17
- @http_client,
18
- {
19
- :service_url => nil,
20
- :url_param_name => "url",
21
- :xpath_selector => "//input[@id='short_url']/@value"
22
- }
23
- )
24
- end
23
+ should "raise exception if service URL is not given" do
24
+ assert_raise(RequiredOptionError) do
25
+ UrlShortener.new(
26
+ :service_url => nil,
27
+ :url_param_name => "url",
28
+ :xpath_selector => "//input[@id='short_url']/@value")
25
29
  end
30
+ end
26
31
 
27
- should "raise exception if URL parameter name is not given" do
28
- assert_raise(ArgumentError) do
29
- UrlShortener.new(
30
- @http_client,
31
- {
32
- :service_url => "http://shorten.it/create",
33
- :url_param_name => nil,
34
- :xpath_selector => "//input[@id='short_url']/@value"
35
- }
36
- )
37
- end
32
+ should "raise exception if URL parameter name is not given" do
33
+ assert_raise(RequiredOptionError) do
34
+ UrlShortener.new(
35
+ :service_url => "http://shorten.it/create",
36
+ :url_param_name => nil,
37
+ :xpath_selector => "//input[@id='short_url']/@value")
38
38
  end
39
+ end
39
40
 
40
- should "raise exception if XPath selector is not given" do
41
- assert_raise(ArgumentError) do
42
- UrlShortener.new(
43
- @http_client,
44
- {
45
- :service_url => "http://shorten.it/create",
46
- :url_param_name => "url",
47
- :xpath_selector => nil
48
- }
49
- )
50
- end
41
+ should "raise exception if XPath selector is not given" do
42
+ assert_raise(RequiredOptionError) do
43
+ UrlShortener.new(
44
+ :service_url => "http://shorten.it/create",
45
+ :url_param_name => "url",
46
+ :xpath_selector => nil)
51
47
  end
48
+ end
52
49
 
53
- should "fallback to use GET method if not given explicitly" do
54
- url_shortener = UrlShortener.new(
55
- @http_client,
56
- {
57
- :service_url => "http://shorten.it/create",
58
- :url_param_name => "url",
59
- :xpath_selector => "//input[@id='short_url']/@value"
60
- }
61
- )
62
- assert_equal(:get, url_shortener.instance_variable_get(:@method))
50
+ should "fallback to use GET method if method is not given explicitly" do
51
+ url_shortener = UrlShortener.new(
52
+ :service_url => "http://shorten.it/create",
53
+ :url_param_name => "url",
54
+ :xpath_selector => "//input[@id='short_url']/@value")
55
+ @http.expects(:get)
56
+ url_shortener.shorten("http://www.ruby-doc.org/core/")
57
+ end
58
+
59
+ should "raise exception if given HTTP request method is unsupported" do
60
+ assert_raise(CommandLineError) do
61
+ UrlShortener.new(
62
+ :method => "put",
63
+ :service_url => "http://shorten.it/create",
64
+ :url_param_name => "url",
65
+ :xpath_selector => "//input[@id='short_url']/@value")
63
66
  end
64
67
  end
68
+ end
65
69
 
66
- context "at runtime" do
67
- context "configured for HTTP GET" do
68
- should "use parameters as URL query parameters, with just the URL parameter" do
69
- url_shortener = UrlShortener.new(
70
- @http_client,
71
- {
72
- :method => "get",
73
- :service_url => "http://shorten.it/create",
74
- :url_param_name => "url",
75
- :xpath_selector => "//input[@id='short_url']/@value"
76
- }
77
- )
78
- @http_client.expects(:get) \
79
- .with("http://shorten.it/create?url=http://www.ruby-doc.org/core/")
80
- url_shortener.shorten("http://www.ruby-doc.org/core/")
81
- end
70
+ context "at runtime" do
71
+ context "configured for HTTP GET" do
72
+ should "use parameters as URL query parameters, with just the URL parameter" do
73
+ url_shortener = UrlShortener.new(
74
+ :method => "get",
75
+ :service_url => "http://shorten.it/create",
76
+ :url_param_name => "url",
77
+ :xpath_selector => "//input[@id='short_url']/@value")
78
+ @http.expects(:get).
79
+ with("http://shorten.it/create?url=http://www.ruby-doc.org/core/")
80
+ url_shortener.shorten("http://www.ruby-doc.org/core/")
81
+ end
82
82
 
83
- should "use parameters as URL query parameters, with additional extra parameters" do
84
- url_shortener = UrlShortener.new(
85
- @http_client,
86
- {
87
- :method => "get",
88
- :service_url => "http://shorten.it/create",
89
- :url_param_name => "url",
90
- :extra_params => {
91
- :token => "xyz"
92
- },
93
- :xpath_selector => "//input[@id='short_url']/@value"
94
- }
95
- )
96
- @http_client.expects(:get) \
97
- .with("http://shorten.it/create?token=xyz&url=http://www.ruby-doc.org/core/")
98
- url_shortener.shorten("http://www.ruby-doc.org/core/")
99
- end
83
+ should "use parameters as URL query parameters, with additional extra parameters" do
84
+ url_shortener = UrlShortener.new(
85
+ :method => "get",
86
+ :service_url => "http://shorten.it/create",
87
+ :url_param_name => "url",
88
+ :extra_params => {
89
+ :token => "xyz"
90
+ },
91
+ :xpath_selector => "//input[@id='short_url']/@value")
92
+ @http.expects(:get).
93
+ with("http://shorten.it/create?token=xyz&url=http://www.ruby-doc.org/core/")
94
+ url_shortener.shorten("http://www.ruby-doc.org/core/")
100
95
  end
96
+ end
101
97
 
102
- context "configured for HTTP POST" do
103
- should "use parameters as payload, with just the URL parameter" do
104
- url_shortener = UrlShortener.new(
105
- @http_client,
106
- {
107
- :method => "post",
108
- :service_url => "http://shorten.it/create",
109
- :url_param_name => "url",
110
- :xpath_selector => "//input[@id='short_url']/@value"
111
- }
112
- )
113
- @http_client.expects(:post) \
114
- .with("http://shorten.it/create", {:url => "http://www.ruby-doc.org/core/"})
115
- url_shortener.shorten("http://www.ruby-doc.org/core/")
116
- end
98
+ context "configured for HTTP POST" do
99
+ should "use parameters as payload, with just the URL parameter" do
100
+ url_shortener = UrlShortener.new(
101
+ :method => "post",
102
+ :service_url => "http://shorten.it/create",
103
+ :url_param_name => "url",
104
+ :xpath_selector => "//input[@id='short_url']/@value")
105
+ @http.expects(:post).
106
+ with("http://shorten.it/create", {:url => "http://www.ruby-doc.org/core/"})
107
+ url_shortener.shorten("http://www.ruby-doc.org/core/")
108
+ end
117
109
 
118
- should "use parameters as payload, with additional extra parameters" do
119
- url_shortener = UrlShortener.new(
120
- @http_client,
121
- {
122
- :method => "post",
123
- :service_url => "http://shorten.it/create",
124
- :url_param_name => "url",
125
- :extra_params => {
126
- :token => "xyz"
127
- },
128
- :xpath_selector => "//input[@id='short_url']/@value"
129
- }
130
- )
131
- @http_client.expects(:post) \
132
- .with("http://shorten.it/create", {
133
- :token => "xyz",
134
- :url => "http://www.ruby-doc.org/core/"
135
- })
136
- url_shortener.shorten("http://www.ruby-doc.org/core/")
137
- end
110
+ should "use parameters as payload, with additional extra parameters" do
111
+ url_shortener = UrlShortener.new(
112
+ :method => "post",
113
+ :service_url => "http://shorten.it/create",
114
+ :url_param_name => "url",
115
+ :extra_params => {
116
+ :token => "xyz"
117
+ },
118
+ :xpath_selector => "//input[@id='short_url']/@value")
119
+ @http.expects(:post).
120
+ with("http://shorten.it/create",
121
+ :token => "xyz",
122
+ :url => "http://www.ruby-doc.org/core/")
123
+ url_shortener.shorten("http://www.ruby-doc.org/core/")
138
124
  end
125
+ end
139
126
 
140
- context "in erroenous situations" do
141
- should "raise HttpError upon connection error" do
142
- url_shortener = UrlShortener.new(
143
- @http_client,
144
- {
145
- :method => "post",
146
- :service_url => "http://shorten.it/create",
147
- :url_param_name => "url",
148
- :xpath_selector => "//input[@id='short_url']/@value"
149
- }
150
- )
151
- @http_client.expects(:post) \
152
- .with("http://shorten.it/create", {
153
- :url => "http://www.ruby-doc.org/core/"
154
- }) \
155
- .raises(HttpError, "connection error")
156
- assert_raise(HttpError) { url_shortener.shorten("http://www.ruby-doc.org/core/") }
157
- end
127
+ context "in erroenous network situations" do
128
+ should "pass exceptions through" do
129
+ url_shortener = UrlShortener.new(
130
+ :method => "post",
131
+ :service_url => "http://shorten.it/create",
132
+ :url_param_name => "url",
133
+ :xpath_selector => "//input[@id='short_url']/@value")
134
+ @http.expects(:post).
135
+ with("http://shorten.it/create", :url => "http://www.ruby-doc.org/core/").
136
+ raises(HttpError.new(404, "Not Found"))
137
+ assert_raise(HttpError) { url_shortener.shorten("http://www.ruby-doc.org/core/") }
158
138
  end
159
139
  end
160
140
  end