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
data/test/util_test.rb
CHANGED
@@ -3,149 +3,200 @@
|
|
3
3
|
require "test_helper"
|
4
4
|
require "time"
|
5
5
|
|
6
|
-
module Tweetwine
|
6
|
+
module Tweetwine::Test
|
7
|
+
|
8
|
+
class UtilTest < UnitTestCase
|
9
|
+
include Util
|
10
|
+
|
11
|
+
context "for checking whether a string is blank" do
|
12
|
+
should("return true for nil") { assert blank?(nil) }
|
13
|
+
should("return true for empty string") { assert blank?('') }
|
14
|
+
should("return false for nonempty string") { assert !blank?('a') }
|
15
|
+
end
|
7
16
|
|
8
|
-
class UtilTest < TweetwineTestCase
|
9
17
|
context "for humanizing time differences" do
|
10
18
|
should "use second granularity for time differences smaller than a minute" do
|
11
|
-
assert_equal [1, "sec"],
|
12
|
-
assert_equal [0, "sec"],
|
13
|
-
assert_equal [1, "sec"],
|
14
|
-
assert_equal [59, "sec"],
|
19
|
+
assert_equal [1, "sec"], humanize_time_diff(Time.parse("2009-01-01 00:00:59").to_s, Time.parse("2009-01-01 00:01:00"))
|
20
|
+
assert_equal [0, "sec"], humanize_time_diff(Time.parse("2009-01-01 01:00:00").to_s, Time.parse("2009-01-01 01:00:00"))
|
21
|
+
assert_equal [1, "sec"], humanize_time_diff(Time.parse("2009-01-01 01:00:00").to_s, Time.parse("2009-01-01 01:00:01"))
|
22
|
+
assert_equal [59, "sec"], humanize_time_diff(Time.parse("2009-01-01 01:00:00").to_s, Time.parse("2009-01-01 01:00:59"))
|
15
23
|
end
|
16
24
|
|
17
25
|
should "use minute granularity for time differences greater than a minute but smaller than an hour" do
|
18
|
-
assert_equal [59, "min"],
|
19
|
-
assert_equal [59, "min"],
|
20
|
-
assert_equal [57, "min"],
|
21
|
-
assert_equal [56, "min"],
|
22
|
-
assert_equal [57, "min"],
|
23
|
-
assert_equal [58, "min"],
|
26
|
+
assert_equal [59, "min"], humanize_time_diff(Time.parse("2009-01-01 01:00").to_s, Time.parse("2009-01-01 01:59"))
|
27
|
+
assert_equal [59, "min"], humanize_time_diff(Time.parse("2009-01-01 01:00:30").to_s, Time.parse("2009-01-01 01:59:00"))
|
28
|
+
assert_equal [57, "min"], humanize_time_diff(Time.parse("2009-01-01 01:01:00").to_s, Time.parse("2009-01-01 01:58:00"))
|
29
|
+
assert_equal [56, "min"], humanize_time_diff(Time.parse("2009-01-01 01:01:31").to_s, Time.parse("2009-01-01 01:58:00"))
|
30
|
+
assert_equal [57, "min"], humanize_time_diff(Time.parse("2009-01-01 01:01:00").to_s, Time.parse("2009-01-01 01:58:29"))
|
31
|
+
assert_equal [58, "min"], humanize_time_diff(Time.parse("2009-01-01 01:01:00").to_s, Time.parse("2009-01-01 01:58:30"))
|
24
32
|
end
|
25
33
|
|
26
34
|
should "use hour granularity for time differences greater than an hour but smaller than a day" do
|
27
|
-
assert_equal [1, "hour"],
|
28
|
-
assert_equal [1, "hour"],
|
29
|
-
assert_equal [2, "hours"],
|
35
|
+
assert_equal [1, "hour"], humanize_time_diff(Time.parse("2009-01-01 01:00").to_s, Time.parse("2009-01-01 02:00"))
|
36
|
+
assert_equal [1, "hour"], humanize_time_diff(Time.parse("2009-01-01 02:00").to_s, Time.parse("2009-01-01 01:00"))
|
37
|
+
assert_equal [2, "hours"], humanize_time_diff(Time.parse("2009-01-01 01:00").to_s, Time.parse("2009-01-01 03:00"))
|
30
38
|
end
|
31
39
|
|
32
40
|
should "use day granularity for time differences greater than a day" do
|
33
|
-
assert_equal [1, "day"],
|
34
|
-
assert_equal [2, "days"],
|
41
|
+
assert_equal [1, "day"], humanize_time_diff(Time.parse("2009-01-01 01:00").to_s, Time.parse("2009-01-02 03:00"))
|
42
|
+
assert_equal [2, "days"], humanize_time_diff(Time.parse("2009-01-01 01:00").to_s, Time.parse("2009-01-03 03:00"))
|
35
43
|
end
|
36
44
|
end
|
37
45
|
|
38
|
-
context "for recursively
|
39
|
-
|
46
|
+
context "for recursively copying a hash" do
|
47
|
+
ALL_KEYS_STRINGS = {
|
48
|
+
'alpha' => 'A',
|
49
|
+
'beta' => 'B',
|
50
|
+
'charlie' => 'C',
|
51
|
+
'delta' => {
|
52
|
+
'echelon' => 'E',
|
53
|
+
'fox' => 'F'
|
54
|
+
}
|
55
|
+
}
|
56
|
+
ALL_KEYS_SYMBOLS = {
|
57
|
+
:alpha => 'A',
|
58
|
+
:beta => 'B',
|
59
|
+
:charlie => 'C',
|
60
|
+
:delta => {
|
61
|
+
:echelon => 'E',
|
62
|
+
:fox => 'F'
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
should "stringify hash keys" do
|
40
67
|
given = {
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
68
|
+
:alpha => 'A',
|
69
|
+
'beta' => 'B',
|
70
|
+
:charlie => 'C',
|
71
|
+
:delta => {
|
72
|
+
:echelon => 'E',
|
73
|
+
'fox' => 'F'
|
47
74
|
}
|
48
75
|
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
76
|
+
assert_equal ALL_KEYS_STRINGS, stringify_hash_keys(given)
|
77
|
+
end
|
78
|
+
|
79
|
+
should "symbolize hash keys" do
|
80
|
+
given = {
|
81
|
+
'alpha' => 'A',
|
82
|
+
:beta => 'B',
|
83
|
+
'charlie' => 'C',
|
84
|
+
'delta' => {
|
85
|
+
'echelon' => 'E',
|
86
|
+
:fox => 'F'
|
56
87
|
}
|
57
88
|
}
|
58
|
-
assert_equal
|
89
|
+
assert_equal ALL_KEYS_SYMBOLS, symbolize_hash_keys(given)
|
90
|
+
end
|
91
|
+
|
92
|
+
should "have symmetric property for stringify and symbolize" do
|
93
|
+
assert_equal ALL_KEYS_STRINGS, stringify_hash_keys(symbolize_hash_keys(ALL_KEYS_STRINGS))
|
94
|
+
assert_equal ALL_KEYS_SYMBOLS, symbolize_hash_keys(stringify_hash_keys(ALL_KEYS_SYMBOLS))
|
59
95
|
end
|
60
96
|
end
|
61
97
|
|
62
98
|
context "for parsing integers from strings, with minimum and default values, and naming parameter" do
|
63
99
|
should "return an integer from its string presentation" do
|
64
|
-
assert_equal 6,
|
100
|
+
assert_equal 6, parse_int_gt("6", 8, 4, "ethical working hours per day")
|
65
101
|
end
|
66
102
|
|
67
103
|
should "return default value if the string parameter is falsy" do
|
68
|
-
assert_equal 8,
|
69
|
-
assert_equal 8,
|
104
|
+
assert_equal 8, parse_int_gt(nil, 8, 4, "ethical working hours per day")
|
105
|
+
assert_equal 8, parse_int_gt(false, 8, 4, "ethical working hours per day")
|
70
106
|
end
|
71
107
|
|
72
108
|
should "raise an error if the parsed value is less than the minimum parameter" do
|
73
|
-
assert_raise(ArgumentError) {
|
74
|
-
assert_raise(ArgumentError) {
|
109
|
+
assert_raise(ArgumentError) { parse_int_gt(3, 8, 4, "ethical working hours per day") }
|
110
|
+
assert_raise(ArgumentError) { parse_int_gt("3", 8, 4, "ethical working hours per day") }
|
75
111
|
end
|
76
112
|
end
|
77
113
|
|
78
114
|
context "for replacing the contents of a string with a regexp that uses group syntax" do
|
79
115
|
should "replace the contents of the string by using a single matching group of the regexp" do
|
80
|
-
assert_equal "hEllo",
|
81
|
-
assert_equal "hEllO",
|
82
|
-
assert_equal "h<b>e</b>ll<b>o</b>",
|
83
|
-
assert_equal "hll",
|
84
|
-
assert_equal "hell",
|
116
|
+
assert_equal "hEllo", str_gsub_by_group("hello", /.+(e)/) { |s| s.upcase }
|
117
|
+
assert_equal "hEllO", str_gsub_by_group("hello", /([aeio])/) { |s| s.upcase }
|
118
|
+
assert_equal "h<b>e</b>ll<b>o</b>", str_gsub_by_group("hello", /([aeio])/) { |s| "<b>#{s}</b>" }
|
119
|
+
assert_equal "hll", str_gsub_by_group("hello", /([aeio])/) { |s| "" }
|
120
|
+
assert_equal "hell", str_gsub_by_group("hello", /.+([io])/) { |s| "" }
|
85
121
|
end
|
86
122
|
|
87
123
|
should "replace the contents of the string by using multiple matching groups of the regexp" do
|
88
|
-
assert_equal "hEllO",
|
89
|
-
assert_equal "h<b>e</b>ll<b>o</b>",
|
90
|
-
assert_equal "hll",
|
91
|
-
assert_equal "hll",
|
92
|
-
assert_equal "hEllo",
|
124
|
+
assert_equal "hEllO", str_gsub_by_group("hello", /([ae]).+([io])/) { |s| s.upcase }
|
125
|
+
assert_equal "h<b>e</b>ll<b>o</b>", str_gsub_by_group("hello", /([ae]).+([io])/) { |s| "<b>#{s}</b>" }
|
126
|
+
assert_equal "hll", str_gsub_by_group("hello", /.+([ae]).+([io])/) { |s| "" }
|
127
|
+
assert_equal "hll", str_gsub_by_group("hello", /([ae]).+([io])/) { |s| "" }
|
128
|
+
assert_equal "hEllo", str_gsub_by_group("hello", /^(a)|.+(e)/) { |s| s.upcase }
|
93
129
|
end
|
94
130
|
|
95
131
|
should "replace the contents of the string by using the whole regexp if there are no groups in the regexp an the regexp matches" do
|
96
|
-
assert_equal "",
|
97
|
-
assert_equal "hELlo",
|
98
|
-
assert_equal "h<b>e</b>ll<b>o</b>",
|
132
|
+
assert_equal "", str_gsub_by_group("", /el/) { |s| s.upcase }
|
133
|
+
assert_equal "hELlo", str_gsub_by_group("hello", /el/) { |s| s.upcase }
|
134
|
+
assert_equal "h<b>e</b>ll<b>o</b>", str_gsub_by_group("hello", /e|o/) { |s| "<b>#{s}</b>" }
|
99
135
|
end
|
100
136
|
|
101
137
|
should "not change the contents of the string if the regexp does not match" do
|
102
|
-
assert_equal "",
|
103
|
-
assert_equal "hello",
|
104
|
-
assert_equal "hello",
|
138
|
+
assert_equal "", str_gsub_by_group("", /.+([ai])/) { |s| s.upcase }
|
139
|
+
assert_equal "hello", str_gsub_by_group("hello", /.+([ai])/) { |s| s.upcase }
|
140
|
+
assert_equal "hello", str_gsub_by_group("hello", /he(f)/) { |s| s.upcase }
|
105
141
|
end
|
106
142
|
|
107
143
|
should "return a new string as the result, leaving the original string unmodified" do
|
108
144
|
org_str = "hello"
|
109
|
-
new_str =
|
145
|
+
new_str = str_gsub_by_group(org_str, /e/) { |s| s.upcase }
|
110
146
|
assert_not_same new_str, org_str
|
111
147
|
assert_equal "hello", org_str
|
112
148
|
assert_equal "hEllo", new_str
|
113
149
|
end
|
114
150
|
|
115
151
|
should "work with UTF-8 input" do
|
116
|
-
assert_equal "Ali<b>en</b>³,<b>Pre</b>dator",
|
152
|
+
assert_equal "Ali<b>en</b>³,<b>Pre</b>dator", str_gsub_by_group("Alien³,Predator", /(en).+(Pre)/) { |s| "<b>#{s}</b>" }
|
117
153
|
end
|
118
154
|
end
|
119
155
|
|
120
156
|
context "for percent-encoding strings" do
|
121
|
-
|
122
|
-
|
123
|
-
|
157
|
+
[
|
158
|
+
%w{a a},
|
159
|
+
%w{B B},
|
160
|
+
%w{3 3},
|
161
|
+
%w{. period},
|
162
|
+
%w{- dash},
|
163
|
+
%w{_ underscore},
|
164
|
+
].each do |char, desc|
|
165
|
+
should "not encode safe characters, case #{desc}" do
|
166
|
+
assert_equal char, percent_encode(char)
|
124
167
|
end
|
125
168
|
end
|
126
169
|
|
127
170
|
should "encode space character with percent-encoding, not with '+' character" do
|
128
|
-
assert_equal "%20",
|
171
|
+
assert_equal "%20", percent_encode(" ")
|
129
172
|
end
|
130
173
|
|
131
174
|
[
|
132
|
-
%w{& %26},
|
133
|
-
%w{? %3F},
|
134
|
-
%w{/ %2F},
|
135
|
-
%w{: %3A},
|
136
|
-
%w{, %2C}
|
137
|
-
].each do |
|
138
|
-
should "encode unsafe characters that URI.encode leaves by default unencoded, case
|
139
|
-
assert_equal
|
140
|
-
assert_equal expected,
|
175
|
+
%w{& %26 ampersand},
|
176
|
+
%w{? %3F question mark},
|
177
|
+
%w{/ %2F slash},
|
178
|
+
%w{: %3A colon},
|
179
|
+
%w{, %2C comma}
|
180
|
+
].each do |char, expected, desc|
|
181
|
+
should "encode unsafe characters that URI.encode leaves by default unencoded, case #{desc}" do
|
182
|
+
assert_equal char, URI.encode(char)
|
183
|
+
assert_equal expected, percent_encode(char)
|
141
184
|
end
|
142
185
|
end
|
143
186
|
end
|
144
187
|
|
145
188
|
context "for unescaping HTML" do
|
146
|
-
|
147
|
-
|
148
|
-
|
189
|
+
[
|
190
|
+
%w{a a},
|
191
|
+
%w{B B},
|
192
|
+
%w{3 3},
|
193
|
+
%w{. period},
|
194
|
+
%w{- dash},
|
195
|
+
%w{_ underscore},
|
196
|
+
%w{+ plus}
|
197
|
+
].each do |char, desc|
|
198
|
+
should "not affect already unescaped characters, case #{desc}" do
|
199
|
+
assert_equal char, unescape_html(char)
|
149
200
|
end
|
150
201
|
end
|
151
202
|
|
@@ -157,7 +208,7 @@ class UtilTest < TweetwineTestCase
|
|
157
208
|
%W{ \ }
|
158
209
|
].each do |input, expected|
|
159
210
|
should "unescape HTML-escaped characters, case '#{input}'" do
|
160
|
-
assert_equal expected,
|
211
|
+
assert_equal expected, unescape_html(input)
|
161
212
|
end
|
162
213
|
end
|
163
214
|
end
|
@@ -177,30 +228,30 @@ class UtilTest < TweetwineTestCase
|
|
177
228
|
end
|
178
229
|
|
179
230
|
should "support both a non-array and a single element array path for finding the value" do
|
180
|
-
assert_equal "beautiful",
|
181
|
-
assert_equal "beautiful",
|
231
|
+
assert_equal "beautiful", find_hash_path(@outer_hash, :simple)
|
232
|
+
assert_equal "beautiful", find_hash_path(@outer_hash, [:simple])
|
182
233
|
end
|
183
234
|
|
184
235
|
should "find a nested value with an array path" do
|
185
|
-
assert_equal "slick",
|
236
|
+
assert_equal "slick", find_hash_path(@outer_hash, [:inner, :salmon])
|
186
237
|
end
|
187
238
|
|
188
239
|
should "return the default value of the hash if the value cannot be found" do
|
189
|
-
assert_equal @outer_hash.default,
|
190
|
-
assert_equal @inner_hash.default,
|
191
|
-
assert_equal @outer_hash.default,
|
240
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, :difficult)
|
241
|
+
assert_equal @inner_hash.default, find_hash_path(@outer_hash, [:inner, :cucumber])
|
242
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, [:fishy, :no_such])
|
192
243
|
end
|
193
244
|
|
194
245
|
should "return the default value of the hash if invalid path value" do
|
195
|
-
assert_equal @outer_hash.default,
|
196
|
-
assert_equal @outer_hash.default,
|
197
|
-
assert_equal @outer_hash.default,
|
198
|
-
assert_equal @outer_hash.default,
|
199
|
-
assert_equal @outer_hash.default,
|
246
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, nil)
|
247
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, [:no_such, nil])
|
248
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, [:simple, nil])
|
249
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, [:inner, nil])
|
250
|
+
assert_equal @outer_hash.default, find_hash_path(@outer_hash, [:inner, :salmon, nil])
|
200
251
|
end
|
201
252
|
|
202
253
|
should "return nil if nil hash value" do
|
203
|
-
assert_equal nil,
|
254
|
+
assert_equal nil, find_hash_path(nil, nil)
|
204
255
|
end
|
205
256
|
end
|
206
257
|
end
|
data/tweetwine.gemspec
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.expand_path("../lib/", __FILE__))
|
4
|
+
name = "tweetwine"
|
5
|
+
require name
|
6
|
+
version = Tweetwine::VERSION.dup
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
|
12
|
+
s.name = name
|
13
|
+
s.version = version
|
14
|
+
s.date = "2010-02-28"
|
15
|
+
s.homepage = "http://github.com/tuomas/tweetwine"
|
16
|
+
|
17
|
+
s.summary = "A simple Twitter command line agent"
|
18
|
+
s.description = "A simple but tasty Twitter agent for command line use, made for fun."
|
19
|
+
|
20
|
+
s.authors = "Tuomas Kareinen"
|
21
|
+
s.email = "tkareine@gmail.com"
|
22
|
+
|
23
|
+
s.files = Dir[
|
24
|
+
"*.md",
|
25
|
+
"*.rdoc",
|
26
|
+
"LICENSE.txt",
|
27
|
+
"Gemfile",
|
28
|
+
"Rakefile",
|
29
|
+
"tweetwine.gemspec",
|
30
|
+
"{bin,contrib,example,lib,test}/**/*",
|
31
|
+
"man/**/*.[1-9]",
|
32
|
+
"man/**/*.ronn"
|
33
|
+
]
|
34
|
+
s.require_paths = %w{lib}
|
35
|
+
s.executables = %w{tweetwine}
|
36
|
+
|
37
|
+
s.add_dependency "oauth", "~> 0.4.4"
|
38
|
+
s.add_dependency "json", ">= 1.0.0" if RUBY_VERSION < "1.9"
|
39
|
+
s.add_development_dependency "contest", "~> 0.1.2"
|
40
|
+
s.add_development_dependency "coulda", "~> 0.6.0"
|
41
|
+
s.add_development_dependency "gem-man", "~> 0.2.0"
|
42
|
+
s.add_development_dependency "matchy", "~> 0.5.2"
|
43
|
+
s.add_development_dependency "mocha", "= 0.9.8"
|
44
|
+
s.add_development_dependency "open4", "~> 1.0.1"
|
45
|
+
s.add_development_dependency "ronn", "~> 0.7.3"
|
46
|
+
s.add_development_dependency "timecop", "~> 0.3.5"
|
47
|
+
s.add_development_dependency "webmock", "~> 1.5.0"
|
48
|
+
|
49
|
+
s.has_rdoc = true
|
50
|
+
s.extra_rdoc_files = Dir["*.rdoc", "LICENSE.txt"]
|
51
|
+
s.rdoc_options << "--title" << "#{name} #{version}" \
|
52
|
+
<< "--exclude" << "test"
|
53
|
+
end
|