spassky 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile.lock +10 -0
- data/examples/qunit-failing/main.js +11 -0
- data/examples/qunit-failing/qunit.js +1512 -0
- data/examples/qunit-failing/suite.html +9 -0
- data/examples/qunit-passing/main.js +11 -0
- data/examples/qunit-passing/qunit.js +1512 -0
- data/examples/qunit-passing/suite.html +9 -0
- data/features/connection.feature +2 -2
- data/features/device_timeout.feature +4 -4
- data/features/list_devices.feature +21 -0
- data/features/run_html_tests.feature +9 -0
- data/features/run_qunit_tests.feature +49 -19
- data/features/server.feature +2 -5
- data/features/step_definitions/steps.rb +13 -19
- data/lib/spassky/client/cli.rb +9 -2
- data/lib/spassky/client/device_list_retriever.rb +15 -0
- data/lib/spassky/client/pusher.rb +3 -0
- data/lib/spassky/server/app.rb +24 -8
- data/lib/spassky/server/device_database.rb +39 -0
- data/lib/spassky/server/device_list.rb +8 -5
- data/lib/spassky/test_result.rb +15 -15
- data/lib/spassky/version.rb +1 -1
- data/spassky.gemspec +2 -0
- data/spec/spassky/client/cli_spec.rb +26 -0
- data/spec/spassky/client/device_list_retriever_spec.rb +18 -0
- data/spec/spassky/client/pusher_spec.rb +10 -0
- data/spec/spassky/client/test_runner_spec.rb +11 -19
- data/spec/spassky/server/app_spec.rb +40 -10
- data/spec/spassky/server/device_database_spec.rb +76 -0
- data/spec/spassky/server/device_list_spec.rb +19 -16
- data/spec/spassky/test_result_spec.rb +14 -14
- metadata +56 -20
data/features/connection.feature
CHANGED
@@ -2,8 +2,8 @@ Feature: Connection
|
|
2
2
|
In order to run tests with minimal effort
|
3
3
|
As a web developer
|
4
4
|
I want to connect devices to a constantly running service
|
5
|
-
|
5
|
+
|
6
6
|
Scenario: Connect a device
|
7
7
|
Given a connected mobile device "ipad"
|
8
8
|
Then it should wait for a test to run
|
9
|
-
And the word "Idle" should appear on the device
|
9
|
+
And the word "Idle" should appear on the device
|
@@ -2,7 +2,7 @@ Feature: Device Timeout
|
|
2
2
|
In order for a clean test run
|
3
3
|
As a Developer-in-Test
|
4
4
|
I want to ignore devices that haven't connected recently
|
5
|
-
|
5
|
+
|
6
6
|
Background: One passing test
|
7
7
|
Given a file named "timed-out.html" with:
|
8
8
|
"""
|
@@ -17,7 +17,7 @@ Feature: Device Timeout
|
|
17
17
|
</body>
|
18
18
|
</html>
|
19
19
|
"""
|
20
|
-
|
20
|
+
|
21
21
|
Scenario: One device times out
|
22
22
|
Given a connected mobile device "ipad"
|
23
23
|
When the device disconnects
|
@@ -27,5 +27,5 @@ Feature: Device Timeout
|
|
27
27
|
TIMED OUT timed-out.html on ipad
|
28
28
|
"""
|
29
29
|
And the exit status should be 2
|
30
|
-
|
31
|
-
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: List Connected Devices
|
2
|
+
In order to easily diagnose device connection issues
|
3
|
+
As a JavaScript developer
|
4
|
+
I want to be able to know what devices are connected
|
5
|
+
|
6
|
+
Scenario: Two Connected Devices
|
7
|
+
Given a Wireless Universal Resource FiLe
|
8
|
+
And a connected mobile device "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"
|
9
|
+
And a connected mobile device "Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"
|
10
|
+
When I run "spassky <host> devices" with the server host
|
11
|
+
Then the output should contain:
|
12
|
+
"""
|
13
|
+
iPhone (id = apple_iphone_ver1_suba543, mobile_browser = Safari, device_os_version = 1.0)
|
14
|
+
iPad (id = apple_ipad_ver1_sub5312110, mobile_browser = Safari, device_os_version = 3.2)
|
15
|
+
"""
|
16
|
+
|
17
|
+
#:id => "apple_iphone_ver1_suba543",
|
18
|
+
#:mobile_browser => "Safari",
|
19
|
+
#:pointing_method => "touchscreen",
|
20
|
+
#:model_name => "iPhone",
|
21
|
+
#:device_os_version => "1.0",
|
@@ -32,6 +32,15 @@ Feature: Run HTML Tests
|
|
32
32
|
</html>
|
33
33
|
"""
|
34
34
|
|
35
|
+
Scenario: No connected devices
|
36
|
+
Given I have no connected devices
|
37
|
+
When I run "spassky <host> passing.html" with the server host
|
38
|
+
Then the output should contain:
|
39
|
+
"""
|
40
|
+
There are no connected devices
|
41
|
+
"""
|
42
|
+
And the exit status should be 1
|
43
|
+
|
35
44
|
Scenario: One passing test on one device
|
36
45
|
Given a connected mobile device "blackberry"
|
37
46
|
When I run "spassky <host> passing.html" with the server host
|
@@ -4,42 +4,72 @@ Feature: Run QUnit Tests
|
|
4
4
|
As a QUnit user
|
5
5
|
I want to test JavaScript code on different web browsers
|
6
6
|
|
7
|
-
|
8
|
-
Given a file named "
|
7
|
+
Scenario: One passing suite on one device
|
8
|
+
Given a file named "qunit_passing/qunit_test/passing.js" with:
|
9
9
|
"""
|
10
|
-
QUnit.done = function(
|
11
|
-
|
12
|
-
|
13
|
-
if (failed.length() > 0) {
|
10
|
+
QUnit.done = function(result) {
|
11
|
+
if (result.failed > 0) {
|
14
12
|
assert(false, "qunit failed");
|
15
13
|
} else {
|
16
14
|
assert(true, "qunit passed");
|
17
15
|
}
|
18
16
|
};
|
19
17
|
|
20
|
-
test("
|
21
|
-
ok(true, "it passed
|
18
|
+
test("it passes", function() {
|
19
|
+
ok(true, "it passed");
|
22
20
|
});
|
23
21
|
"""
|
24
|
-
And a file named "
|
25
|
-
And a file named "
|
22
|
+
And a file named "qunit_passing/qunit_test/qunit.js" with QUnit.js in it
|
23
|
+
And a file named "qunit_passing/qunit_test/suite.html" with:
|
26
24
|
"""
|
27
25
|
<html>
|
28
|
-
<head>
|
29
|
-
</head>
|
26
|
+
<head></head>
|
30
27
|
<body>
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
<h1>A QUnit Suite</h1>
|
29
|
+
<script type="text/javascript" src="qunit.js"></script>
|
30
|
+
<script type="text/javascript" src="passing.js"></script>
|
34
31
|
</body>
|
35
32
|
</html>
|
36
33
|
"""
|
37
|
-
|
38
|
-
|
39
|
-
Given a connected mobile device "blackberry"
|
40
|
-
When I run "spassky <host> qunit_suite/qunit_test" with the server host
|
34
|
+
And a connected mobile device "blackberry"
|
35
|
+
When I run "spassky <host> qunit_passing/qunit_test" with the server host
|
41
36
|
Then the output should contain:
|
42
37
|
"""
|
43
38
|
PASS qunit_test on blackberry
|
44
39
|
"""
|
45
40
|
And the exit status should be 0
|
41
|
+
|
42
|
+
Scenario: One failing suite on one device
|
43
|
+
Given a file named "qunit_failing/qunit_test/failing.js" with:
|
44
|
+
"""
|
45
|
+
QUnit.done = function(result) {
|
46
|
+
if (result.failed > 0) {
|
47
|
+
assert(false, "qunit failed");
|
48
|
+
} else {
|
49
|
+
assert(true, "qunit passed");
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
test("it fails", function() {
|
54
|
+
ok(false, "it failed");
|
55
|
+
});
|
56
|
+
"""
|
57
|
+
And a file named "qunit_failing/qunit_test/qunit.js" with QUnit.js in it
|
58
|
+
And a file named "qunit_failing/qunit_test/suite.html" with:
|
59
|
+
"""
|
60
|
+
<html>
|
61
|
+
<head></head>
|
62
|
+
<body>
|
63
|
+
<h1>A QUnit Suite</h1>
|
64
|
+
<script type="text/javascript" src="qunit.js"></script>
|
65
|
+
<script type="text/javascript" src="failing.js"></script>
|
66
|
+
</body>
|
67
|
+
</html>
|
68
|
+
"""
|
69
|
+
And a connected mobile device "blackberry"
|
70
|
+
When I run "spassky <host> qunit_failing/qunit_test" with the server host
|
71
|
+
Then the output should contain:
|
72
|
+
"""
|
73
|
+
FAIL qunit_test on blackberry
|
74
|
+
"""
|
75
|
+
And the exit status should be 1
|
data/features/server.feature
CHANGED
@@ -4,8 +4,5 @@ Feature: Server
|
|
4
4
|
I want to be able to type 'spassky-server' to launch a server
|
5
5
|
|
6
6
|
Scenario: Launch Server
|
7
|
-
Given I run spassky-server
|
8
|
-
Then
|
9
|
-
"""
|
10
|
-
Sinatra/1.2.6 has taken the stage on 9191
|
11
|
-
"""
|
7
|
+
Given I run spassky-server
|
8
|
+
Then it should not crash
|
@@ -9,12 +9,19 @@ Given /^a connected mobile device "([^"]*)"$/ do |user_agent|
|
|
9
9
|
@last_user_agent = user_agent
|
10
10
|
end
|
11
11
|
|
12
|
+
Given /^I have no connected devices$/ do
|
13
|
+
@uri = URI.parse(current_url)
|
14
|
+
end
|
15
|
+
|
12
16
|
Given /^a file named "([^"]*)" with ([^\s]*) in it$/ do |file_name, fixture_name|
|
13
17
|
fixture_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "fixtures", fixture_name))
|
14
18
|
fixture_content = File.read(fixture_path)
|
15
19
|
write_file(file_name, fixture_content)
|
16
20
|
end
|
17
21
|
|
22
|
+
Given /^a Wireless Universal Resource FiLe$/ do
|
23
|
+
end
|
24
|
+
|
18
25
|
When /^I run "([^"]*)" with the server host$/ do |command_line|
|
19
26
|
run_simple(unescape(command_line.gsub('<host>', "http://#{@uri.host}:#{@uri.port}")), false)
|
20
27
|
end
|
@@ -42,25 +49,12 @@ When /^the device disconnects$/ do
|
|
42
49
|
end
|
43
50
|
end
|
44
51
|
|
45
|
-
Given /^I run spassky\-server
|
46
|
-
@
|
47
|
-
|
48
|
-
process.io.stdout = @output
|
49
|
-
process.start
|
50
|
-
sleep 1
|
51
|
-
process.stop
|
52
|
+
Given /^I run spassky\-server$/ do
|
53
|
+
@spassky_server_process = ChildProcess.build('./bin/spassky-server')
|
54
|
+
@spassky_server_process.start
|
52
55
|
end
|
53
56
|
|
54
|
-
Then /^
|
55
|
-
|
56
|
-
|
57
|
-
while text == ""
|
58
|
-
@output.rewind
|
59
|
-
text = @output.read
|
60
|
-
break if sleep_count = 10
|
61
|
-
sleep 0.5
|
62
|
-
sleep_count += 1
|
63
|
-
end
|
64
|
-
|
65
|
-
text.should include string
|
57
|
+
Then /^it should not crash$/ do
|
58
|
+
@spassky_server_process.should_not be_crashed
|
59
|
+
@spassky_server_process.stop
|
66
60
|
end
|
data/lib/spassky/client/cli.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'spassky/client/device_list_retriever'
|
1
2
|
require 'spassky/client/test_runner'
|
2
3
|
require 'spassky/client/pusher'
|
3
4
|
require 'spassky/client/directory_reader'
|
@@ -5,8 +6,14 @@ require 'spassky/client/directory_reader'
|
|
5
6
|
module Spassky::Client
|
6
7
|
class Cli
|
7
8
|
def self.run(argv)
|
8
|
-
|
9
|
-
|
9
|
+
if argv[1] == "devices"
|
10
|
+
DeviceListRetriever.new(argv[0]).get_connected_devices.each do |device|
|
11
|
+
puts device
|
12
|
+
end
|
13
|
+
else
|
14
|
+
writer = argv.include?('--colour') ? ColouredWriter : DefaultWriter
|
15
|
+
TestRunner.new(Pusher.new(argv[0]), writer.new(STDOUT), DirectoryReader.new).run_tests(argv[1])
|
16
|
+
end
|
10
17
|
end
|
11
18
|
end
|
12
19
|
end
|
@@ -27,6 +27,9 @@ module Spassky::Client
|
|
27
27
|
def post_test(options)
|
28
28
|
location = nil
|
29
29
|
RestClient.post(test_runs_url, options) do |response, request, result|
|
30
|
+
if response.code == 500
|
31
|
+
raise response.to_str
|
32
|
+
end
|
30
33
|
location = response.headers[:location]
|
31
34
|
end
|
32
35
|
raise "Expected #{test_runs_url} to respond with 302" unless location
|
data/lib/spassky/server/app.rb
CHANGED
@@ -3,6 +3,7 @@ require 'spassky/server/random_string_generator'
|
|
3
3
|
require 'spassky/server/test_run'
|
4
4
|
require 'spassky/server/device_list'
|
5
5
|
require 'spassky/server/html_test'
|
6
|
+
require 'spassky/server/device_database'
|
6
7
|
|
7
8
|
module Spassky::Server
|
8
9
|
class App < Sinatra::Base
|
@@ -15,13 +16,23 @@ module Spassky::Server
|
|
15
16
|
@device_list.clear
|
16
17
|
end
|
17
18
|
|
19
|
+
get "/devices/list" do
|
20
|
+
@device_list.recently_connected_devices.to_json
|
21
|
+
end
|
22
|
+
|
18
23
|
get '/device/connect' do
|
19
24
|
redirect idle_url
|
20
25
|
end
|
21
26
|
|
27
|
+
def get_device_identifier user_agent
|
28
|
+
SingletonDeviceDatabase.instance.device_identifier(user_agent)
|
29
|
+
end
|
30
|
+
|
22
31
|
get '/device/idle/:random' do
|
23
|
-
|
24
|
-
|
32
|
+
device_identifier = get_device_identifier(request.user_agent)
|
33
|
+
|
34
|
+
test_run = TestRun.find_next_to_run_for_user_agent(device_identifier)
|
35
|
+
@device_list.update_last_connected(device_identifier)
|
25
36
|
if test_run
|
26
37
|
redirect_to_run_tests(test_run)
|
27
38
|
else
|
@@ -30,12 +41,17 @@ module Spassky::Server
|
|
30
41
|
end
|
31
42
|
|
32
43
|
post '/test_runs' do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
44
|
+
recently_connected_devices = @device_list.recently_connected_devices
|
45
|
+
if recently_connected_devices.size > 0
|
46
|
+
run = TestRun.create({
|
47
|
+
:name => params[:name],
|
48
|
+
:contents => JSON.parse(params[:contents]),
|
49
|
+
:devices => @device_list.recently_connected_devices
|
50
|
+
})
|
51
|
+
redirect "/test_runs/#{run.id}"
|
52
|
+
else
|
53
|
+
halt 500, "There are no connected devices"
|
54
|
+
end
|
39
55
|
end
|
40
56
|
|
41
57
|
get '/test_runs/:id' do
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "wurfl-lite"
|
2
|
+
require "singleton"
|
3
|
+
|
4
|
+
module Spassky::Server
|
5
|
+
LATEST = 'http://downloads.sourceforge.net/project/wurfl/WURFL/latest/wurfl-latest.xml.gz'
|
6
|
+
WURFL_FILE = "wurfl/wurfl-latest.xml.gz"
|
7
|
+
|
8
|
+
class DeviceNotFoundError < StandardError
|
9
|
+
end
|
10
|
+
|
11
|
+
class DeviceDatabase
|
12
|
+
def initialize
|
13
|
+
download_wurfl_file unless File.exist?(WURFL_FILE)
|
14
|
+
@wurfl = WURFL.new(WURFL_FILE)
|
15
|
+
end
|
16
|
+
|
17
|
+
def download_wurfl_file
|
18
|
+
Kernel.puts("Downloading WURFL database")
|
19
|
+
content = RestClient.get(LATEST)
|
20
|
+
File.open(WURFL_FILE, "w") do |file|
|
21
|
+
file.write(content)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def device_identifier user_agent
|
26
|
+
device = @wurfl[user_agent]
|
27
|
+
return user_agent if device.nil?
|
28
|
+
"#{device.model_name} (id = #{device.id}, mobile_browser = #{device.mobile_browser}, device_os_version = #{device.device_os_version})"
|
29
|
+
end
|
30
|
+
|
31
|
+
def device user_agent
|
32
|
+
@wurfl[user_agent]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class SingletonDeviceDatabase < DeviceDatabase
|
37
|
+
include Singleton
|
38
|
+
end
|
39
|
+
end
|
@@ -1,18 +1,21 @@
|
|
1
1
|
module Spassky::Server
|
2
2
|
class DeviceList
|
3
|
+
def initialize
|
4
|
+
@devices_and_time_last_connected = {}
|
5
|
+
end
|
6
|
+
|
3
7
|
def update_last_connected user_agent
|
4
|
-
@devices_and_time_last_connected
|
5
|
-
@devices_and_time_last_connected[user_agent] = Time.now
|
8
|
+
@devices_and_time_last_connected[user_agent] = Time.now
|
6
9
|
end
|
7
|
-
|
10
|
+
|
8
11
|
def recently_connected_devices
|
9
12
|
@devices_and_time_last_connected.keys.select do |user_agent|
|
10
13
|
Time.now.to_f - @devices_and_time_last_connected[user_agent].to_f < 3
|
11
14
|
end
|
12
15
|
end
|
13
|
-
|
16
|
+
|
14
17
|
def clear
|
15
18
|
@devices_and_time_last_connected = {}
|
16
19
|
end
|
17
20
|
end
|
18
|
-
end
|
21
|
+
end
|
data/lib/spassky/test_result.rb
CHANGED
@@ -6,7 +6,7 @@ module Spassky
|
|
6
6
|
def initialize device_statuses
|
7
7
|
@device_statuses = device_statuses
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def status
|
11
11
|
statuses = @device_statuses.map { |s| s.status }.uniq
|
12
12
|
return "in progress" if statuses.include?("in progress") || statuses.size == 0
|
@@ -14,15 +14,15 @@ module Spassky
|
|
14
14
|
return "timed out" if statuses.include?("timed out")
|
15
15
|
"pass"
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def count_fails
|
19
19
|
@device_statuses.count { |s| s.status == "fail" }
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def count_timeouts
|
23
23
|
@device_statuses.count { |s| s.status == "timed out" }
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def completed_since(older_test_result)
|
27
27
|
if older_test_result.nil?
|
28
28
|
device_statuses.select { |s| s.completed? }
|
@@ -30,7 +30,7 @@ module Spassky
|
|
30
30
|
find_newly_completed_device_results(older_test_result)
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def summary
|
35
35
|
result = "?"
|
36
36
|
count = @device_statuses.size
|
@@ -48,7 +48,7 @@ module Spassky
|
|
48
48
|
result << "s" if @device_statuses.size > 1
|
49
49
|
return result
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def to_json
|
53
53
|
{
|
54
54
|
:status => "pass",
|
@@ -61,7 +61,7 @@ module Spassky
|
|
61
61
|
end
|
62
62
|
}.to_json
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
def self.from_json json
|
66
66
|
parsed = JSON.parse(json)
|
67
67
|
test_result = TestResult.new(
|
@@ -70,9 +70,9 @@ module Spassky
|
|
70
70
|
end
|
71
71
|
)
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
private
|
75
|
-
|
75
|
+
|
76
76
|
def find_newly_completed_device_results(older_test_result)
|
77
77
|
completed = []
|
78
78
|
before_and_after(older_test_result) do |before, after|
|
@@ -82,29 +82,29 @@ module Spassky
|
|
82
82
|
end
|
83
83
|
completed
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
def before_and_after(older_test_result)
|
87
87
|
device_statuses.each_with_index do |s, i|
|
88
88
|
yield older_test_result.device_statuses[i], s
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
class DeviceTestStatus
|
94
94
|
attr_reader :user_agent, :status, :test_name
|
95
|
-
|
95
|
+
|
96
96
|
def initialize(user_agent, status, test_name)
|
97
97
|
@user_agent = user_agent
|
98
98
|
@status = status
|
99
99
|
@test_name = test_name
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
def in_progress?
|
103
103
|
@status == "in progress"
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
def completed?
|
107
107
|
@status != "in progress"
|
108
108
|
end
|
109
109
|
end
|
110
|
-
end
|
110
|
+
end
|
data/lib/spassky/version.rb
CHANGED
data/spassky.gemspec
CHANGED
@@ -22,10 +22,12 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_dependency 'json'
|
23
23
|
s.add_dependency 'sinatra'
|
24
24
|
s.add_dependency 'rainbow'
|
25
|
+
s.add_dependency 'wurfl-lite'
|
25
26
|
|
26
27
|
s.add_development_dependency 'rake'
|
27
28
|
s.add_development_dependency 'rspec'
|
28
29
|
s.add_development_dependency 'cucumber'
|
29
30
|
s.add_development_dependency 'capybara'
|
30
31
|
s.add_development_dependency 'aruba'
|
32
|
+
s.add_development_dependency 'fakefs'
|
31
33
|
end
|
@@ -44,5 +44,31 @@ module Spassky::Client
|
|
44
44
|
Cli::run(["server_name", "test_name", "--colour"])
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
context "with devices as the second argument" do
|
49
|
+
it "creates a new device list retriever with the passed in url" do
|
50
|
+
device_list_retriever = mock :device_list_retriever
|
51
|
+
device_list_retriever.stub!(:get_connected_devices).and_return([])
|
52
|
+
DeviceListRetriever.should_receive(:new).with("http://localhost:9000").and_return(device_list_retriever)
|
53
|
+
Cli::run(["http://localhost:9000", "devices"])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "gets a list of devices" do
|
57
|
+
device_list_retriever = mock :device_list_retriever
|
58
|
+
device_list_retriever.should_receive(:get_connected_devices).and_return([])
|
59
|
+
DeviceListRetriever.stub!(:new).and_return(device_list_retriever)
|
60
|
+
Cli::run(["http://localhost:9000", "devices"])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "outputs a list of devices" do
|
64
|
+
device_list_retriever = mock :device_list_retriever
|
65
|
+
device_list_retriever.stub!(:get_connected_devices).and_return(["iphone", "ipad", "nokia"])
|
66
|
+
DeviceListRetriever.stub!(:new).and_return(device_list_retriever)
|
67
|
+
Cli.should_receive(:puts).with("iphone")
|
68
|
+
Cli.should_receive(:puts).with("ipad")
|
69
|
+
Cli.should_receive(:puts).with("nokia")
|
70
|
+
Cli::run(["http://localhost:9000", "devices"])
|
71
|
+
end
|
72
|
+
end
|
47
73
|
end
|
48
74
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Spassky::Client
|
4
|
+
describe DeviceListRetriever do
|
5
|
+
it "retrieves the device list from the server" do
|
6
|
+
devices = ["iphone", "nokia"]
|
7
|
+
RestClient.should_receive(:get).with("http://localhost:9292/devices/list").and_return(devices.to_json)
|
8
|
+
DeviceListRetriever.new("http://localhost:9292").get_connected_devices
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns a list of devices" do
|
12
|
+
devices = ["iphone", "nokia"]
|
13
|
+
RestClient.stub(:get).and_return(devices.to_json)
|
14
|
+
returned_devices = DeviceListRetriever.new("http://localhost:9292").get_connected_devices
|
15
|
+
returned_devices.should == devices
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -43,6 +43,16 @@ module Spassky::Client
|
|
43
43
|
}.should raise_error("Expected http://foo/test_runs to respond with 302")
|
44
44
|
end
|
45
45
|
|
46
|
+
it "raises the error when the response is a 500" do
|
47
|
+
@response = mock("this is the error", :code => 500, :headers => { }, :to_str => "this is the error")
|
48
|
+
RestClient.stub!(:post).with("http://foo/test_runs", "test contents"
|
49
|
+
).and_yield(@response, nil, nil)
|
50
|
+
lambda {
|
51
|
+
@pusher.push("test contents") do |result|
|
52
|
+
end
|
53
|
+
}.should raise_error("this is the error")
|
54
|
+
end
|
55
|
+
|
46
56
|
it "polls the URL returned until the test passes" do
|
47
57
|
RestClient.should_receive(:get).with("http://poll/me").and_return(in_progress_status, in_progress_status, in_progress_status, passed_status)
|
48
58
|
@pusher.push("test contents") do |result|
|
@@ -14,36 +14,28 @@ module Spassky::Client
|
|
14
14
|
@test_runner = TestRunner.new(@test_pusher, @writer, @directory_reader)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
test_result = mock :
|
19
|
-
test_result.stub!(:status).and_return
|
20
|
-
test_result.stub!(:summary).and_return
|
17
|
+
def new_test_result status, summary
|
18
|
+
test_result = mock :"#{status.gsub(" ", "_")}_test_result"
|
19
|
+
test_result.stub!(:status).and_return status
|
20
|
+
test_result.stub!(:summary).and_return summary
|
21
21
|
test_result.stub!(:completed_since).and_return([])
|
22
22
|
test_result
|
23
23
|
end
|
24
24
|
|
25
|
+
def new_in_progress_test_result
|
26
|
+
new_test_result "in progress", "in progress summary"
|
27
|
+
end
|
28
|
+
|
25
29
|
def new_passed_test_result
|
26
|
-
|
27
|
-
test_result.stub!(:status).and_return "pass"
|
28
|
-
test_result.stub!(:summary).and_return "pass summary"
|
29
|
-
test_result.stub!(:completed_since).and_return([])
|
30
|
-
test_result
|
30
|
+
new_test_result "pass", "pass summary"
|
31
31
|
end
|
32
32
|
|
33
33
|
def new_failed_test_result
|
34
|
-
|
35
|
-
test_result.stub!(:status).and_return "fail"
|
36
|
-
test_result.stub!(:summary).and_return "fail summary"
|
37
|
-
test_result.stub!(:completed_since).and_return([])
|
38
|
-
test_result
|
34
|
+
new_test_result "fail", "fail summary"
|
39
35
|
end
|
40
36
|
|
41
37
|
def new_timeout_test_result
|
42
|
-
|
43
|
-
test_result.stub!(:status).and_return "timed out"
|
44
|
-
test_result.stub!(:summary).and_return "timed out summary"
|
45
|
-
test_result.stub!(:completed_since).and_return([])
|
46
|
-
test_result
|
38
|
+
new_test_result "timed out", "timed out summary"
|
47
39
|
end
|
48
40
|
|
49
41
|
it "reads a test" do
|