uninhibited 0.1.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.
- data/MIT_LICENSE +20 -0
- data/README.md +31 -0
- data/lib/uninhibited.rb +23 -0
- data/lib/uninhibited/background_metadata.rb +28 -0
- data/lib/uninhibited/feature.rb +169 -0
- data/lib/uninhibited/formatter.rb +88 -0
- data/lib/uninhibited/object_extensions.rb +29 -0
- data/lib/uninhibited/version.rb +3 -0
- metadata +110 -0
data/MIT_LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Bernerd Schaefer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Uninhibited
|
2
|
+
|
3
|
+
Inspired by [unencumbered](http://github.com/hashrocket/unencumbered),
|
4
|
+
Unhibited gives painless Cucumber-style syntax for RSpec integration tests.
|
5
|
+
|
6
|
+
Here's a sample feature in Uninhibited:
|
7
|
+
|
8
|
+
require "spec_helper"
|
9
|
+
|
10
|
+
Feature "User creates a vurl" do
|
11
|
+
Given "I am on the home page" do
|
12
|
+
visit root_path
|
13
|
+
end
|
14
|
+
|
15
|
+
When "I submit a valid vurl" do
|
16
|
+
fill_in "vurl_url", :with => 'http://example.com'
|
17
|
+
click_button 'Vurlify!'
|
18
|
+
end
|
19
|
+
|
20
|
+
Then "I should be on the vurl stats page" do
|
21
|
+
current_url.should == stats_url(Vurl.last.slug)
|
22
|
+
end
|
23
|
+
|
24
|
+
And "I should see a success message" do
|
25
|
+
response.body.should include('Vurl was successfully created')
|
26
|
+
end
|
27
|
+
|
28
|
+
And "my vurl was created" do
|
29
|
+
Vurl.last.url.should == 'http://example.com'
|
30
|
+
end
|
31
|
+
end
|
data/lib/uninhibited.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'uninhibited/background_metadata'
|
3
|
+
require 'uninhibited/feature'
|
4
|
+
require 'uninhibited/formatter'
|
5
|
+
require 'uninhibited/object_extensions'
|
6
|
+
require 'uninhibited/version'
|
7
|
+
|
8
|
+
module Uninhibited
|
9
|
+
|
10
|
+
# Set up Uninhibited's required features, and configures RSpec as necessary.
|
11
|
+
def self.setup
|
12
|
+
Object.send(:include, Uninhibited::ObjectExtensions)
|
13
|
+
|
14
|
+
RSpec::Core::Metadata.send(:include, BackgroundMetadata)
|
15
|
+
|
16
|
+
config = RSpec.configuration
|
17
|
+
config.filter[:include_background] = true if config.filter
|
18
|
+
config.formatter = Uninhibited::Formatter
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
Uninhibited.setup
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Uninhibited
|
2
|
+
# Extension for RSpec::Core::Metadata to include background step definitions
|
3
|
+
# even when running filtered actions.
|
4
|
+
module BackgroundMetadata
|
5
|
+
|
6
|
+
# When running a filtered set of steps, we still want to run the background
|
7
|
+
# steps, so we need a custom method for handling this case.
|
8
|
+
def all_apply_or_background?(filters)
|
9
|
+
if filters[:include_background] && self[:background]
|
10
|
+
true
|
11
|
+
else
|
12
|
+
rspec_all_apply?(filters.reject { |k,| k == :include_background })
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# @param [RSpec::Core::Metadata] base rspec's metadata class
|
19
|
+
# @api private
|
20
|
+
def self.included(base)
|
21
|
+
base.class_eval <<-RUBY
|
22
|
+
alias rspec_all_apply? all_apply?
|
23
|
+
alias all_apply? all_apply_or_background?
|
24
|
+
RUBY
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Uninhibited
|
2
|
+
|
3
|
+
# Features
|
4
|
+
# @todo complete
|
5
|
+
module Feature
|
6
|
+
|
7
|
+
# Defines a new Scenario group
|
8
|
+
#
|
9
|
+
# Feature "User signs in" do
|
10
|
+
# Scenario "success" do
|
11
|
+
# Given "I on the login page"
|
12
|
+
# When "I fill in my email and password"
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# This will be printed like so:
|
17
|
+
#
|
18
|
+
# Feature: User signs in
|
19
|
+
# Scenario: success
|
20
|
+
# Given I am on the login page
|
21
|
+
# When I fill in my email and password
|
22
|
+
#
|
23
|
+
# @param args the description, metadata, etc. as RSpec's #describe method
|
24
|
+
# takes.
|
25
|
+
# @param example_group_block the block to be executed within the feature
|
26
|
+
def Scenario(*args, &example_group_block)
|
27
|
+
describe("Scenario:", *args) do
|
28
|
+
instance_eval(&example_group_block) if block_given?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Defines a new Background group
|
33
|
+
#
|
34
|
+
# Feature "Something" do
|
35
|
+
# Background do
|
36
|
+
# Given "I..."
|
37
|
+
# end
|
38
|
+
# Scenario "success" do
|
39
|
+
# When "I..."
|
40
|
+
# end
|
41
|
+
# Scenario "failure" do
|
42
|
+
# When "I..."
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# This will be printed like so:
|
47
|
+
#
|
48
|
+
# Feature: User signs in
|
49
|
+
# Background:
|
50
|
+
# Given I...
|
51
|
+
# Scenario: success
|
52
|
+
# When I...
|
53
|
+
# Scenario: failure
|
54
|
+
# When I...
|
55
|
+
#
|
56
|
+
# @param args the description, metadata, etc. as RSpec's #describe method
|
57
|
+
# takes.
|
58
|
+
# @param example_group_block the block to be executed within the feature
|
59
|
+
def Background(*args, &example_group_block)
|
60
|
+
describe("Background:", *args) do
|
61
|
+
metadata[:background] = true
|
62
|
+
|
63
|
+
instance_eval(&example_group_block) if block_given?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Defines a new Given example
|
68
|
+
#
|
69
|
+
# Given "I am on the home page" do
|
70
|
+
# visit root_path
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# @param [String] desc the description
|
74
|
+
# @param [Hash] options the metadata for this example
|
75
|
+
# @param block the example's code
|
76
|
+
def Given(desc=nil, options={}, &block)
|
77
|
+
example("Given #{desc}", options, &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Defines a new When example
|
81
|
+
#
|
82
|
+
# When "I click Home" do
|
83
|
+
# click_link "Home"
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# @param [String] desc the description
|
87
|
+
# @param [Hash] options the metadata for this example
|
88
|
+
# @param block the example's code
|
89
|
+
def When(desc=nil, options={}, &block)
|
90
|
+
example("When #{desc}", options, &block)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Defines a new Then example
|
94
|
+
#
|
95
|
+
# Then "I see a welcome message" do
|
96
|
+
# page.should have_content("Welcome!")
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# @param [String] desc the description
|
100
|
+
# @param [Hash] options the metadata for this example
|
101
|
+
# @param block the example's code
|
102
|
+
def Then(desc=nil, options={}, &block)
|
103
|
+
example("Then #{desc}", options, &block)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Defines a new And example
|
107
|
+
#
|
108
|
+
# And "I am on the home page" do
|
109
|
+
# visit root_path
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# @param [String] desc the description
|
113
|
+
# @param [Hash] options the metadata for this example
|
114
|
+
# @param block the example's code
|
115
|
+
def And(desc=nil, options={}, &block)
|
116
|
+
example("And #{desc}", options, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Defines a new But example
|
120
|
+
#
|
121
|
+
# But "I am on the home page" do
|
122
|
+
# visit root_path
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# @param [String] desc the description
|
126
|
+
# @param [Hash] options the metadata for this example
|
127
|
+
# @param block the example's code
|
128
|
+
def But(desc=nil, options={}, &block)
|
129
|
+
example("But #{desc}", options, &block)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Skip examples after the example provided.
|
133
|
+
#
|
134
|
+
# @param [ExampleGroup] example_group the example group of example
|
135
|
+
# @param [Example] example the example to skip after
|
136
|
+
#
|
137
|
+
# @api private
|
138
|
+
def skip_examples_after(example_group, example)
|
139
|
+
examples = example_group.descendant_filtered_examples.flatten
|
140
|
+
examples[examples.index(example)..-1].each do |e|
|
141
|
+
e.metadata[:pending] = true
|
142
|
+
e.metadata[:skipped] = true
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
# Extends an ExampleGroup with the features required for running
|
149
|
+
# Uninhibited specs.
|
150
|
+
#
|
151
|
+
# @param [ExampleGroup] base the example group
|
152
|
+
# @api private
|
153
|
+
def self.extended(base)
|
154
|
+
base.metadata[:feature] = true
|
155
|
+
|
156
|
+
base.after(:each) do
|
157
|
+
if example.instance_variable_get(:@exception)
|
158
|
+
if example.example_group.metadata[:background]
|
159
|
+
self.class.skip_examples_after(self.class.ancestors[1], example)
|
160
|
+
else
|
161
|
+
self.class.skip_examples_after(self.class, example)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Uninhibited
|
2
|
+
|
3
|
+
# Custom formatter for displaying the results of a feature.
|
4
|
+
class Formatter < RSpec::Core::Formatters::DocumentationFormatter
|
5
|
+
|
6
|
+
# the number of skipped examples
|
7
|
+
# @attr [Integer]
|
8
|
+
attr_accessor :skipped_count
|
9
|
+
|
10
|
+
# the skipped examples
|
11
|
+
# @attr_reader [Array]
|
12
|
+
attr_reader :skipped_examples
|
13
|
+
|
14
|
+
# Builds a new formatter for outputting Uninhibited features.
|
15
|
+
#
|
16
|
+
# @api rspec
|
17
|
+
# @param [IO] output the output stream
|
18
|
+
def initialize(output)
|
19
|
+
super
|
20
|
+
@skipped_examples = []
|
21
|
+
@skipped_count = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
# Adds the pending example to skipped examples array if it was skipped,
|
25
|
+
# otherwise it delegates to super.
|
26
|
+
#
|
27
|
+
# @api rspec
|
28
|
+
def example_pending(example)
|
29
|
+
if example_group.metadata[:feature] && example.metadata[:skipped]
|
30
|
+
@skipped_examples << pending_examples.delete(example)
|
31
|
+
@skipped_count += 1
|
32
|
+
output.puts cyan("#{current_indentation}#{example.description}")
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Stubbed method to return the summary as provided, since the summary will
|
39
|
+
# already be colorized.
|
40
|
+
#
|
41
|
+
# @return [String] the output summary
|
42
|
+
#
|
43
|
+
# @api rspec
|
44
|
+
def colorise_summary(summary)
|
45
|
+
summary
|
46
|
+
end
|
47
|
+
|
48
|
+
# Generates a colorized summary line based on the supplied arguments.
|
49
|
+
#
|
50
|
+
# formatter.summary_line(1, 0, 0)
|
51
|
+
# # => 1 example (0 failures)
|
52
|
+
#
|
53
|
+
# formatter.summary_line(2, 1, 1)
|
54
|
+
# # => 2 examples (1 failure, 1 pending)
|
55
|
+
#
|
56
|
+
# formatter.skipped_count += 1
|
57
|
+
# formatter.summary_line(2, 0, 0)
|
58
|
+
# # => 2 examples (1 failure, 1 skipped)
|
59
|
+
#
|
60
|
+
# @param [Integer] example_count the total examples run
|
61
|
+
# @param [Integer] failure_count the failed examples
|
62
|
+
# @param [Integer] pending_count the pending examples
|
63
|
+
#
|
64
|
+
# @return [String] the formatted summary line
|
65
|
+
#
|
66
|
+
# @api rspec
|
67
|
+
def summary_line(example_count, failure_count, pending_count)
|
68
|
+
pending_count -= skipped_count
|
69
|
+
summary = pluralize(example_count, "example")
|
70
|
+
summary << " ("
|
71
|
+
summary << red(pluralize(failure_count, "failure"))
|
72
|
+
summary << ", " << yellow("#{pending_count} pending") if pending_count > 0
|
73
|
+
summary << ", " << cyan("#{skipped_count} skipped") if skipped_count > 0
|
74
|
+
summary << ")"
|
75
|
+
summary
|
76
|
+
end
|
77
|
+
|
78
|
+
# Generate a string to output to the terminal with cyan coloration
|
79
|
+
#
|
80
|
+
# @param [String] text the text to be colorized
|
81
|
+
# @return [String] colorized text
|
82
|
+
def cyan(text)
|
83
|
+
color(text, "\e[36m")
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Uninhibited
|
2
|
+
|
3
|
+
# Extension methods to be included in the global object space
|
4
|
+
# for defining features.
|
5
|
+
module ObjectExtensions
|
6
|
+
|
7
|
+
# Defines a new feature:
|
8
|
+
#
|
9
|
+
# Feature "User signs in" do
|
10
|
+
# Given "..."
|
11
|
+
# When "..."
|
12
|
+
# Then "..."
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# @param args the description, metadata, etc. as RSpec's #describe method
|
16
|
+
# takes.
|
17
|
+
# @param example_group_block the block to be executed within the feature
|
18
|
+
#
|
19
|
+
# @return [Feature] the new example group
|
20
|
+
def Feature(*args, &example_group_block)
|
21
|
+
describe(*args) do
|
22
|
+
extend Uninhibited::Feature
|
23
|
+
instance_eval(&example_group_block) if block_given?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uninhibited
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Bernerd Schaefer
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-09-02 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
- beta
|
32
|
+
- 20
|
33
|
+
version: 2.0.0.beta.20
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: yard
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: bluecloth
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id003
|
60
|
+
description: ""
|
61
|
+
email: bj.schaefer@gmail.com
|
62
|
+
executables: []
|
63
|
+
|
64
|
+
extensions: []
|
65
|
+
|
66
|
+
extra_rdoc_files: []
|
67
|
+
|
68
|
+
files:
|
69
|
+
- lib/uninhibited/background_metadata.rb
|
70
|
+
- lib/uninhibited/feature.rb
|
71
|
+
- lib/uninhibited/formatter.rb
|
72
|
+
- lib/uninhibited/object_extensions.rb
|
73
|
+
- lib/uninhibited/version.rb
|
74
|
+
- lib/uninhibited.rb
|
75
|
+
- README.md
|
76
|
+
- MIT_LICENSE
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://bernerdschaefer.github.com/uninhibited
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
segments:
|
98
|
+
- 1
|
99
|
+
- 3
|
100
|
+
- 6
|
101
|
+
version: 1.3.6
|
102
|
+
requirements: []
|
103
|
+
|
104
|
+
rubyforge_project: uninhibited
|
105
|
+
rubygems_version: 1.3.6
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: ""
|
109
|
+
test_files: []
|
110
|
+
|