specify 0.10.2 → 1.0.0

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
- SHA1:
3
- metadata.gz: 87785f51fa0d7d5c529b7856afdeec58b5fb33f2
4
- data.tar.gz: 76ec7120adbd2fb1f2e0976756f9f9a7990bb825
2
+ SHA256:
3
+ metadata.gz: d8d284ca6600d067bcd67451cb6af8abef30831d25d1b2d5a1e9b4fe4619f127
4
+ data.tar.gz: 20b23de09742a461528a04df263b68ff11ddd0efcda66231242caa4f2efe71e6
5
5
  SHA512:
6
- metadata.gz: 8d0045e2c22929aff89fb8e34a707a4bc5dc2c62e5a9cee5f5eed38d04e50f382f86e22e3e90c8ec0241047f81e053d215d9a344668bba0535fe0d99bdf04ce9
7
- data.tar.gz: 0904c0da9c04efc6cf88d3b056a1f58fdf8859f20cf1c41ed3b2d6f1151c5f005c27598076bc543e838c4222b19d0906024babf552f0a916f2a254f67ac808f5
6
+ metadata.gz: e74dad48ac6b8216a2d47f038fa65a9769c46e001e921be9f02982f0e1bd5f9903b4b20dd073cb39f3c30698d87b792eed7609b5ddff778af2ee8308d18d9917
7
+ data.tar.gz: c5ff56f667afa59729bfc8a4c802794d0266233c4c72ec2fff8c8d6e93a4ade47beb3c37d59227479375e1130f534464dc42c2a3e66a5c95cda0c1ed51a73315
data/.gitignore CHANGED
@@ -1,29 +1,49 @@
1
- *.gem
2
- *.rbc
3
- .idea
4
- .bundle
5
- .config
6
- .yardoc
7
- Gemfile.lock
8
- InstalledFiles
9
- _yardoc
10
- coverage
11
- doc/
12
- lib/bundler/man
13
- pkg
14
- rdoc
15
- spec/reports
16
- spec/examples.txt
17
- test/tmp
18
- test/version_tmp
19
- tmp
20
- *.bundle
21
- *.so
22
- *.o
23
- *.a
24
- ._*
25
- mkmf.log
1
+ # Ruby Generated
2
+
3
+ /Gemfile.lock
4
+ /.bundle/
5
+ /.yardoc
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /spec/coverage/
12
+ /tmp/
13
+
14
+ # Generated Reports
15
+ reports/
16
+
17
+ # Rspec Failure Tracking
18
+
19
+ .rspec_status
20
+
21
+ # IDE Files
22
+
23
+ .idea/
24
+ *.iml
25
+ *.iws
26
+ *.ipr
27
+ .vscode/
28
+ .settings/
29
+ .metadata
30
+ .classpath
31
+ .loadpath
32
+ .buildpath
33
+ .project
34
+
35
+ # OS Files
36
+
26
37
  .DS_Store
27
38
  .DS_Store?
39
+ ._*
40
+ .Spotlight-V100
28
41
  .Trashes
29
- .thumbs.db
42
+ ehthumbs.db
43
+ Thumbs.db
44
+ $RECYCLE.BIN/
45
+ Desktop.ini
46
+ *.tmp
47
+ *.bak
48
+ *.swp
49
+ *~.nib
data/.hound.yml CHANGED
@@ -1,95 +1,78 @@
1
1
  AllCops:
2
2
  Exclude:
3
3
  - specify.gemspec
4
- - test/*.rb
5
4
  - spec/**/*
6
5
 
7
- # missing top-level module documentation comment
6
+ # Removing need for frozen string literal comment.
7
+ Style/FrozenStringLiteralComment:
8
+ Enabled: false
9
+
10
+ # Removing the preference for string single quotes.
11
+ Style/StringLiterals:
12
+ Enabled: false
13
+
14
+ # Missing top-level module documentation comment.
8
15
  Style/Documentation:
9
16
  Enabled: false
10
17
 
11
- # prefer reduce over inject
18
+ # Prefer reduce over inject.
12
19
  Style/CollectionMethods:
13
20
  PreferredMethods:
14
21
  reduce: 'inject'
15
22
 
16
- # use each_with_object instead of inject
23
+ # Use each_with_object instead of inject.
17
24
  Style/EachWithObject:
18
25
  Enabled: false
19
26
 
20
- # removing the preference for string single quotes
21
- Style/StringLiterals:
22
- Enabled: false
23
-
24
- # prefer fail over raise
27
+ # Prefer fail over raise.
25
28
  Style/SignalException:
26
29
  Enabled: false
27
30
 
28
- Style/TrailingComma:
29
- EnforcedStyleForMultiline: comma
30
-
31
- # this never works for validations
32
- Style/AlignHash:
31
+ # This never works for validations.
32
+ Layout/AlignHash:
33
33
  EnforcedLastArgumentHashStyle: ignore_implicit
34
34
 
35
- # align multi-line params with previous line
36
- Style/AlignParameters:
35
+ # Align multi-line params with previous line.
36
+ Layout/AlignParameters:
37
37
  EnforcedStyle: with_fixed_indentation
38
38
 
39
- # indent `when` clause one step from `case`
40
- Style/CaseIndentation:
39
+ # Indent `when` clause one step from `case`.
40
+ Layout/CaseIndentation:
41
41
  IndentOneStep: true
42
42
 
43
- # don't force crappy var names for reduce/inject loops
43
+ # Don't force bad var names for reduce/inject loops.
44
44
  Style/SingleLineBlockParams:
45
45
  Enabled: false
46
46
 
47
- # for method chains, keep the dot with the method name
48
- Style/DotPosition:
47
+ # For method chains, keep the dot with the method name.
48
+ Layout/DotPosition:
49
49
  EnforcedStyle: leading
50
50
 
51
- Style/AccessorMethodName:
52
- Enabled: false
53
-
54
- Style/PredicateName:
55
- Enabled: false
56
-
57
- Style/MethodName:
58
- Enabled: false
59
-
60
- Style/Alias:
61
- Enabled: false
62
-
63
- Style/Next:
64
- Enabled: false
65
-
66
- # stop nesting so hard
51
+ # Stop nesting so hard.
67
52
  Metrics/BlockNesting:
68
53
  Max: 2
69
54
 
70
- # short methods
55
+ # Encourage short methods.
71
56
  Metrics/MethodLength:
72
- Max: 25
57
+ Max: 15
73
58
 
74
- Metrics/LineLength:
75
- Enabled: false
76
- #Max: 115
59
+ # Encourage short (as possible) modules.
60
+ Metrics/ModuleLength:
61
+ Max: 100
77
62
 
78
- # fewer parameters
63
+ # Encourage fewer parameters.
79
64
  Metrics/ParameterLists:
80
- Max: 5
65
+ Max: 4
81
66
 
82
- Metrics/AbcSize:
67
+ # Remove execute permissions check.
68
+ Lint/ScriptPermission:
83
69
  Enabled: false
84
70
 
85
- Metrics/ModuleLength:
86
- Max: 130
87
-
88
- Metrics/CyclomaticComplexity:
89
- Max: 12
71
+ # Specify Additions
90
72
 
91
- Metrics/PerceivedComplexity:
92
- Max: 12
93
-
94
- Lint/RescueException:
95
- Enabled: false
73
+ # This checks assignments, branches and coverage. During development,
74
+ # adding to the output of RSpec in a way that reads cleanly as code
75
+ # means being a little only slightly more forgiving for this metric.
76
+ # The default value is 15.
77
+ Metrics/AbcSize:
78
+ Max: 17
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format RSpec::Specify::Formatter
2
+ --color
3
+ --require spec_helper
@@ -1,2 +1,6 @@
1
+ inherit_mode:
2
+ merge:
3
+ - Exclude
4
+
1
5
  inherit_from:
2
6
  - .hound.yml
@@ -1,18 +1,14 @@
1
- language: ruby
2
-
1
+ ---
3
2
  sudo: false
3
+ language: ruby
4
+ cache: bundler
4
5
 
5
6
  rvm:
6
- - 2.0.0
7
- - 2.1
8
- - 2.2
7
+ - 2.5.1
8
+
9
+ before_install:
10
+ - gem install bundler
9
11
 
10
12
  branches:
11
13
  only:
12
14
  - master
13
-
14
- notifications:
15
- recipients:
16
- - jeffnyman@gmail.com
17
-
18
- before_install: gem install bundler -v 1.10.6
@@ -1,13 +1,74 @@
1
- # Contributor Code of Conduct
1
+ # Contributor Covenant Code of Conduct
2
2
 
3
- As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
3
+ ## Our Pledge
4
4
 
5
- We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
6
11
 
7
- Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
12
+ ## Our Standards
8
13
 
9
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
10
16
 
11
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
12
22
 
13
- This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at jeff.nyman@yello.co. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile CHANGED
@@ -1,3 +1,7 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
+
3
+ gem "coveralls", require: false
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
2
6
 
3
7
  gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Jeff Nyman
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,25 +1,22 @@
1
1
  # Specify
2
2
 
3
- [![Build Status](https://travis-ci.org/jnyman/specify.svg)](https://travis-ci.org/jnyman/specify)
3
+ > **The height of sophistication is simplicity.**<br>
4
+ > &nbsp;&nbsp;&nbsp;&nbsp;*Clare Boothe Brokaw*
4
5
 
5
- [![Coverage Status](https://img.shields.io/coveralls/jnyman/specify.svg)](https://coveralls.io/r/jnyman/specify?branch=master)
6
6
  [![Gem Version](https://badge.fury.io/rb/specify.svg)](http://badge.fury.io/rb/specify)
7
- [![Dependency Status](https://gemnasium.com/jnyman/specify.svg)](https://gemnasium.com/jnyman/specify)
8
- [![Code Climate](https://codeclimate.com/github/jnyman/specify/badges/gpa.svg)](https://codeclimate.com/github/jnyman/specify)
7
+ [![Build Status](https://travis-ci.org/jeffnyman/specify.svg)](https://travis-ci.org/jeffnyman/specify)
8
+ [![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/jeffnyman/specify/blob/master/LICENSE.md)
9
+ [![Maintainability](https://api.codeclimate.com/v1/badges/a42684de1702ed5a9333/maintainability)](https://codeclimate.com/github/jeffnyman/specify/maintainability)
9
10
 
10
- [![Gitter chat](https://badges.gitter.im/jnyman/specify.png)](https://gitter.im/jnyman/specify)
11
- [![endorse](https://api.coderwall.com/jnyman/endorsecount.png)](https://coderwall.com/jnyman)
11
+ ---
12
12
 
13
- > _"Simplicity is the ultimate sophistication."_
14
- > -- <cite>Leonardo da Vinci</cite>
13
+ Specify is a tool for leveraging RSpec to create an expressive DSL for test and data conditions. Specify will also provide test result reporting that recognizes the DSL.
15
14
 
16
- Specify is a test solution development tool that acts as a BDD-style micro-framework.
17
-
18
- Specify provides a very thin wrapper around RSpec that provides a Gherkin-style syntax for use with test examples.
15
+ Specify provides an internal DSL, similar to the [RSpec Story Runner](https://github.com/dchelimsky/rspec-stories). This was the predecessor of the [Cucumber](http://cukes.info/) external DSL provided by [Gherkin](http://cukes.info/gherkin.html).
19
16
 
20
17
  ## Installation
21
18
 
22
- To get the latest stable release, add this line to your application's Gemfile:
19
+ Add this line to your application's Gemfile:
23
20
 
24
21
  ```ruby
25
22
  gem 'specify'
@@ -28,45 +25,173 @@ gem 'specify'
28
25
  To get the latest code:
29
26
 
30
27
  ```ruby
31
- gem 'specify', git: https://github.com/jnyman/specify
28
+ gem 'specify', git: 'https://github.com/jeffnyman/specify'
32
29
  ```
33
30
 
34
31
  After doing one of the above, execute the following command:
35
32
 
36
- $ bundle
33
+ ```
34
+ $ bundle
35
+ ```
37
36
 
38
37
  You can also install Specify just as you would any other gem:
39
38
 
40
- $ gem install specify
39
+ ```
40
+ $ gem install specify
41
+ ```
41
42
 
42
43
  ## Usage
43
44
 
44
- To use Specify you simply have to require it within your `spec_helper` file:
45
+ To use Specify you simply have to require it within your `spec_helper.rb` file:
45
46
 
46
47
  ```ruby
47
48
  require 'specify'
48
49
  ```
49
50
 
50
- Then you simply run your `rspec` command as normal against your test suite.
51
+ Because Specify uses a custom formatter, you should have an `.rspec` file with the following line in it:
52
+
53
+ ```ruby
54
+ --format RSpec::Specify::Formatter
55
+ ```
56
+
57
+ Then you simply run your `rspec` command as normal against your test suite. Where the Specify formatter comes into play is in how you can construct your test specifications. You can use RSpec constructs within Specify constructs. Here is an example:
58
+
59
+ ```ruby
60
+ Feature 'Bank Accounts' do
61
+ let(:valid_account_number) { '1234567890' }
62
+ subject { Account.new(valid_account_number) }
63
+
64
+ Scenario 'starting a new account' do
65
+ test 'will have a starting balance of 0' do
66
+ expect(subject.balance).to eq(0)
67
+ end
68
+
69
+ it 'will not allow an invalid account name' do
70
+ expect { Account.new('thx1138') }.to raise_error(InvalidAccountNumberError)
71
+ end
72
+ end
73
+ end
74
+ ```
75
+
76
+ You can see that within the Specify-provided `Feature` construct I have the standard `let` and `subject` elements. Within the Specify-provided `Scenario` you can see I use a Specify-provide method (`test`) and an RSpec-provided method (`it`).
77
+
78
+ Modern development practices put an emphasis on communication. Much of this communication is done via the mechanisms of tests. These tests ideally act as readable specifications that communicate the intent of a test. Equally ideally, however, these tests do not hide the code that executes them behind too many layers of abstractions.
79
+
80
+ Tools in the xSpec family, of which RSpec is a part, do a good job of keeping code as a first-class citizen. This is contrasted with tools in the xBehave family, of which Cucumber is a part, where you have various abstractions like feature files sitting in front of code. Beyond that you also often have an intermediary layer, like the step definition files of Cucumber, that add one more layer of maintenance.
81
+
82
+ Beyond even that, such xBehave tools often do limit you to the expressions available via a structuring syntax, such as with the Gherkin API, that is outside of the code.
83
+
84
+ Specify lets you write as much logic beside your specifications as you want by leveraging the RSpec ecosystem with the addition of a Gherkin-like syntax as well as additions to that syntax. Perhaps worth noting is that Specify has no dependence on Gherkin.
85
+
86
+ The [unit tests](https://github.com/jeffnyman/specify/tree/master/spec) will give you some idea of how Specify allows the structuring of test specifications.
87
+
88
+ ### The Specify API
89
+
90
+ In RSpec, `describe` creates an example group and `it` creates a single example. You can use `context` as an alias for `describe` and you can use `example` and `specify` as aliases for `it`. Specify does a couple of things in the context of the API that RSpec provides.
91
+
92
+ Specify adds a few new example groups: `Feature` and `Story`. These are considered top-level example groups. Because they are top-level, they are mutually exlcusive so you can't have one nested within the other.
93
+
94
+ Specify also provides another set of example groups: `Ability`, `Component`, `Workflow`, and `Service`. These can be nested within one another and can be nested within the top-level example groups.
95
+
96
+ Specify provides some constructs that map to RSpec hooks as well: `Background` and `Setup` (both of which act like an RSpec `before`) along with `Teardown` and `Cleanup` (both of which act like an RSpec `after`).
97
+
98
+ As a very simple example, consider this:
99
+
100
+ ```ruby
101
+ Feature 'The Nature of Truth' do
102
+ Ability 'logic tests can be applied' do
103
+ Scenario 'true is not false' do
104
+ Then 'true is almost certainly not false' do
105
+ expect(true).to_not be false
106
+ end
107
+ end
108
+
109
+ Scenario 'true is true' do
110
+ Then 'true is pretty definitely true' do
111
+ expect(true).to be true
112
+ end
113
+ end
114
+ end
115
+ end
116
+ ```
117
+
118
+ Gherkin structures allow you to use the word "Ability" as an alias for "Feature". However Specify takes the viewpoint that a feature could be speaking to a high-level viewpoint, within which there are multiple abilities. Thus you can use both descriptors simultaneously, one nested within the other, which would not be possible with Gherkin. You can also see here that multiple Scenario blocks can be included within a Feature or Ability just as they would in Gherkin.
119
+
120
+ You might know that RSpec allows you to define your own names for its constructs already. For example, I could do something like this:
121
+
122
+ ```ruby
123
+ RSpec.configure do |rspec|
124
+ rspec.alias_example_group_to :scenario
125
+ rspec.alias_example_to :then
126
+ end
127
+ ```
128
+
129
+ So why wouldn't you just do that instead of using something like Specify? The answer lies in realizing that the `Scenario` implementation provided by Specify is not just acting as an alias for `context`. Rather, Specify hooks into RSpec to change the execution. This is done by extending RSpec to support step groups.
130
+
131
+ ### Specify Augments RSpec
51
132
 
52
- ## Why Specify?
133
+ RSpec is predicated upon unit testing or, at most, integration testing. Thus RSpec focuses on providing a runner that works for edge-to-edge tests. As such, RSpec's mode of action is that all examples should be completely independent. Consider this:
53
134
 
54
- Specify provides an internal DSL, similar to the [RSpec Story Runner](https://github.com/dchelimsky/rspec-stories), which was the predecessor of the [Cucumber](http://cukes.info/) external DSL provided by [Gherkin](http://cukes.info/gherkin.html).
135
+ ```ruby
136
+ context 'Simple Scenario' do
137
+ it 'sets up some context' do
138
+ end
139
+
140
+ it 'takes some action'
141
+ end
142
+
143
+ it 'observes some result' do
144
+ end
145
+ end
146
+ ```
55
147
 
56
- Behavior Driven Development (or even just good Test Driven Development) practices put emphasis on communication. Tools like Cucumber focus on allowing communication via a test description language, structured by Gherkin keywords. However, while the ideas of Gherkin are nice, tools like Cucumber abstract away the nuts and bolts of your tests.
148
+ Here each it block is a step but also is one independent test. The conditions for passing or failing must be within each step. Contrast this with a Cucumber feature scenario:
149
+
150
+ ```
151
+ Scenario: 'Simple Scenario'
152
+ Given some context
153
+ When some action
154
+ Then some result
155
+ ```
57
156
 
58
- Abstraction can be a good thing but Cucumber gives you no choice in the matter. It hides code blocks behind a "call by regular expression" invocation mechanism instead of making those code blocks readily available in the acceptance test description.
157
+ Here the `Scenario` block has three steps but they are not independent. They have to work together to be considered a passing or failing test.
59
158
 
60
- Specify lets you write as much logic beside your specifications as you want by leveraging the RSpec ecosystem with the addition of a Gherkin-like syntax.
159
+ So, for end-to-end purposes, this means if you want to use RSpec you have to write a sequence of examples, each of which repeats the behavior of all previous examples. Another alternative is that you could write one single large example that performs the entire set of actions. The problem in that case is that there is no independent reporting of each step. Or you could try to rely on a clever use of `before` and `after` calls. The problem there is that the `before` and `after` logic may differ significantly between tests. This is why tools like Cucumber end up being used.
61
160
 
62
- The [wiki](https://github.com/jnyman/specify/wiki) contains more information about Specify.
161
+ So that's one of the goals of Specify: provide just the good parts of Cucumber and skip all the questionable parts.
162
+
163
+ At minimum this means the ability to chain examples into a series of steps that run in sequence and which stop when a step fails. This allows you to assemble a series of tests that should all pass, but where complete isolation of those tests is not sensible. Given how Specify augments RSpec, this allows RSpec to be less unit and more integration and certainly more end-to-end.
164
+
165
+ Key to this is the ability to share state between example steps.
166
+
167
+ To that end, within the idea of an example group, Specify provides some constructs that are marked with metadata of "has_steps": `Scenario`, `Behavior`, and `Condition`. You can use non-capitalized variations of these as well. These are considered step groups. These cannot be nested within one another.
168
+
169
+ You can also use the following: `Steps`, `Rules`, `Tests`, `Facts` (along with non-capitalized variants). These are just meant to accommodate various ways of expressing tests but they also show you how Specify can be used to provide a grammar that is as expressive as you would like it to be.
170
+
171
+ Specify allows the normal RSpec `it`, `example`, and `specify` example keywords to be used within these step groups. However, Specify also adds a few other example keywords based on the above constructs: `step`, `rule`, `test`, and `fact`. Specify also provides the Gherkin style keywords as examples: `Given`, `When`, `Then`, `And`, and `But`.
172
+
173
+ RSpec provides multiple ways to create and use shared example groups. These come in pairs, with one method for defining a shared group and another for using it. So, in RSpec, `shared_context` and `include_context` are for reusing common setup and helper logic whereas `shared_examples` and `include_examples` are for reusing examples. Specify hooks into this general mechanism and provides `shared_steps` and `include_steps`. These shared steps go into RSpec's "world," which is an internal container that is used for holding global non-configuration data.
174
+
175
+ ## Development
176
+
177
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec:all` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
178
+
179
+ To experiment with the code, run `bin/console` for an interactive prompt. If you want to make changes and see how they work as a gem installed on your local machine, run `bundle exec rake install`.
180
+
181
+ The default `rake` command will run all tests as well as a Rubocop analysis.
182
+
183
+ If you have rights to deploy a new version, make sure to update the version number in `version.rb`, and then run `bundle exec rake release`. This will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
63
184
 
64
185
  ## Contributing
65
186
 
66
- To work on Specify:
187
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/jeffnyman/specify](https://github.com/jeffnyman/specify). The testing ecosystem of Ruby is very large and this project is intended to be a welcoming arena for collaboration on yet another test-supporting tool. As such, contributors are very much welcome but are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) which is provided as a [code of conduct](https://github.com/jeffnyman/specify/blob/master/CODE_OF_CONDUCT.md).
188
+
189
+ The Specify gems follows [semantic versioning](http://semver.org).
190
+
191
+ To contribute to Specify:
67
192
 
68
193
  1. [Fork the project](http://gun.io/blog/how-to-github-fork-branch-and-pull-request/).
69
- 2. Create a feature branch. (`git checkout -b my-new-feature`)
194
+ 2. Create your feature branch. (`git checkout -b my-new-feature`)
70
195
  3. Commit your changes. (`git commit -am 'new feature'`)
71
196
  4. Push the branch. (`git push origin my-new-feature`)
72
197
  5. Create a new [pull request](https://help.github.com/articles/using-pull-requests).
@@ -78,13 +203,14 @@ To work on Specify:
78
203
  ## License
79
204
 
80
205
  Specify is distributed under the [MIT](http://www.opensource.org/licenses/MIT) license.
81
- See the [LICENSE](https://github.com/jnyman/symbiont/blob/master/LICENSE.txt) file for details.
206
+ See the [LICENSE](https://github.com/jeffnyman/specify/blob/master/LICENSE.md) file for details.
82
207
 
83
208
  ## Credits
84
209
 
85
- Specify has been inspired by the following projects:
210
+ Specify has been inspired by the following projects. Each provided me with ideas for what to do and, in some cases, for what not to do. All were invaluable as I better considered how to leverage RSpec's functionality.
86
211
 
87
212
  * [maniok_bdd](https://github.com/21croissants/maniok_bdd)
88
213
  * [rspec-gherkin](https://github.com/sheerun/rspec-gherkin)
89
214
  * [rspec example steps](https://github.com/railsware/rspec-example_steps)
90
215
  * [XSpec](https://github.com/xaviershay/xspec)
216
+ * [Mouse Melon](https://github.com/wojtha/mouse_melon)