flatware-rspec 0.4.0
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +176 -0
- data/lib/flatware-rspec.rb +1 -0
- data/lib/flatware/rspec/checkpoint.rb +29 -0
- data/lib/flatware/rspec/cli.rb +16 -0
- data/lib/flatware/rspec/example_notification.rb +21 -0
- data/lib/flatware/rspec/examples_notification.rb +24 -0
- data/lib/flatware/rspec/formatter.rb +50 -0
- data/lib/flatware/rspec/formatters/console.rb +33 -0
- data/lib/flatware/rspec/summary.rb +40 -0
- metadata +83 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96ee1612dd1b6bedadb6d14a2314dd62f8e06121
|
4
|
+
data.tar.gz: 57140b234970845f9ef60dcfcfe5a500ee03277a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff248de8080055159ea82ad929ef1f0481153fd4cc3fa4b4dfcc55e7a584009024f6255d226c652ea8dd85a326005d98771d1f0bead85913999c1cdf12ef07c1
|
7
|
+
data.tar.gz: 9f44cdadf9e6fa43a3d56b0e2f601b5434460553d9c4962f89e4c36647f7ad7da3eb2c8806467c4058b2eeacbfe0df62ccb78edc2b08c7491ff756190310fa10
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Brian Dunn
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# Flatware [![Build Status][travis-badge]][travis] [![Code Climate][code-climate-badge]][code-climate]
|
2
|
+
|
3
|
+
[travis-badge]: https://travis-ci.org/briandunn/flatware.svg?branch=master
|
4
|
+
[travis]: http://travis-ci.org/briandunn/flatware
|
5
|
+
[code-climate-badge]: https://codeclimate.com/github/briandunn/flatware.png
|
6
|
+
[code-climate]: https://codeclimate.com/github/briandunn/flatware
|
7
|
+
|
8
|
+
Flatware parallelizes your test suite to significantly reduce test time.
|
9
|
+
|
10
|
+
## Requirements
|
11
|
+
|
12
|
+
* ZeroMQ > 4.0
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
### ZeroMQ
|
17
|
+
|
18
|
+
#### Linux Ubuntu
|
19
|
+
|
20
|
+
```sh
|
21
|
+
sudo apt-get install -qq libzmq3-dev
|
22
|
+
```
|
23
|
+
|
24
|
+
(Never you mind the 3. This package contains ZMQ version 4.)
|
25
|
+
|
26
|
+
#### Mac OSX
|
27
|
+
|
28
|
+
Ruby FFI isn't getting along with the latest ZMQ formula. A tweaked verson is available in the Hashrocket tap.
|
29
|
+
|
30
|
+
```sh
|
31
|
+
brew tap hashrocket/formulas
|
32
|
+
brew install hashrocket/formulas/zeromq
|
33
|
+
brew install zeromq
|
34
|
+
```
|
35
|
+
|
36
|
+
### Flatware
|
37
|
+
|
38
|
+
Add the runners you need to your Gemfile:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
gem 'flatware-rspec' # one
|
42
|
+
gem 'flatware-cucumber' # or both
|
43
|
+
```
|
44
|
+
|
45
|
+
then run
|
46
|
+
|
47
|
+
```sh
|
48
|
+
bundle install
|
49
|
+
```
|
50
|
+
|
51
|
+
## Usage
|
52
|
+
|
53
|
+
### Cucumber
|
54
|
+
|
55
|
+
To run your entire suite with the default cucumber options, add the `flatware-cucumber` gem and just:
|
56
|
+
|
57
|
+
```sh
|
58
|
+
$ flatware cucumber
|
59
|
+
```
|
60
|
+
|
61
|
+
### RSpec
|
62
|
+
|
63
|
+
To run your entire suite with the default rspec options add the `flatware-rspec` gem and just:
|
64
|
+
|
65
|
+
```sh
|
66
|
+
$ flatware rspec
|
67
|
+
```
|
68
|
+
|
69
|
+
### Options
|
70
|
+
|
71
|
+
If you'd like to limit the number of forked workers, you can pass the 'w' flag:
|
72
|
+
|
73
|
+
```sh
|
74
|
+
$ flatware -w 3
|
75
|
+
```
|
76
|
+
|
77
|
+
You can also pass most cucumber/rspec options to Flatware. For example, to run only
|
78
|
+
features that are not tagged 'javascript', you can:
|
79
|
+
|
80
|
+
```sh
|
81
|
+
$ flatware cucumber -t ~@javascript
|
82
|
+
```
|
83
|
+
|
84
|
+
Additionally, for either cucumber or rspec you can specify a directory:
|
85
|
+
|
86
|
+
```sh
|
87
|
+
$ flatware rspec spec/features
|
88
|
+
```
|
89
|
+
|
90
|
+
## Typical Usage in a Rails App
|
91
|
+
|
92
|
+
Add the following to your `config/database.yml`:
|
93
|
+
|
94
|
+
```yml
|
95
|
+
test:
|
96
|
+
database: foo_test
|
97
|
+
```
|
98
|
+
|
99
|
+
becomes:
|
100
|
+
|
101
|
+
```yml
|
102
|
+
test:
|
103
|
+
database: foo_test<%=ENV['TEST_ENV_NUMBER']%>
|
104
|
+
```
|
105
|
+
|
106
|
+
Run the following:
|
107
|
+
|
108
|
+
```sh
|
109
|
+
$ rake db:setup # if not already done
|
110
|
+
$ flatware fan rake db:test:prepare
|
111
|
+
```
|
112
|
+
|
113
|
+
Now you are ready to rock:
|
114
|
+
|
115
|
+
```sh
|
116
|
+
$ flatware rspec && flatware cucumber
|
117
|
+
```
|
118
|
+
|
119
|
+
## Planned Features
|
120
|
+
|
121
|
+
* Use heuristics to run your slowest tests first
|
122
|
+
|
123
|
+
## Design Goals
|
124
|
+
|
125
|
+
### Maintainable
|
126
|
+
|
127
|
+
* Fully test at an integration level. Don't be afraid to change the code. If you
|
128
|
+
break it you'll know.
|
129
|
+
* Couple as loosely as possible, and only to the most stable/public bits of
|
130
|
+
Cucumber and RSpec.
|
131
|
+
|
132
|
+
### Minimal
|
133
|
+
|
134
|
+
* Projects define their own preparation scripts
|
135
|
+
* Only distribute to local cores (for now)
|
136
|
+
|
137
|
+
### Robust
|
138
|
+
|
139
|
+
* Depend on a dedicated messaging library
|
140
|
+
* Be accountable for completed work; provide progress report regardless of
|
141
|
+
completing the suite.
|
142
|
+
|
143
|
+
## Tinkering
|
144
|
+
|
145
|
+
Flatware integration tests use [aruba][a]. In order to get a demo cucumber project you
|
146
|
+
can add the `@no-clobber` tag to `features/flatware.feature` and run the test
|
147
|
+
with `cucumber features/flatware.feature`. Now you should have a `./tmp/aruba`
|
148
|
+
directory. CD there and `flatware` will be in your path so you can tinker away.
|
149
|
+
|
150
|
+
## How it works
|
151
|
+
|
152
|
+
Flatware relies on a message passing system to enable concurrency.
|
153
|
+
The main process declares a worker for each cpu in the computer. Each
|
154
|
+
worker forks from the main process and is then assigned a portion of the
|
155
|
+
test suite. As the worker runs the test suite it sends progress
|
156
|
+
messages to the main process. These messages are collected and when
|
157
|
+
the last worker is finished the main process provides a report on the
|
158
|
+
collected progress messages.
|
159
|
+
|
160
|
+
## Resources
|
161
|
+
|
162
|
+
To learn more about the messaging system that Flatware uses, take a look at the
|
163
|
+
[excellent ZeroMQ guide][z].
|
164
|
+
|
165
|
+
[z]: http://zguide.zeromq.org/page:all
|
166
|
+
[a]: https://github.com/cucumber/aruba
|
167
|
+
|
168
|
+
## Contributing to Flatware
|
169
|
+
|
170
|
+
Do whatever you want. I'd love to help make sure Flatware meets your needs.
|
171
|
+
|
172
|
+
## About
|
173
|
+
|
174
|
+
[](https://hashrocket.com)
|
175
|
+
|
176
|
+
Flatware is supported by the team at [Hashrocket](https://hashrocket.com), a multidisciplinary design & development consultancy. If you'd like to [work with us](https://hashrocket.com/contact-us/hire-us) or [join our team](https://hashrocket.com/contact-us/jobs), don't hesitate to get in touch.
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'flatware/rspec'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'flatware/rspec/examples_notification'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
module RSpec
|
5
|
+
class Checkpoint
|
6
|
+
attr_reader :summary, :failures_notification
|
7
|
+
|
8
|
+
def initialize(summary, failures_notification)
|
9
|
+
@summary, @failures_notification = summary, ExamplesNotification.new(failures_notification.failure_notifications)
|
10
|
+
end
|
11
|
+
|
12
|
+
def +(other)
|
13
|
+
self.class.new summary + other.summary, failures_notification + other.failures_notification
|
14
|
+
end
|
15
|
+
|
16
|
+
def failures?
|
17
|
+
summary.failure_count > 0
|
18
|
+
end
|
19
|
+
|
20
|
+
def failure_notifications
|
21
|
+
failures_notification.failure_notifications
|
22
|
+
end
|
23
|
+
|
24
|
+
def fully_formatted_failed_examples(*args)
|
25
|
+
failures_notification.fully_formatted_failed_examples(*args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'flatware/cli'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
class CLI
|
5
|
+
worker_option
|
6
|
+
method_option 'dispatch-endpoint', type: :string, default: 'ipc://dispatch'
|
7
|
+
method_option 'sink-endpoint', type: :string, default: 'ipc://task'
|
8
|
+
desc "rspec [FLATWARE_OPTS]", "parallelizes rspec"
|
9
|
+
def rspec(*rspec_args)
|
10
|
+
jobs = RSpec.extract_jobs_from_args rspec_args, workers: workers
|
11
|
+
Flatware.verbose = options[:log]
|
12
|
+
Worker.spawn count: workers, runner: RSpec, dispatch: options['dispatch-endpoint'], sink: options['sink-endpoint']
|
13
|
+
start_sink jobs: jobs, workers: workers, formatter: Flatware::RSpec::Formatters::Console.new($stdout, $stderr)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rspec/core/formatters/console_codes'
|
2
|
+
|
3
|
+
module Flatware
|
4
|
+
module RSpec
|
5
|
+
class ExampleNotification
|
6
|
+
attr_reader :formatted
|
7
|
+
def initialize(notification)
|
8
|
+
@formatted = notification.fully_formatted '!', default_colorizer
|
9
|
+
end
|
10
|
+
|
11
|
+
def fully_formatted(i, _=nil)
|
12
|
+
formatted.sub '!', i.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def default_colorizer
|
17
|
+
::RSpec::Core::Formatters::ConsoleCodes
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'flatware/rspec/example_notification'
|
2
|
+
module Flatware
|
3
|
+
module RSpec
|
4
|
+
class ExamplesNotification
|
5
|
+
attr_reader :failure_notifications
|
6
|
+
|
7
|
+
def initialize(failure_notifications)
|
8
|
+
@failure_notifications = failure_notifications.map(&ExampleNotification.method(:new))
|
9
|
+
end
|
10
|
+
|
11
|
+
def +(other)
|
12
|
+
self.class.new failure_notifications + other.failure_notifications
|
13
|
+
end
|
14
|
+
|
15
|
+
def fully_formatted_failed_examples(*)
|
16
|
+
formatted = "\n\nFailures:\n"
|
17
|
+
failure_notifications.each_with_index do |failure, index|
|
18
|
+
formatted << failure.fully_formatted(index.next)
|
19
|
+
end
|
20
|
+
formatted
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'flatware/rspec/checkpoint'
|
2
|
+
require 'flatware/rspec/summary'
|
3
|
+
require 'rspec/core/formatters/console_codes'
|
4
|
+
|
5
|
+
module Flatware
|
6
|
+
module RSpec
|
7
|
+
ProgressMessage = Struct.new(:progress)
|
8
|
+
|
9
|
+
class Formatter
|
10
|
+
attr_reader :summary, :output
|
11
|
+
|
12
|
+
def initialize(stdout)
|
13
|
+
@output = stdout
|
14
|
+
end
|
15
|
+
|
16
|
+
def example_passed(example)
|
17
|
+
send_progress :passed
|
18
|
+
end
|
19
|
+
|
20
|
+
def example_failed(example)
|
21
|
+
send_progress :failed
|
22
|
+
end
|
23
|
+
|
24
|
+
def example_pending(example)
|
25
|
+
send_progress :pending
|
26
|
+
end
|
27
|
+
|
28
|
+
def dump_summary(summary)
|
29
|
+
@summary = Summary.from_notification(summary)
|
30
|
+
end
|
31
|
+
|
32
|
+
def dump_failures(failure_notification)
|
33
|
+
@failure_notification = failure_notification
|
34
|
+
end
|
35
|
+
|
36
|
+
def close(*)
|
37
|
+
Sink::client.checkpoint Checkpoint.new(summary, @failure_notification)
|
38
|
+
@failure_notification = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def send_progress(status)
|
44
|
+
Sink::client.progress ProgressMessage.new status
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
::RSpec::Core::Formatters.register Formatter, :example_passed, :example_failed, :example_pending, :dump_summary, :dump_failures, :close
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Flatware::RSpec::Formatters
|
2
|
+
class Console
|
3
|
+
attr_reader :formatter
|
4
|
+
|
5
|
+
def initialize(out, err)
|
6
|
+
::RSpec::configuration.tty = true
|
7
|
+
::RSpec::configuration.color = true
|
8
|
+
@formatter = ::RSpec::Core::Formatters::ProgressFormatter.new(out)
|
9
|
+
end
|
10
|
+
|
11
|
+
def progress(result)
|
12
|
+
formatter.send(message_for(result),nil)
|
13
|
+
end
|
14
|
+
|
15
|
+
def summarize(checkpoints)
|
16
|
+
result = checkpoints.reduce :+
|
17
|
+
if result
|
18
|
+
formatter.dump_failures result
|
19
|
+
formatter.dump_summary result.summary
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def message_for(result)
|
26
|
+
{
|
27
|
+
passed: :example_passed,
|
28
|
+
failed: :example_failed,
|
29
|
+
pending: :example_pending
|
30
|
+
}.fetch result.progress
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rspec/core/notifications'
|
2
|
+
module Flatware
|
3
|
+
module RSpec
|
4
|
+
Summary = Struct.new(:duration, :examples, :failed_examples, :pending_examples, :load_time)
|
5
|
+
|
6
|
+
class Example
|
7
|
+
attr_reader :location_rerun_argument, :full_description
|
8
|
+
def initialize(rspec_example)
|
9
|
+
@full_description = rspec_example.full_description
|
10
|
+
@location_rerun_argument = rspec_example.location_rerun_argument
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Summary
|
15
|
+
def +(other)
|
16
|
+
self.class.new duration + other.duration,
|
17
|
+
examples + other.examples,
|
18
|
+
failed_examples + other.failed_examples,
|
19
|
+
pending_examples + other.pending_examples,
|
20
|
+
load_time + other.load_time
|
21
|
+
end
|
22
|
+
|
23
|
+
def fully_formatted
|
24
|
+
::RSpec::Core::Notifications::SummaryNotification.new(duration, examples, failed_examples, pending_examples, load_time).fully_formatted
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure_count
|
28
|
+
failed_examples.size
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.from_notification(summary)
|
32
|
+
serialized_examples = [summary.examples, summary.failed_examples, summary.pending_examples].map do |examples|
|
33
|
+
examples.map(&Example.method(:new))
|
34
|
+
end
|
35
|
+
|
36
|
+
new summary.duration, *serialized_examples, summary.load_time
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flatware-rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Dunn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: flatware
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.4.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.4.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.4'
|
41
|
+
description: A distributed rspec runner
|
42
|
+
email: brian@hashrocket.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files:
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.md
|
48
|
+
files:
|
49
|
+
- LICENSE.txt
|
50
|
+
- README.md
|
51
|
+
- lib/flatware-rspec.rb
|
52
|
+
- lib/flatware/rspec/checkpoint.rb
|
53
|
+
- lib/flatware/rspec/cli.rb
|
54
|
+
- lib/flatware/rspec/example_notification.rb
|
55
|
+
- lib/flatware/rspec/examples_notification.rb
|
56
|
+
- lib/flatware/rspec/formatter.rb
|
57
|
+
- lib/flatware/rspec/formatters/console.rb
|
58
|
+
- lib/flatware/rspec/summary.rb
|
59
|
+
homepage: http://github.com/briandunn/flatware
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - "~>"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '2.1'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.6.8
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: A distributed rspec runner
|
83
|
+
test_files: []
|