twurl 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- options = parse_options(args)
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
- path = arguments.slice!(index)
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
- options.host = host
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
 
@@ -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 = 2 unless defined? Twurl::Version::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
@@ -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(['/1.1/url/does/not/matter.json'])
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(['/1.1/url/does/not/matter.json'])
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
- path = '/1.1/url/does/not/matter.json'
34
- order_variant_1 = [option_variation, path].flatten
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.2
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-06-12 00:00:00.000000000 Z
13
+ date: 2013-07-12 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: oauth