spassky 0.1.0 → 0.1.1
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/.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
|