cucumber-pro 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aba26207747344dda383814db4114cb91cee6d20
4
- data.tar.gz: f809da648aed73a7eca530eb31391c02343b00e4
3
+ metadata.gz: 4c1ea22ade2589bfaba0ea2b8b452133995630c9
4
+ data.tar.gz: 31a0837902dfacd353adf063083d2a5c6d9d1681
5
5
  SHA512:
6
- metadata.gz: f246995c5281209a5cd2340ab3a3f3fec7cbfbc1f79cdd9d3f80769cf186e782d3677c9b360401a7d92f8a1648dab7ae1a96c6e4bb691895fadf5971b7972523
7
- data.tar.gz: 349ae812ab5017bb077a5f378370498323b7a68119bb7349025a5a4009770277f131039c8b93a645dd5e56e75521221138e467e0c4d6b2e542454d54eab05d7e
6
+ metadata.gz: 3ba8796ca612b363c444fb9308687d6dfdcc66e0620eb2d197e9461dacec93bb019cb2a5d13d9621d62753ac70113bc09b66183a02d528d4bc71e22c02b2a401
7
+ data.tar.gz: 4f3a0bf99cdd27ac75142da244443a1f5378b03e36cf66be3a2fed14db919d82d4fa5110635600b2a85d749bd0c79a74f8db810fd3503cd8b863dfcf7d197149
data/Rakefile CHANGED
@@ -25,7 +25,7 @@ desc 'Run repeated tests to check for async bugs'
25
25
  task :soak, :repetitions do |task, args|
26
26
  reps = args[:repetitions] || 10
27
27
  results = reps.to_i.times.map do
28
- `cucumber`
28
+ `rspec > tmp/test.log`
29
29
  print $? == 0 ? '.' : 'x'
30
30
  $?
31
31
  end
data/TODO.md CHANGED
@@ -1,7 +1,7 @@
1
1
  - Unit tests for Messaging
2
2
  - Handle cases where some messages sent are not ack'd with a timeout
3
3
  - Handle cases where some messages sent come back with an error
4
- - e.g. upgrade your client error
4
+ - e.g. upgrade your client error
5
5
  - Allow configuration of git remote
6
6
  - Build against Cucumber 2.0 and 1.3.x
7
7
  - SVN support
data/lib/cucumber/pro.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'logger'
2
2
  require 'cucumber/pro/formatter'
3
3
  require 'cucumber/pro/web_socket/session'
4
+ require 'cucumber/pro/errors'
4
5
 
5
6
  module Cucumber
6
7
  module Pro
@@ -8,7 +9,7 @@ module Cucumber
8
9
  class << self
9
10
  def new(runtime, output, options)
10
11
  create_logger(output)
11
- session = WebSocket::Session.new(url, logger)
12
+ session = WebSocket::Session.new(url, logger, timeout: config.timeout)
12
13
  Formatter.new(session)
13
14
  end
14
15
 
@@ -41,31 +42,18 @@ module Cucumber
41
42
  end
42
43
 
43
44
  class Config
44
- attr_accessor :url, :logger, :token
45
+ attr_accessor :url, :logger, :token, :timeout
45
46
  end
46
47
 
47
48
  # Default config
48
49
  configure do |config|
49
- config.url = ENV['CUCUMBER_PRO_URL'] || 'wss://results.cucumber.pro/ws'
50
- config.token = ENV['CUCUMBER_PRO_TOKEN']
51
- ENV['cucumber_pro_log_path'].tap do |path|
52
- config.logger = Logger.new(path) if path
50
+ config.url = ENV['CUCUMBER_PRO_URL'] || 'wss://results.cucumber.pro/ws'
51
+ config.token = ENV['CUCUMBER_PRO_TOKEN']
52
+ config.timeout = 5
53
+ if file = ENV['CUCUMBER_PRO_LOG_FILE']
54
+ config.logger = Logger.new(file)
53
55
  end
54
56
  end
55
57
 
56
- module Error
57
- AccessDenied = Class.new(StandardError) {
58
- def initialize
59
- super "Access denied."
60
- end
61
- }
62
-
63
- MissingToken = Class.new(StandardError) {
64
- def initialize
65
- super "Missing access token. Please visit https://app.cucumber.pro/api-token for instructions."
66
- end
67
- }
68
- end
69
-
70
58
  end
71
59
  end
@@ -0,0 +1,25 @@
1
+ module Cucumber
2
+ module Pro
3
+
4
+ module Error
5
+ AccessDenied = Class.new(StandardError) {
6
+ def initialize
7
+ super "Access denied."
8
+ end
9
+ }
10
+
11
+ MissingToken = Class.new(StandardError) {
12
+ def initialize
13
+ super "Missing access token. Please visit https://app.cucumber.pro/my/profile for instructions."
14
+ end
15
+ }
16
+
17
+ Timeout = Class.new(StandardError) {
18
+ def initialize
19
+ super "Timed out waiting for a reply from the Cucumber Pro server."
20
+ end
21
+ }
22
+ end
23
+
24
+ end
25
+ end
@@ -1 +1 @@
1
- 0.0.11
1
+ 0.0.12
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
  require 'faye/websocket'
3
3
  require 'eventmachine'
4
+ require 'cucumber/pro/errors'
4
5
 
5
6
  module Cucumber
6
7
  module Pro
@@ -8,7 +9,7 @@ module Cucumber
8
9
 
9
10
  class Session
10
11
 
11
- def initialize(url, logger)
12
+ def initialize(url, logger, options)
12
13
  @url, @logger = url, logger
13
14
  create_socket = -> worker {
14
15
  ws = Faye::WebSocket::Client.new(@url, nil, ping: 15)
@@ -19,7 +20,7 @@ module Cucumber
19
20
  ws
20
21
  }
21
22
  @queue = Queue.new
22
- @socket = Worker.new(create_socket, logger, self)
23
+ @socket = Worker.new(create_socket, logger, self, options)
23
24
  end
24
25
 
25
26
  def send(message)
@@ -49,8 +50,9 @@ module Cucumber
49
50
 
50
51
  class Worker
51
52
 
52
- def initialize(create_socket, logger, error_handler)
53
+ def initialize(create_socket, logger, error_handler, options = {})
53
54
  @create_socket, @logger, @error_handler = create_socket, logger, error_handler
55
+ @timeout = options.fetch(:timeout) { raise ArgumentError("Please specify timeout") }
54
56
  @q = Queue.new
55
57
  @em = Thread.new { start_client }
56
58
  @ack_count = 0
@@ -59,8 +61,9 @@ module Cucumber
59
61
  def close
60
62
  @q << -> {
61
63
  if @ack_count == 0
62
- @ws.close
64
+ close_websocket
63
65
  else
66
+ ensure_close_timer_started
64
67
  EM.next_tick { close }
65
68
  end
66
69
  }
@@ -81,7 +84,25 @@ module Cucumber
81
84
 
82
85
  private
83
86
 
84
- attr_reader :logger, :error_handler, :next_task
87
+ attr_reader :logger, :error_handler, :next_task, :timeout
88
+
89
+ def ensure_close_timer_started
90
+ return if @close_timer
91
+ logger.debug [:ws, :set_close_timeout, timeout]
92
+ @close_timer = EM.add_timer(timeout) { handle_close_timeout }
93
+ end
94
+
95
+ def handle_close_timeout
96
+ logger.debug [:ws, :handle_close_timeout]
97
+ return unless @ws
98
+ error_handler.error Error::Timeout.new
99
+ close_websocket
100
+ end
101
+
102
+ def close_websocket
103
+ logger.debug [:ws, :close_socket]
104
+ @ws.close
105
+ end
85
106
 
86
107
  def start_client
87
108
  EM.run do
@@ -1,79 +1,103 @@
1
1
  require 'cucumber/pro/web_socket/session'
2
2
  require 'logger'
3
3
 
4
- module Cucumber::Pro::WebSocket
4
+ module Cucumber::Pro
5
+ module WebSocket
6
+
7
+ describe Worker do
8
+ let(:good_data) { double('good data') }
9
+ let(:error_handler) { double('error handler') }
10
+ let(:logger) { Logger.new(ENV['CUCUMBER_PRO_LOG_PATH'] || STDOUT) }
11
+ let!(:socket) { SpySocket.new }
12
+ let(:worker) { Worker.new(self.method(:create_fake_socket), logger, error_handler, timeout: 0.5) }
13
+
14
+ before { logger.level = Logger::DEBUG }
15
+
16
+ it "closes once all messages have been acknowledged (but not before)" do
17
+ worker.send(good_data)
18
+ worker.close
19
+ eventually do
20
+ socket.data.last.should == good_data
21
+ end
22
+ eventually do
23
+ expect( worker ).to_not be_closed
24
+ end
25
+ socket.send_ack
26
+ eventually do
27
+ expect( worker ).to be_closed
28
+ end
29
+ end
5
30
 
6
- describe Worker do
7
- let(:good_data) { double('good data') }
8
- let(:logger) { Logger.new(STDOUT) }
9
- let(:socket) { FakeSocket.new }
10
- let(:worker) { Worker.new(self.method(:create_fake_socket), logger, logger) }
31
+ it "throws an error and closes if all messages are not acknowledged within a timeout period" do
32
+ expect( error_handler ).to receive(:error).with(Error::Timeout.new)
33
+ worker.send(good_data)
34
+ worker.close
35
+ eventually do
36
+ expect( worker ).to be_closed
37
+ end
38
+ end
11
39
 
12
- before { logger.level = Logger::DEBUG }
40
+ it "throws an error if the server responds with an error"
13
41
 
14
- it "closes once all messages have been acknowledged (but not before)" do
15
- worker.send(good_data)
16
- worker.close
17
- eventually do
18
- socket.data.last.should == good_data
19
- end
20
- eventually do
21
- expect( worker ).to_not be_closed
22
- end
23
- socket.send_ack
24
- eventually do
25
- expect( worker ).to be_closed
42
+ def create_fake_socket(worker)
43
+ socket.worker = worker
44
+ EM.next_tick {
45
+ worker.method(:on_open).call(double('ws event'))
46
+ }
47
+ socket
26
48
  end
27
- end
28
49
 
29
- def create_fake_socket(worker)
30
- socket.worker = worker
31
- EM.next_tick {
32
- worker.method(:on_open).call(double('ws event'))
33
- }
34
- socket
35
- end
36
50
 
51
+ class SpySocket
52
+ include RSpec::Mocks::ExampleMethods
37
53
 
38
- class FakeSocket
39
- include RSpec::Mocks::ExampleMethods
54
+ attr_accessor :worker
55
+ attr_reader :data
40
56
 
41
- attr_accessor :worker
42
- attr_reader :data
57
+ def initialize
58
+ @q = Queue.new
59
+ end
43
60
 
44
- def initialize
45
- @data = []
46
- end
61
+ def close
62
+ worker.method(:on_close).call(ws_event(1000))
63
+ end
47
64
 
48
- def close
49
- worker.method(:on_close).call(ws_event(1000))
50
- end
65
+ def send(data)
66
+ @q << data
67
+ self
68
+ end
51
69
 
52
- def send(data)
53
- @data << data
54
- end
70
+ def send_ack
71
+ event = ws_event(1000, { 'type' => 'metadata_saved' })
72
+ worker.method(:on_message).call(event)
73
+ end
55
74
 
56
- def send_ack
57
- event = ws_event(1000, { 'type' => 'metadata_saved' })
58
- worker.method(:on_message).call(event)
59
- end
75
+ def data
76
+ @data ||= []
77
+ while !@q.empty?
78
+ @data << @q.pop
79
+ end
80
+ @data
81
+ end
82
+
83
+ private
60
84
 
61
- private
85
+ def ws_event(code, data = {})
86
+ double('ws event', code: 1000, data: data)
87
+ end
62
88
 
63
- def ws_event(code, data = {})
64
- double('ws event', code: 1000, data: data)
65
89
  end
66
- end
67
90
 
68
- require 'anticipate'
69
- include Anticipate
70
- def eventually(&block)
71
- result = nil
72
- sleeping(0.1).seconds.between_tries.failing_after(30).tries do
73
- result = block.call
91
+ require 'anticipate'
92
+ include Anticipate
93
+ def eventually(&block)
94
+ result = nil
95
+ sleeping(0.1).seconds.between_tries.failing_after(50).tries do
96
+ result = block.call
97
+ end
98
+ result
74
99
  end
75
- result
76
100
  end
77
- end
78
101
 
102
+ end
79
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber-pro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wynne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-22 00:00:00.000000000 Z
11
+ date: 2014-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faye-websocket
@@ -158,6 +158,7 @@ files:
158
158
  - features/support/fake_results_service.rb
159
159
  - features/support/world.rb
160
160
  - lib/cucumber/pro.rb
161
+ - lib/cucumber/pro/errors.rb
161
162
  - lib/cucumber/pro/formatter.rb
162
163
  - lib/cucumber/pro/info.rb
163
164
  - lib/cucumber/pro/scm/working_copy.rb
@@ -190,7 +191,7 @@ rubyforge_project:
190
191
  rubygems_version: 2.0.14
191
192
  signing_key:
192
193
  specification_version: 4
193
- summary: cucumber-pro-0.0.11
194
+ summary: cucumber-pro-0.0.12
194
195
  test_files:
195
196
  - features/publish_results.feature
196
197
  - features/security.feature