turbot 0.1.34 → 0.1.35
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/README.md +6 -0
- data/lib/turbot/auth.rb +1 -1
- data/lib/turbot/cli.rb +4 -0
- data/lib/turbot/command/bots.rb +17 -15
- data/lib/turbot/version.rb +1 -1
- data/spec/schemas/{dummy_schema.json → dummy-schema.json} +0 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/turbot/auth_spec.rb +75 -75
- data/spec/turbot/client/ssl_endpoint_spec.rb +6 -6
- data/spec/turbot/client_spec.rb +4 -4
- data/spec/turbot/command/bots_spec.rb +50 -24
- metadata +151 -8
data/README.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
Turbot CLI
|
2
2
|
==========
|
3
3
|
|
4
|
+
[](https://badge.fury.io/rb/turbot)
|
5
|
+
[](https://travis-ci.org/openc/turbot-client)
|
6
|
+
[](https://gemnasium.com/openc/turbot-client)
|
7
|
+
[](https://coveralls.io/r/openc/turbot-client)
|
8
|
+
[](https://codeclimate.com/github/openc/turbot-client)
|
9
|
+
|
4
10
|
The Turbot CLI is used to manage Turbot apps from the command line.
|
5
11
|
|
6
12
|
Setup
|
data/lib/turbot/auth.rb
CHANGED
@@ -197,7 +197,7 @@ class Turbot::Auth
|
|
197
197
|
# write these to a hidden file
|
198
198
|
write_credentials
|
199
199
|
check
|
200
|
-
rescue Turbot::API::Errors::NotFound, Turbot::API::Errors::Unauthorized => e
|
200
|
+
rescue RestClient::Unauthorized, Turbot::API::Errors::NotFound, Turbot::API::Errors::Unauthorized => e
|
201
201
|
delete_credentials
|
202
202
|
display "Authentication failed."
|
203
203
|
retry if retry_login?
|
data/lib/turbot/cli.rb
CHANGED
data/lib/turbot/command/bots.rb
CHANGED
@@ -151,8 +151,7 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
151
151
|
error("There's already a bot called #{bot} registered with Turbot. Bot names must be unique.")
|
152
152
|
end
|
153
153
|
|
154
|
-
|
155
|
-
manifest = parsed_manifest(working_dir)
|
154
|
+
manifest = parsed_manifest(working_directory)
|
156
155
|
response = api.create_bot(bot, manifest)
|
157
156
|
if response.is_a? Turbot::API::FailureResponse
|
158
157
|
error(response.message)
|
@@ -174,11 +173,10 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
174
173
|
puts "Are you happy your bot produces valid data (e.g. with `turbot bots:validate`)? [Y/n]"
|
175
174
|
confirmed = ask
|
176
175
|
error("Aborting push") if !confirmed.downcase.empty? && confirmed.downcase != "y"
|
177
|
-
|
178
|
-
manifest = parsed_manifest(working_dir)
|
176
|
+
manifest = parsed_manifest(working_directory)
|
179
177
|
archive = Tempfile.new(bot)
|
180
178
|
archive_path = "#{archive.path}.zip"
|
181
|
-
create_zip_archive(archive_path,
|
179
|
+
create_zip_archive(archive_path, working_directory, manifest['files'] + ['manifest.json'])
|
182
180
|
|
183
181
|
response = File.open(archive_path) {|file| api.update_code(bot, file)}
|
184
182
|
case response
|
@@ -199,18 +197,18 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
199
197
|
# Validating example... done
|
200
198
|
|
201
199
|
def validate
|
202
|
-
scraper_path = shift_argument || scraper_file(
|
200
|
+
scraper_path = shift_argument || scraper_file(working_directory)
|
203
201
|
validate_arguments!
|
204
|
-
config = parsed_manifest(
|
202
|
+
config = parsed_manifest(working_directory)
|
205
203
|
|
206
|
-
%w(bot_id data_type identifying_fields files publisher).each do |key|
|
204
|
+
%w(bot_id data_type identifying_fields files language publisher).each do |key|
|
207
205
|
error("Manifest is missing #{key}") unless config.has_key?(key)
|
208
206
|
end
|
209
207
|
|
210
208
|
type = config["data_type"]
|
211
209
|
|
212
210
|
handler = ValidationHandler.new
|
213
|
-
runner = TurbotRunner::Runner.new(
|
211
|
+
runner = TurbotRunner::Runner.new(working_directory, :record_handler => handler)
|
214
212
|
rc = runner.run
|
215
213
|
|
216
214
|
puts
|
@@ -233,7 +231,7 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
233
231
|
validate_arguments!
|
234
232
|
|
235
233
|
handler = DumpHandler.new
|
236
|
-
runner = TurbotRunner::Runner.new(
|
234
|
+
runner = TurbotRunner::Runner.new(working_directory, :record_handler => handler)
|
237
235
|
rc = runner.run
|
238
236
|
|
239
237
|
puts
|
@@ -255,7 +253,7 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
255
253
|
#
|
256
254
|
# def single
|
257
255
|
# # This will need to be language-aware, eventually
|
258
|
-
# scraper_path = shift_argument || scraper_file(
|
256
|
+
# scraper_path = shift_argument || scraper_file(working_directory)
|
259
257
|
# validate_arguments!
|
260
258
|
# print 'Arguments (as JSON object, e.g. {"id":"ABC123"}: '
|
261
259
|
# arg = ask
|
@@ -276,9 +274,9 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
276
274
|
def preview
|
277
275
|
validate_arguments!
|
278
276
|
|
279
|
-
config = parsed_manifest(
|
277
|
+
config = parsed_manifest(working_directory)
|
280
278
|
|
281
|
-
response = api.update_bot(bot, parsed_manifest(
|
279
|
+
response = api.update_bot(bot, parsed_manifest(working_directory))
|
282
280
|
if !response.is_a? Turbot::API::SuccessResponse
|
283
281
|
error(response.message)
|
284
282
|
end
|
@@ -291,7 +289,7 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
291
289
|
puts "Sending to turbot... "
|
292
290
|
|
293
291
|
handler = PreviewHandler.new(bot, api)
|
294
|
-
runner = TurbotRunner::Runner.new(
|
292
|
+
runner = TurbotRunner::Runner.new(working_directory, :record_handler => handler)
|
295
293
|
rc = runner.run
|
296
294
|
|
297
295
|
puts
|
@@ -332,8 +330,12 @@ class Turbot::Command::Bots < Turbot::Command::Base
|
|
332
330
|
Dir.glob("scraper*").reject{|n| !n.match(/(rb|py)$/)}.first
|
333
331
|
end
|
334
332
|
|
333
|
+
def working_directory
|
334
|
+
Dir.pwd
|
335
|
+
end
|
336
|
+
|
335
337
|
def manifest_path
|
336
|
-
File.join(
|
338
|
+
File.join(working_directory, 'manifest.json')
|
337
339
|
end
|
338
340
|
|
339
341
|
def create_zip_archive(archive_path, basepath, subpaths)
|
data/lib/turbot/version.rb
CHANGED
File without changes
|
data/spec/spec_helper.rb
CHANGED
@@ -2,6 +2,13 @@ $stdin = File.new("/dev/null")
|
|
2
2
|
|
3
3
|
require "rubygems"
|
4
4
|
|
5
|
+
require "simplecov"
|
6
|
+
require "coveralls"
|
7
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter "spec"
|
10
|
+
end
|
11
|
+
|
5
12
|
require "excon"
|
6
13
|
Excon.defaults[:mock] = true
|
7
14
|
|
@@ -30,7 +37,7 @@ def org_api
|
|
30
37
|
end
|
31
38
|
|
32
39
|
def stub_api_request(method, path)
|
33
|
-
stub_request(method, "
|
40
|
+
stub_request(method, "http://turbot.opencorporates.com#{path}")
|
34
41
|
end
|
35
42
|
|
36
43
|
def prepare_command(klass)
|
data/spec/turbot/auth_spec.rb
CHANGED
@@ -63,7 +63,7 @@ module Turbot
|
|
63
63
|
before do
|
64
64
|
@cli.stub!(:ask_for_credentials).and_return(['new_user', 'new_password'])
|
65
65
|
@cli.stub!(:check)
|
66
|
-
@cli.should_receive(:check_for_associated_ssh_key)
|
66
|
+
# @cli.should_receive(:check_for_associated_ssh_key)
|
67
67
|
@cli.reauthorize
|
68
68
|
end
|
69
69
|
it "updates saved credentials" do
|
@@ -89,7 +89,7 @@ module Turbot
|
|
89
89
|
it "asks for credentials when the file doesn't exist" do
|
90
90
|
@cli.delete_credentials
|
91
91
|
@cli.should_receive(:ask_for_credentials).and_return(["u", "p"])
|
92
|
-
@cli.should_receive(:check_for_associated_ssh_key)
|
92
|
+
# @cli.should_receive(:check_for_associated_ssh_key)
|
93
93
|
@cli.user.should == 'u'
|
94
94
|
@cli.password.should == 'p'
|
95
95
|
end
|
@@ -99,7 +99,7 @@ module Turbot
|
|
99
99
|
@cli.stub!(:check)
|
100
100
|
@cli.stub!(:ask_for_credentials).and_return("username", "apikey")
|
101
101
|
@cli.should_receive(:write_credentials)
|
102
|
-
@cli.should_receive(:check_for_associated_ssh_key)
|
102
|
+
# @cli.should_receive(:check_for_associated_ssh_key)
|
103
103
|
@cli.ask_for_and_save_credentials
|
104
104
|
end
|
105
105
|
|
@@ -107,7 +107,7 @@ module Turbot
|
|
107
107
|
@cli.stub!(:write_credentials)
|
108
108
|
@cli.stub!(:retry_login?).and_return(false)
|
109
109
|
@cli.stub!(:ask_for_credentials).and_return("username", "apikey")
|
110
|
-
@cli.stub!(:check) { raise
|
110
|
+
@cli.stub!(:check) { raise RestClient::Unauthorized }
|
111
111
|
@cli.should_receive(:delete_credentials)
|
112
112
|
lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
|
113
113
|
end
|
@@ -117,7 +117,7 @@ module Turbot
|
|
117
117
|
@cli.stub!(:write_credentials)
|
118
118
|
@cli.stub!(:delete_credentials)
|
119
119
|
@cli.stub!(:ask_for_credentials).and_return("username", "apikey")
|
120
|
-
@cli.stub!(:check) { raise
|
120
|
+
@cli.stub!(:check) { raise RestClient::Unauthorized }
|
121
121
|
@cli.should_receive(:ask_for_credentials).exactly(3).times
|
122
122
|
lambda { @cli.ask_for_and_save_credentials }.should raise_error(SystemExit)
|
123
123
|
end
|
@@ -125,7 +125,7 @@ module Turbot
|
|
125
125
|
it "writes the login information to the credentials file for the 'turbot login' command" do
|
126
126
|
@cli.stub!(:ask_for_credentials).and_return(['one', 'two'])
|
127
127
|
@cli.stub!(:check)
|
128
|
-
@cli.should_receive(:check_for_associated_ssh_key)
|
128
|
+
# @cli.should_receive(:check_for_associated_ssh_key)
|
129
129
|
@cli.reauthorize
|
130
130
|
Netrc.read(@cli.netrc_path)["api.#{@cli.host}"].should == (['one', 'two'])
|
131
131
|
end
|
@@ -141,74 +141,74 @@ module Turbot
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
describe "automatic key uploading" do
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
end
|
144
|
+
# describe "automatic key uploading" do
|
145
|
+
# before(:each) do
|
146
|
+
# FileUtils.mkdir_p("#{@cli.home_directory}/.ssh")
|
147
|
+
# @cli.stub!(:ask_for_credentials).and_return("username", "apikey")
|
148
|
+
# end
|
149
|
+
|
150
|
+
# describe "an account with existing keys" do
|
151
|
+
# before :each do
|
152
|
+
# @api = mock(Object)
|
153
|
+
# @response = mock(Object)
|
154
|
+
# @response.should_receive(:body).and_return(['existingkeys'])
|
155
|
+
# @api.should_receive(:get_ssh_keys).and_return(@response)
|
156
|
+
# @cli.should_receive(:api).and_return(@api)
|
157
|
+
# end
|
158
|
+
|
159
|
+
# it "should not do anything if the account already has keys" do
|
160
|
+
# @cli.should_not_receive(:associate_key)
|
161
|
+
# @cli.check_for_associated_ssh_key
|
162
|
+
# end
|
163
|
+
# end
|
164
|
+
|
165
|
+
# describe "an account with no keys" do
|
166
|
+
# before :each do
|
167
|
+
# @api = mock(Object)
|
168
|
+
# @response = mock(Object)
|
169
|
+
# @response.should_receive(:body).and_return([])
|
170
|
+
# @api.should_receive(:get_ssh_keys).and_return(@response)
|
171
|
+
# @cli.should_receive(:api).and_return(@api)
|
172
|
+
# end
|
173
|
+
|
174
|
+
# describe "with zero public keys" do
|
175
|
+
# it "should ask to generate a key" do
|
176
|
+
# @cli.should_receive(:ask).and_return("y")
|
177
|
+
# @cli.should_receive(:generate_ssh_key).with("id_rsa")
|
178
|
+
# @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
|
179
|
+
# @cli.check_for_associated_ssh_key
|
180
|
+
# end
|
181
|
+
# end
|
182
|
+
|
183
|
+
# describe "with one public key" do
|
184
|
+
# before(:each) { FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub") }
|
185
|
+
# after(:each) { FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub") }
|
186
|
+
|
187
|
+
# it "should upload the key" do
|
188
|
+
# @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa.pub")
|
189
|
+
# @cli.check_for_associated_ssh_key
|
190
|
+
# end
|
191
|
+
# end
|
192
|
+
|
193
|
+
# describe "with many public keys" do
|
194
|
+
# before(:each) do
|
195
|
+
# FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa.pub")
|
196
|
+
# FileUtils.touch("#{@cli.home_directory}/.ssh/id_rsa2.pub")
|
197
|
+
# end
|
198
|
+
|
199
|
+
# after(:each) do
|
200
|
+
# FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa.pub")
|
201
|
+
# FileUtils.rm("#{@cli.home_directory}/.ssh/id_rsa2.pub")
|
202
|
+
# end
|
203
|
+
|
204
|
+
# it "should ask which key to upload" do
|
205
|
+
# File.open("#{@cli.home_directory}/.ssh/id_rsa.pub", "w") { |f| f.puts }
|
206
|
+
# @cli.should_receive(:associate_key).with("#{@cli.home_directory}/.ssh/id_rsa2.pub")
|
207
|
+
# @cli.should_receive(:ask).and_return("2")
|
208
|
+
# @cli.check_for_associated_ssh_key
|
209
|
+
# end
|
210
|
+
# end
|
211
|
+
# end
|
212
|
+
# end
|
213
213
|
end
|
214
214
|
end
|
@@ -7,20 +7,20 @@ describe Turbot::Client, "ssl endpoints" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "adds an ssl endpoint" do
|
10
|
-
stub_request(:post, "
|
10
|
+
stub_request(:post, "http://turbot.opencorporates.com/bots/example/ssl-endpoints").
|
11
11
|
with(:body => { :accept => "json", :pem => "pem content", :key => "key content" }).
|
12
12
|
to_return(:body => %{ {"cname": "tokyo-1050" } })
|
13
13
|
@client.ssl_endpoint_add("example", "pem content", "key content").should == { "cname" => "tokyo-1050" }
|
14
14
|
end
|
15
15
|
|
16
16
|
it "gets info on an ssl endpoint" do
|
17
|
-
stub_request(:get, "
|
17
|
+
stub_request(:get, "http://turbot.opencorporates.com/bots/example/ssl-endpoints/tokyo-1050").
|
18
18
|
to_return(:body => %{ {"cname": "tokyo-1050" } })
|
19
19
|
@client.ssl_endpoint_info("example", "tokyo-1050").should == { "cname" => "tokyo-1050" }
|
20
20
|
end
|
21
21
|
|
22
22
|
it "lists ssl endpoints for an bot" do
|
23
|
-
stub_request(:get, "
|
23
|
+
stub_request(:get, "http://turbot.opencorporates.com/bots/example/ssl-endpoints").
|
24
24
|
to_return(:body => %{ [{"cname": "tokyo-1050" }, {"cname": "tokyo-1051" }] })
|
25
25
|
@client.ssl_endpoint_list("example").should == [
|
26
26
|
{ "cname" => "tokyo-1050" },
|
@@ -29,18 +29,18 @@ describe Turbot::Client, "ssl endpoints" do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it "removes an ssl endpoint" do
|
32
|
-
stub_request(:delete, "
|
32
|
+
stub_request(:delete, "http://turbot.opencorporates.com/bots/example/ssl-endpoints/tokyo-1050")
|
33
33
|
@client.ssl_endpoint_remove("example", "tokyo-1050")
|
34
34
|
end
|
35
35
|
|
36
36
|
it "rolls back an ssl endpoint" do
|
37
|
-
stub_request(:post, "
|
37
|
+
stub_request(:post, "http://turbot.opencorporates.com/bots/example/ssl-endpoints/tokyo-1050/rollback").
|
38
38
|
to_return(:body => %{ {"cname": "tokyo-1050" } })
|
39
39
|
@client.ssl_endpoint_rollback("example", "tokyo-1050").should == { "cname" => "tokyo-1050" }
|
40
40
|
end
|
41
41
|
|
42
42
|
it "updates an ssl endpoint" do
|
43
|
-
stub_request(:put, "
|
43
|
+
stub_request(:put, "http://turbot.opencorporates.com/bots/example/ssl-endpoints/tokyo-1050").
|
44
44
|
with(:body => { :accept => "json", :pem => "pem content", :key => "key content" }).
|
45
45
|
to_return(:body => %{ {"cname": "tokyo-1050" } })
|
46
46
|
@client.ssl_endpoint_update("example", "tokyo-1050", "pem content", "key content").should == { "cname" => "tokyo-1050" }
|
data/spec/turbot/client_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe Turbot::Client do
|
|
14
14
|
|
15
15
|
it "Client.auth -> get user details" do
|
16
16
|
user_info = { "api_key" => "abc" }
|
17
|
-
stub_request(:post, "
|
17
|
+
stub_request(:post, "http://foo:bar@turbot.opencorporates.com/login").to_return(:body => json_encode(user_info))
|
18
18
|
capture_stderr do # capture deprecation message
|
19
19
|
Turbot::Client.auth("foo", "bar").should == user_info
|
20
20
|
end
|
@@ -450,7 +450,7 @@ describe Turbot::Client do
|
|
450
450
|
end
|
451
451
|
|
452
452
|
it "install_addon(bot_name, addon_name) with response" do
|
453
|
-
stub_request(:post, "
|
453
|
+
stub_request(:post, "http://turbot.opencorporates.com/bots/example/addons/addon1").
|
454
454
|
to_return(:body => json_encode({'price' => 'free', 'message' => "Don't Panic"}))
|
455
455
|
|
456
456
|
@client.install_addon('example', 'addon1').
|
@@ -458,7 +458,7 @@ describe Turbot::Client do
|
|
458
458
|
end
|
459
459
|
|
460
460
|
it "upgrade_addon(bot_name, addon_name) with response" do
|
461
|
-
stub_request(:put, "
|
461
|
+
stub_request(:put, "http://turbot.opencorporates.com/bots/example/addons/addon1").
|
462
462
|
to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
|
463
463
|
|
464
464
|
@client.upgrade_addon('example', 'addon1').
|
@@ -466,7 +466,7 @@ describe Turbot::Client do
|
|
466
466
|
end
|
467
467
|
|
468
468
|
it "downgrade_addon(bot_name, addon_name) with response" do
|
469
|
-
stub_request(:put, "
|
469
|
+
stub_request(:put, "http://turbot.opencorporates.com/bots/example/addons/addon1").
|
470
470
|
to_return(:body => json_encode('price' => 'free', 'message' => "Don't Panic"))
|
471
471
|
|
472
472
|
@client.downgrade_addon('example', 'addon1').
|
@@ -3,70 +3,96 @@ require "turbot/command/bots"
|
|
3
3
|
|
4
4
|
describe Turbot::Command::Bots do
|
5
5
|
describe "validate" do
|
6
|
+
let :working_directory do
|
7
|
+
Dir.mktmpdir
|
8
|
+
end
|
9
|
+
|
10
|
+
let :schemas_directory do
|
11
|
+
Dir.mktmpdir
|
12
|
+
end
|
13
|
+
|
6
14
|
before do
|
7
15
|
config = {
|
8
16
|
'bot_id' => 'dummy bot',
|
9
17
|
'data_type' => 'dummy',
|
10
18
|
'identifying_fields' => ['name'],
|
11
19
|
'files' => 'scraper.rb',
|
20
|
+
'language' => 'ruby',
|
21
|
+
'publisher' => {
|
22
|
+
'name' => 'Dummy',
|
23
|
+
'url' => 'http://example.com/',
|
24
|
+
'terms' => 'MIT',
|
25
|
+
'terms_url' => 'http://opensource.org/licenses/MIT',
|
26
|
+
},
|
12
27
|
}
|
13
28
|
Turbot::Command::Bots.any_instance.stub(:parsed_manifest).and_return(config)
|
29
|
+
|
30
|
+
# Create a manifest.json file for TurbotRunner to find.
|
31
|
+
File.open(File.join(working_directory, 'manifest.json'), 'w') { |f| f << JSON.dump(config) }
|
32
|
+
Turbot::Command::Bots.any_instance.stub(:working_directory).and_return(working_directory)
|
33
|
+
|
34
|
+
# Change the path to TurbotRunner's schemas.
|
35
|
+
begin
|
36
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
37
|
+
TurbotRunner::SCHEMAS_PATH = File.expand_path('../../../schemas', __FILE__)
|
38
|
+
ensure
|
39
|
+
$VERBOSE = old_verbose
|
40
|
+
end
|
14
41
|
end
|
15
42
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
and_return(File.expand_path('../../../schemas/dummy_schema.json', __FILE__))
|
43
|
+
after do
|
44
|
+
FileUtils.remove_entry_secure(working_directory)
|
45
|
+
FileUtils.remove_entry_secure(schemas_directory)
|
46
|
+
end
|
21
47
|
|
48
|
+
def define_scraper(hash)
|
49
|
+
File.open(File.join(working_directory, 'scraper.rb'), 'w') do |f|
|
50
|
+
f << <<-EOL
|
51
|
+
require 'json'
|
52
|
+
puts JSON.dump(#{hash})
|
53
|
+
EOL
|
22
54
|
end
|
55
|
+
end
|
23
56
|
|
57
|
+
context "for data_type with schema" do
|
24
58
|
it "says bot is valid if its output matches the schema" do
|
25
|
-
|
26
|
-
stub(:run_scraper_each_line).
|
27
|
-
and_yield({name: 'One'}.to_json)
|
59
|
+
define_scraper(name: 'One')
|
28
60
|
|
29
61
|
stderr, stdout = execute("bots:validate")
|
30
62
|
|
63
|
+
stdout.should include 'Validated 1 records!'
|
31
64
|
stderr.should == ""
|
32
|
-
stdout.should include 'Validated 1 records successfully'
|
33
65
|
end
|
34
66
|
|
35
67
|
it "says bot is invalid if its output doesn't match the schema" do
|
36
|
-
|
37
|
-
stub(:run_scraper_each_line).
|
38
|
-
and_yield({name: 123}.to_json)
|
68
|
+
define_scraper(name: 123)
|
39
69
|
|
40
70
|
stderr, stdout = execute("bots:validate")
|
41
71
|
|
42
|
-
stdout.should
|
43
|
-
stderr.should
|
72
|
+
stdout.should include 'Property of wrong type'
|
73
|
+
stderr.should == ""
|
44
74
|
end
|
45
75
|
|
46
76
|
context "for bot that doesn't output identifying fields" do
|
47
77
|
it "says bot is invalid" do
|
48
|
-
|
49
|
-
stub(:run_scraper_each_line).
|
50
|
-
and_yield({title: 'One'}.to_json)
|
78
|
+
define_scraper(title: 'One')
|
51
79
|
|
52
80
|
stderr, stdout = execute("bots:validate")
|
53
81
|
|
54
|
-
stdout.should
|
55
|
-
stderr.should
|
82
|
+
stdout.should include 'There were no values provided for any of the identifying fields'
|
83
|
+
stderr.should == ""
|
56
84
|
end
|
57
85
|
end
|
58
86
|
end
|
59
87
|
|
60
88
|
context "for data_type without schema" do
|
61
89
|
it "says bot is invalid" do
|
62
|
-
|
63
|
-
stub(:get_schema).
|
64
|
-
and_return(nil)
|
90
|
+
define_scraper({})
|
65
91
|
|
66
92
|
stderr, stdout = execute("bots:validate")
|
67
93
|
|
68
|
-
stdout.should
|
69
|
-
stderr.should
|
94
|
+
stdout.should include "Validated 0 records before bot failed!"
|
95
|
+
stderr.should == ""
|
70
96
|
end
|
71
97
|
end
|
72
98
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.35
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-01-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: turbotlib
|
@@ -130,7 +130,7 @@ dependencies:
|
|
130
130
|
requirements:
|
131
131
|
- - '='
|
132
132
|
- !ruby/object:Gem::Version
|
133
|
-
version: 0.2.
|
133
|
+
version: 0.2.7
|
134
134
|
type: :runtime
|
135
135
|
prerelease: false
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -138,7 +138,7 @@ dependencies:
|
|
138
138
|
requirements:
|
139
139
|
- - '='
|
140
140
|
- !ruby/object:Gem::Version
|
141
|
-
version: 0.2.
|
141
|
+
version: 0.2.7
|
142
142
|
- !ruby/object:Gem::Dependency
|
143
143
|
name: excon
|
144
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -155,8 +155,152 @@ dependencies:
|
|
155
155
|
- - ! '>='
|
156
156
|
- !ruby/object:Gem::Version
|
157
157
|
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: coveralls
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: fakefs
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: json
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: rake
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - ! '>='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: 0.8.7
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 0.8.7
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: rr
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ~>
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 1.0.2
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ~>
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: 1.0.2
|
238
|
+
- !ruby/object:Gem::Dependency
|
239
|
+
name: rspec
|
240
|
+
requirement: !ruby/object:Gem::Requirement
|
241
|
+
none: false
|
242
|
+
requirements:
|
243
|
+
- - '='
|
244
|
+
- !ruby/object:Gem::Version
|
245
|
+
version: 2.13.0
|
246
|
+
type: :development
|
247
|
+
prerelease: false
|
248
|
+
version_requirements: !ruby/object:Gem::Requirement
|
249
|
+
none: false
|
250
|
+
requirements:
|
251
|
+
- - '='
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: 2.13.0
|
254
|
+
- !ruby/object:Gem::Dependency
|
255
|
+
name: sqlite3
|
256
|
+
requirement: !ruby/object:Gem::Requirement
|
257
|
+
none: false
|
258
|
+
requirements:
|
259
|
+
- - ! '>='
|
260
|
+
- !ruby/object:Gem::Version
|
261
|
+
version: '0'
|
262
|
+
type: :development
|
263
|
+
prerelease: false
|
264
|
+
version_requirements: !ruby/object:Gem::Requirement
|
265
|
+
none: false
|
266
|
+
requirements:
|
267
|
+
- - ! '>='
|
268
|
+
- !ruby/object:Gem::Version
|
269
|
+
version: '0'
|
270
|
+
- !ruby/object:Gem::Dependency
|
271
|
+
name: tins
|
272
|
+
requirement: !ruby/object:Gem::Requirement
|
273
|
+
none: false
|
274
|
+
requirements:
|
275
|
+
- - ~>
|
276
|
+
- !ruby/object:Gem::Version
|
277
|
+
version: 1.6.0
|
278
|
+
type: :development
|
279
|
+
prerelease: false
|
280
|
+
version_requirements: !ruby/object:Gem::Requirement
|
281
|
+
none: false
|
282
|
+
requirements:
|
283
|
+
- - ~>
|
284
|
+
- !ruby/object:Gem::Version
|
285
|
+
version: 1.6.0
|
286
|
+
- !ruby/object:Gem::Dependency
|
287
|
+
name: webmock
|
288
|
+
requirement: !ruby/object:Gem::Requirement
|
289
|
+
none: false
|
290
|
+
requirements:
|
291
|
+
- - ! '>='
|
292
|
+
- !ruby/object:Gem::Version
|
293
|
+
version: '0'
|
294
|
+
type: :development
|
295
|
+
prerelease: false
|
296
|
+
version_requirements: !ruby/object:Gem::Requirement
|
297
|
+
none: false
|
298
|
+
requirements:
|
299
|
+
- - ! '>='
|
300
|
+
- !ruby/object:Gem::Version
|
301
|
+
version: '0'
|
158
302
|
description: Client library and command-line tool to deploy and manage apps on Turbot.
|
159
|
-
email: support@turbot.com
|
303
|
+
email: support@turbot.opencorporates.com
|
160
304
|
executables:
|
161
305
|
- turbot
|
162
306
|
extensions: []
|
@@ -196,7 +340,7 @@ files:
|
|
196
340
|
- lib/vendor/turbot/okjson.rb
|
197
341
|
- spec/helper/legacy_help.rb
|
198
342
|
- spec/helper/pg_dump_restore_spec.rb
|
199
|
-
- spec/schemas/
|
343
|
+
- spec/schemas/dummy-schema.json
|
200
344
|
- spec/spec.opts
|
201
345
|
- spec/spec_helper.rb
|
202
346
|
- spec/support/display_message_matcher.rb
|
@@ -223,7 +367,7 @@ files:
|
|
223
367
|
- templates/manifest.json
|
224
368
|
- templates/python/scraper.py
|
225
369
|
- templates/ruby/scraper.rb
|
226
|
-
homepage:
|
370
|
+
homepage: https://turbot.opencorporates.com/
|
227
371
|
licenses:
|
228
372
|
- MIT
|
229
373
|
post_install_message:
|
@@ -249,4 +393,3 @@ signing_key:
|
|
249
393
|
specification_version: 3
|
250
394
|
summary: Client library and CLI to deploy apps on Turbot.
|
251
395
|
test_files: []
|
252
|
-
has_rdoc:
|