tweetwine 0.2.12 → 0.3.0
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.
- data/CHANGELOG.rdoc +7 -0
- data/Gemfile +17 -0
- data/README.md +57 -47
- data/Rakefile +17 -26
- data/bin/tweetwine +11 -12
- data/contrib/tweetwine-completion.bash +2 -3
- data/example/application_behavior_example.rb +173 -0
- data/example/example_helper.rb +44 -28
- data/example/fixture/config.yaml +8 -0
- data/example/fixture/shorten_rubygems.html +5 -0
- data/example/fixture/shorten_rubylang.html +5 -0
- data/example/fixture/update_utf8.json +1 -0
- data/example/fixture/update_with_urls.json +1 -0
- data/example/fixture/{update.json → update_without_urls.json} +0 -0
- data/example/search_statuses_example.rb +49 -16
- data/example/show_followers_example.rb +7 -8
- data/example/show_friends_example.rb +7 -8
- data/example/show_home_example.rb +19 -16
- data/example/show_mentions_example.rb +8 -9
- data/example/show_user_example.rb +16 -13
- data/example/update_status_example.rb +143 -26
- data/example/use_http_proxy_example.rb +40 -20
- data/lib/tweetwine/basic_object.rb +19 -0
- data/lib/tweetwine/character_encoding.rb +59 -0
- data/lib/tweetwine/cli.rb +354 -230
- data/lib/tweetwine/config.rb +65 -0
- data/lib/tweetwine/http.rb +120 -0
- data/lib/tweetwine/oauth.rb +104 -0
- data/lib/tweetwine/obfuscate.rb +21 -0
- data/lib/tweetwine/option_parser.rb +31 -0
- data/lib/tweetwine/promise.rb +39 -0
- data/lib/tweetwine/twitter.rb +211 -0
- data/lib/tweetwine/{io.rb → ui.rb} +30 -21
- data/lib/tweetwine/url_shortener.rb +15 -9
- data/lib/tweetwine/util.rb +30 -15
- data/lib/tweetwine.rb +72 -12
- data/man/tweetwine.7 +43 -69
- data/man/tweetwine.7.ronn +57 -47
- data/test/character_encoding_test.rb +87 -0
- data/test/cli_test.rb +19 -6
- data/test/config_test.rb +244 -0
- data/test/fixture/oauth.rb +21 -0
- data/test/fixture/test_config.yaml +4 -4
- data/test/http_test.rb +199 -0
- data/test/oauth_test.rb +77 -0
- data/test/obfuscate_test.rb +16 -0
- data/test/option_parser_test.rb +60 -0
- data/test/promise_test.rb +56 -0
- data/test/test_helper.rb +76 -8
- data/test/twitter_test.rb +625 -0
- data/test/{io_test.rb → ui_test.rb} +92 -74
- data/test/url_shortener_test.rb +115 -135
- data/test/util_test.rb +136 -85
- data/tweetwine.gemspec +53 -0
- metadata +112 -56
- data/example/show_metadata_example.rb +0 -86
- data/lib/tweetwine/client.rb +0 -187
- data/lib/tweetwine/meta.rb +0 -5
- data/lib/tweetwine/options.rb +0 -24
- data/lib/tweetwine/retrying_http.rb +0 -99
- data/lib/tweetwine/startup_config.rb +0 -50
- data/man/tweetwine.1 +0 -109
- data/man/tweetwine.1.ronn +0 -69
- data/test/client_test.rb +0 -544
- data/test/options_test.rb +0 -45
- data/test/retrying_http_test.rb +0 -147
- 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
|
8
|
-
context "
|
7
|
+
class UITest < UnitTestCase
|
8
|
+
context "a UI instance" do
|
9
9
|
setup do
|
10
|
-
@
|
11
|
-
@
|
12
|
-
@
|
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
|
-
@
|
17
|
-
@
|
18
|
-
assert_equal "42", @
|
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
|
-
@
|
23
|
-
@
|
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
|
-
@
|
28
|
-
@
|
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
|
-
@
|
33
|
-
@
|
34
|
-
assert_equal true, @
|
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
|
-
@
|
39
|
-
@
|
40
|
-
assert_equal false, @
|
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
|
-
@
|
45
|
-
@
|
46
|
-
assert_equal false, @
|
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
|
-
@
|
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
|
-
@
|
75
|
+
@out.expects(:puts).with(<<-END
|
58
76
|
#{from_user}
|
59
77
|
|
60
78
|
END
|
61
79
|
)
|
62
|
-
@
|
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
|
-
@
|
93
|
+
@out.expects(:puts).with(<<-END
|
76
94
|
#{from_user}, 2 secs ago:
|
77
95
|
#{status}
|
78
96
|
|
79
97
|
END
|
80
98
|
)
|
81
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
145
|
+
@out.expects(:puts).with(<<-END
|
128
146
|
|
129
147
|
#{status}
|
130
148
|
|
131
149
|
END
|
132
150
|
)
|
133
|
-
@
|
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
|
-
@
|
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
|
-
@
|
163
|
+
@out.expects(:puts).with(<<-END
|
146
164
|
\e[32m#{from_user}\e[0m
|
147
165
|
|
148
166
|
END
|
149
167
|
)
|
150
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
318
|
+
@ui.show_record(record)
|
301
319
|
end
|
302
320
|
end
|
303
321
|
end
|
304
322
|
|
305
|
-
context "
|
323
|
+
context "username regex" do
|
306
324
|
should "match a proper username reference" do
|
307
|
-
assert_full_match
|
308
|
-
assert_full_match
|
309
|
-
assert_full_match
|
310
|
-
assert_full_match
|
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
|
315
|
-
assert_no_full_match
|
316
|
-
assert_no_full_match
|
317
|
-
assert_no_full_match
|
318
|
-
assert_no_full_match
|
319
|
-
assert_no_full_match
|
320
|
-
assert_no_full_match
|
321
|
-
assert_no_full_match
|
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 "
|
343
|
+
context "hashtag regex" do
|
326
344
|
should "match a proper hashtag reference" do
|
327
|
-
assert_full_match
|
328
|
-
assert_full_match
|
329
|
-
assert_full_match
|
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
|
334
|
-
assert_no_full_match
|
335
|
-
assert_no_full_match
|
336
|
-
assert_no_full_match
|
337
|
-
assert_no_full_match
|
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
|
data/test/url_shortener_test.rb
CHANGED
@@ -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 <
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
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
|