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 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
+ [![Hashrocket logo](https://hashrocket.com/hashrocket_logo.svg)](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: []