uninhibited 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
@@ -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
@@ -0,0 +1,3 @@
1
+ module Uninhibited
2
+ VERSION = '0.1.0'
3
+ 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
+