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
         
     |