twurl 0.8.2 → 0.8.3
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/lib/twurl/cli.rb +33 -3
- data/lib/twurl/version.rb +1 -1
- data/test/cli_test.rb +48 -26
- metadata +2 -2
data/lib/twurl/cli.rb
CHANGED
@@ -3,14 +3,21 @@ module Twurl
|
|
3
3
|
SUPPORTED_COMMANDS = %w(authorize accounts alias set)
|
4
4
|
DEFAULT_COMMAND = 'request'
|
5
5
|
PATH_PATTERN = /^\/\w+/
|
6
|
+
PROTOCOL_PATTERN = /^\w+:\/\//
|
6
7
|
README = File.dirname(__FILE__) + '/../../README'
|
7
8
|
@output ||= STDOUT
|
9
|
+
class NoPathFound < Exception
|
10
|
+
end
|
8
11
|
|
9
12
|
class << self
|
10
13
|
attr_accessor :output
|
11
14
|
|
12
15
|
def run(args)
|
13
|
-
|
16
|
+
begin
|
17
|
+
options = parse_options(args)
|
18
|
+
rescue NoPathFound => e
|
19
|
+
exit
|
20
|
+
end
|
14
21
|
dispatch(options)
|
15
22
|
end
|
16
23
|
|
@@ -81,6 +88,12 @@ Supported Commands: #{SUPPORTED_COMMANDS.sort.join(', ')}
|
|
81
88
|
arguments = option_parser.parse!(args)
|
82
89
|
Twurl.options.command = extract_command!(arguments)
|
83
90
|
Twurl.options.path = extract_path!(arguments)
|
91
|
+
|
92
|
+
if Twurl.options.command == DEFAULT_COMMAND and Twurl.options.path.nil?
|
93
|
+
CLI.puts option_parser
|
94
|
+
raise NoPathFound, "No path found"
|
95
|
+
end
|
96
|
+
|
84
97
|
Twurl.options.subcommands = arguments
|
85
98
|
Twurl.options
|
86
99
|
end
|
@@ -128,12 +141,24 @@ Supported Commands: #{SUPPORTED_COMMANDS.sort.join(', ')}
|
|
128
141
|
path = nil
|
129
142
|
arguments.each_with_index do |argument, index|
|
130
143
|
if argument[PATH_PATTERN]
|
131
|
-
|
144
|
+
path_with_params = arguments.slice!(index)
|
145
|
+
path, params = path_with_params.split("?", 2)
|
146
|
+
if params
|
147
|
+
path += "?" + escape_params(params)
|
148
|
+
end
|
132
149
|
break
|
133
150
|
end
|
134
151
|
end
|
135
152
|
path
|
136
153
|
end
|
154
|
+
|
155
|
+
def escape_params(params)
|
156
|
+
split_params = params.split("&").map do |param|
|
157
|
+
key, value = param.split('=', 2)
|
158
|
+
CGI::escape(key) + '=' + CGI::escape(value)
|
159
|
+
end
|
160
|
+
split_params.join("&")
|
161
|
+
end
|
137
162
|
end
|
138
163
|
|
139
164
|
module AvailableOptions
|
@@ -215,7 +240,12 @@ Supported Commands: #{SUPPORTED_COMMANDS.sort.join(', ')}
|
|
215
240
|
|
216
241
|
def host
|
217
242
|
on('-H', '--host [host]', 'Specify host to make requests to (default: api.twitter.com)') do |host|
|
218
|
-
|
243
|
+
if host[PROTOCOL_PATTERN]
|
244
|
+
protocol, protocolless_host = host.split(PROTOCOL_PATTERN, 2)
|
245
|
+
options.host = protocolless_host
|
246
|
+
else
|
247
|
+
options.host = host
|
248
|
+
end
|
219
249
|
end
|
220
250
|
end
|
221
251
|
|
data/lib/twurl/version.rb
CHANGED
@@ -2,7 +2,7 @@ module Twurl
|
|
2
2
|
class Version
|
3
3
|
MAJOR = 0 unless defined? Twurl::Version::MAJOR
|
4
4
|
MINOR = 8 unless defined? Twurl::Version::MINOR
|
5
|
-
PATCH =
|
5
|
+
PATCH = 3 unless defined? Twurl::Version::PATCH
|
6
6
|
BETA = nil unless defined? Twurl::Version::BETA # Time.now.to_i.to_s
|
7
7
|
|
8
8
|
class << self
|
data/test/cli_test.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
3
|
class Twurl::CLI::OptionParsingTest < Minitest::Test
|
4
|
+
TEST_PATH = '/1.1/url/does/not/matter.json'
|
5
|
+
|
4
6
|
module CommandParsingTests
|
5
7
|
def test_no_command_specified_falls_to_default_command
|
6
|
-
options = Twurl::CLI.parse_options([
|
8
|
+
options = Twurl::CLI.parse_options([TEST_PATH])
|
7
9
|
assert_equal Twurl::CLI::DEFAULT_COMMAND, options.command
|
8
10
|
end
|
9
11
|
|
@@ -15,24 +17,38 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
15
17
|
|
16
18
|
def test_unsupported_command_specified_sets_default_command
|
17
19
|
unsupported_command = 'unsupported'
|
18
|
-
options = Twurl::CLI.parse_options([unsupported_command])
|
20
|
+
options = Twurl::CLI.parse_options([TEST_PATH, unsupported_command])
|
19
21
|
assert_equal Twurl::CLI::DEFAULT_COMMAND, options.command
|
20
22
|
end
|
21
23
|
end
|
22
24
|
include CommandParsingTests
|
23
25
|
|
26
|
+
module PathParsingTests
|
27
|
+
def test_missing_path_throws_no_path_found
|
28
|
+
stub(Twurl::CLI).puts
|
29
|
+
assert_raises Twurl::CLI::NoPathFound do
|
30
|
+
Twurl::CLI.parse_options([])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_uri_params_are_encoded
|
35
|
+
options = Twurl::CLI.parse_options(["/1.1/url?baz=bamf:rofl"])
|
36
|
+
assert_equal options.path, "/1.1/url?baz=bamf%3Arofl"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
include PathParsingTests
|
40
|
+
|
24
41
|
module RequestMethodParsingTests
|
25
42
|
def test_request_method_is_default_if_unspecified
|
26
|
-
options = Twurl::CLI.parse_options([
|
43
|
+
options = Twurl::CLI.parse_options([TEST_PATH])
|
27
44
|
assert_equal Twurl::Options::DEFAULT_REQUEST_METHOD, options.request_method
|
28
45
|
end
|
29
46
|
|
30
47
|
def test_specifying_a_request_method_extracts_and_normalizes_request_method
|
31
48
|
variations = [%w[-X put], %w[-X PUT], %w[--request-method PUT], %w[--request-method put]]
|
32
49
|
variations.each do |option_variation|
|
33
|
-
|
34
|
-
|
35
|
-
order_variant_2 = [path, option_variation].flatten
|
50
|
+
order_variant_1 = [option_variation, TEST_PATH].flatten
|
51
|
+
order_variant_2 = [TEST_PATH, option_variation].flatten
|
36
52
|
[order_variant_1, order_variant_2].each do |args|
|
37
53
|
options = Twurl::CLI.parse_options(args)
|
38
54
|
assert_equal 'put', options.request_method
|
@@ -41,7 +57,7 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
41
57
|
end
|
42
58
|
|
43
59
|
def test_specifying_unsupported_request_method_returns_an_error
|
44
|
-
Twurl::CLI.parse_options(['-X', 'UNSUPPORTED'])
|
60
|
+
Twurl::CLI.parse_options([TEST_PATH, '-X', 'UNSUPPORTED'])
|
45
61
|
end
|
46
62
|
end
|
47
63
|
include RequestMethodParsingTests
|
@@ -50,13 +66,13 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
50
66
|
def test_extracting_the_consumer_key
|
51
67
|
mock(Twurl::CLI).prompt_for('Consumer key').never
|
52
68
|
|
53
|
-
options = Twurl::CLI.parse_options(['-c', 'the-key'])
|
69
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-c', 'the-key'])
|
54
70
|
assert_equal 'the-key', options.consumer_key
|
55
71
|
end
|
56
72
|
|
57
73
|
def test_consumer_key_option_with_no_value_prompts_user_for_value
|
58
74
|
mock(Twurl::CLI).prompt_for('Consumer key').times(1) { 'inputted-key'}
|
59
|
-
options = Twurl::CLI.parse_options(['-c'])
|
75
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-c'])
|
60
76
|
assert_equal 'inputted-key', options.consumer_key
|
61
77
|
end
|
62
78
|
end
|
@@ -64,39 +80,39 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
64
80
|
|
65
81
|
module DataParsingTests
|
66
82
|
def test_extracting_a_single_key_value_pair
|
67
|
-
options = Twurl::CLI.parse_options(['-d', 'key=value'])
|
83
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key=value'])
|
68
84
|
assert_equal({'key' => 'value'}, options.data)
|
69
85
|
|
70
|
-
options = Twurl::CLI.parse_options(['--data', 'key=value'])
|
86
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '--data', 'key=value'])
|
71
87
|
assert_equal({'key' => 'value'}, options.data)
|
72
88
|
end
|
73
89
|
|
74
90
|
def test_passing_data_and_no_explicit_request_method_defaults_request_method_to_post
|
75
|
-
options = Twurl::CLI.parse_options(['-d', 'key=value'])
|
91
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key=value'])
|
76
92
|
assert_equal 'post', options.request_method
|
77
93
|
end
|
78
94
|
|
79
95
|
def test_passing_data_and_an_explicit_request_method_uses_the_specified_method
|
80
|
-
options = Twurl::CLI.parse_options(['-d', 'key=value', '-X', 'DELETE'])
|
96
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key=value', '-X', 'DELETE'])
|
81
97
|
assert_equal({'key' => 'value'}, options.data)
|
82
98
|
assert_equal 'delete', options.request_method
|
83
99
|
end
|
84
100
|
|
85
101
|
def test_multiple_pairs_when_option_is_specified_multiple_times_on_command_line_collects_all
|
86
|
-
options = Twurl::CLI.parse_options(['-d', 'key=value', '-d', 'another=pair'])
|
102
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key=value', '-d', 'another=pair'])
|
87
103
|
assert_equal({'key' => 'value', 'another' => 'pair'}, options.data)
|
88
104
|
end
|
89
105
|
|
90
106
|
def test_multiple_pairs_separated_by_ampersand_are_all_captured
|
91
|
-
options = Twurl::CLI.parse_options(['-d', 'key=value&another=pair'])
|
107
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key=value&another=pair'])
|
92
108
|
assert_equal({'key' => 'value', 'another' => 'pair'}, options.data)
|
93
109
|
end
|
94
110
|
|
95
111
|
def test_extracting_an_empty_key_value_pair
|
96
|
-
options = Twurl::CLI.parse_options(['-d', 'key='])
|
112
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-d', 'key='])
|
97
113
|
assert_equal({'key' => ''}, options.data)
|
98
114
|
|
99
|
-
options = Twurl::CLI.parse_options(['--data', 'key='])
|
115
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '--data', 'key='])
|
100
116
|
assert_equal({'key' => ''}, options.data)
|
101
117
|
end
|
102
118
|
end
|
@@ -104,15 +120,15 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
104
120
|
|
105
121
|
module HeaderParsingTests
|
106
122
|
def test_extracting_a_single_header
|
107
|
-
options = Twurl::CLI.parse_options(['-A', 'Key: Value'])
|
123
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-A', 'Key: Value'])
|
108
124
|
assert_equal({'Key' => 'Value'}, options.headers)
|
109
125
|
|
110
|
-
options = Twurl::CLI.parse_options(['--header', 'Key: Value'])
|
126
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '--header', 'Key: Value'])
|
111
127
|
assert_equal({'Key' => 'Value'}, options.headers)
|
112
128
|
end
|
113
129
|
|
114
130
|
def test_multiple_headers_when_option_is_specified_multiple_times_on_command_line_collects_all
|
115
|
-
options = Twurl::CLI.parse_options(['-A', 'Key: Value', '-A', 'Another: Pair'])
|
131
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-A', 'Key: Value', '-A', 'Another: Pair'])
|
116
132
|
assert_equal({'Key' => 'Value', 'Another' => 'Pair'}, options.headers)
|
117
133
|
end
|
118
134
|
end
|
@@ -120,13 +136,13 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
120
136
|
|
121
137
|
module SSLDisablingTests
|
122
138
|
def test_ssl_is_on_by_default
|
123
|
-
options = Twurl::CLI.parse_options([])
|
139
|
+
options = Twurl::CLI.parse_options([TEST_PATH])
|
124
140
|
assert options.ssl?
|
125
141
|
end
|
126
142
|
|
127
143
|
def test_passing_no_ssl_option_disables_ssl
|
128
144
|
['-U', '--no-ssl'].each do |switch|
|
129
|
-
options = Twurl::CLI.parse_options([switch])
|
145
|
+
options = Twurl::CLI.parse_options([TEST_PATH, switch])
|
130
146
|
assert !options.ssl?
|
131
147
|
end
|
132
148
|
end
|
@@ -135,7 +151,7 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
135
151
|
|
136
152
|
module HostOptionTests
|
137
153
|
def test_not_specifying_host_sets_it_to_the_default
|
138
|
-
options = Twurl::CLI.parse_options([])
|
154
|
+
options = Twurl::CLI.parse_options([TEST_PATH])
|
139
155
|
assert_equal Twurl::Options::DEFAULT_HOST, options.host
|
140
156
|
end
|
141
157
|
|
@@ -143,24 +159,30 @@ class Twurl::CLI::OptionParsingTest < Minitest::Test
|
|
143
159
|
custom_host = 'localhost:3000'
|
144
160
|
assert Twurl::Options::DEFAULT_HOST != custom_host
|
145
161
|
|
146
|
-
[['-H', custom_host], ['--host', custom_host]].each do |option_combination|
|
162
|
+
[[TEST_PATH, '-H', custom_host], [TEST_PATH, '--host', custom_host]].each do |option_combination|
|
147
163
|
options = Twurl::CLI.parse_options(option_combination)
|
148
164
|
assert_equal custom_host, options.host
|
149
165
|
end
|
150
166
|
end
|
167
|
+
|
168
|
+
def test_protocol_is_stripped_from_host
|
169
|
+
custom_host = 'localhost:3000'
|
170
|
+
options = Twurl::CLI.parse_options([TEST_PATH, '-H', "https://"+custom_host])
|
171
|
+
assert_equal custom_host, options.host
|
172
|
+
end
|
151
173
|
end
|
152
174
|
include HostOptionTests
|
153
175
|
|
154
176
|
module ProxyOptionTests
|
155
177
|
def test_not_specifying_proxy_sets_it_to_nil
|
156
|
-
options = Twurl::CLI.parse_options([])
|
178
|
+
options = Twurl::CLI.parse_options([TEST_PATH])
|
157
179
|
assert_equal nil, options.proxy
|
158
180
|
end
|
159
181
|
|
160
182
|
def test_setting_proxy_updates_to_requested_value
|
161
183
|
custom_proxy = 'localhost:80'
|
162
184
|
|
163
|
-
[['-P', custom_proxy], ['--proxy', custom_proxy]].each do |option_combination|
|
185
|
+
[[TEST_PATH, '-P', custom_proxy], [TEST_PATH, '--proxy', custom_proxy]].each do |option_combination|
|
164
186
|
options = Twurl::CLI.parse_options(option_combination)
|
165
187
|
assert_equal custom_proxy, options.proxy
|
166
188
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twurl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-07-12 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: oauth
|