elight-coulda 0.1.1

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ coulda*.gem
2
+ coverage/*
data/HISTORY ADDED
@@ -0,0 +1,7 @@
1
+ 0.1.0
2
+ -----
3
+ Initial release with basic features to generate tests from internal DSL
4
+
5
+ 0.1.1
6
+ -----
7
+ Corrections for github gem build process
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ coulda
2
+
3
+ MIT License
4
+
5
+ Copyright (c) 2009, Evan David Light
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ coulda
2
+ ------
3
+ coulda gives you Cucumber-like BDD power but with an internal DSL. This means no "call-by-regexp" and
4
+ no Gherkin/plain-text/external DSL. coulda is just code -- but with a Cucumber-like take on BDD.
5
+
6
+ coulda, obviously was inspired by Cucumber, Shoulda, but also Thor. coulda believes that the best way to reuse
7
+ code is the good ol' fashioned method. Instead of sharing files of regexps mapped to procs, you just write
8
+ methods. That simple.
9
+
10
+ You can define the implementation of your Given/When/Then right there with the behavior description. Or,
11
+ if you want to reuse some Givens/Whens/Thens, just write a method! And if you find your Feature is getting
12
+ too bloated or that you would like to reuse Givens/Whens/Thens between features, put them in a helper.
13
+
14
+ Easy as pie.
15
+
16
+ require 'rubygems'
17
+ require 'coulda'
18
+ include Coulda
19
+
20
+ Feature "feature name" do
21
+ in_order_to "foo"
22
+ as_a "bar"
23
+ i_want_to "blech"
24
+
25
+ def something
26
+ end
27
+
28
+ def expectation
29
+ end
30
+
31
+ Scenario "pending scenario"
32
+
33
+ Scenario "another scenario" do
34
+ Given "a pending prereq"
35
+ When "something happens" do
36
+ something
37
+ end
38
+ Then "expect something else" do
39
+ expectation
40
+ end
41
+ end
42
+
43
+ Scenario "that is live" do
44
+ Given "foo" do; end
45
+ When "bar" do; end
46
+ Then "blech" do; end
47
+ end
48
+ end
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+
7
+ require 'shoulda'
8
+
9
+ # Test::Unit::UI::VERBOSE
10
+ test_files_pattern = 'test/**/*_test.rb'
11
+ src_files_pattern = 'src/**/*.rb'
12
+
13
+ Rake::TestTask.new do |t|
14
+ src_files = Dir[src_files_pattern]
15
+ src_files.each { |f| puts f; require f[0...-3] }
16
+ t.pattern = test_files_pattern
17
+ t.verbose = false
18
+ end
19
+
20
+ begin
21
+ require 'jeweler'
22
+ Jeweler::Tasks.new do |s|
23
+ s.name = "coulda"
24
+ s.version = "0.1.1"
25
+ s.authors = ["Evan David Light"]
26
+ s.email = "evan@tiggerpalace.com"
27
+ s.summary = "Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse"
28
+ s.homepage = "http://evan.tiggerpalace.com/"
29
+ s.description = "Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse"
30
+ end
31
+ rescue LoadError
32
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
33
+ end
34
+
35
+
36
+ desc 'Default: run tests.'
37
+ task :default => 'test'
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
data/coulda.gemspec ADDED
@@ -0,0 +1,56 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{coulda}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Evan David Light"]
12
+ s.date = %q{2009-09-12}
13
+ s.description = %q{Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse}
14
+ s.email = %q{evan@tiggerpalace.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "HISTORY",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "coulda.gemspec",
27
+ "example/sample.rb",
28
+ "lib/coulda.rb",
29
+ "lib/coulda/feature.rb",
30
+ "lib/coulda/scenario.rb",
31
+ "test/feature_test.rb",
32
+ "test/scenario_test.rb",
33
+ "test/test_helper.rb"
34
+ ]
35
+ s.homepage = %q{http://evan.tiggerpalace.com/}
36
+ s.rdoc_options = ["--charset=UTF-8"]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.3.4}
39
+ s.summary = %q{Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse}
40
+ s.test_files = [
41
+ "test/feature_test.rb",
42
+ "test/scenario_test.rb",
43
+ "test/test_helper.rb"
44
+ ]
45
+ s.add_dependency 'jeremymcanally-pending', '>= 0.1'
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ else
53
+ end
54
+ else
55
+ end
56
+ end
data/example/sample.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'coulda'
3
+ include Coulda
4
+
5
+ Feature "feature name" do
6
+ in_order_to "foo"
7
+ as_a "bar"
8
+ i_want_to "blech"
9
+
10
+ def something
11
+ end
12
+
13
+ def expectation
14
+ end
15
+
16
+ Scenario "pending scenario"
17
+
18
+ Scenario "another scenario" do
19
+ Given "a pending prereq"
20
+ When "something happens" do
21
+ something
22
+ end
23
+ Then "expect something else" do
24
+ expectation
25
+ end
26
+ end
27
+
28
+ Scenario "that is live" do
29
+ Given "foo" do; end
30
+ When "bar" do; end
31
+ Then "blech" do; end
32
+ end
33
+ end
@@ -0,0 +1,68 @@
1
+ require 'test/unit'
2
+
3
+ module Coulda
4
+ class Feature < Test::Unit::TestCase
5
+ class << self
6
+ def in_order_to(what)
7
+ @in_order_to = what
8
+ end
9
+
10
+ def as_a(who)
11
+ @as_a = who
12
+ end
13
+
14
+ def i_want_to(what)
15
+ @i_want_to = what
16
+ end
17
+
18
+ def for_name(name)
19
+ klass = Class.new(Feature)
20
+ class_name = "Feature" + name.split(/\s/).map { |w| w.capitalize }.join
21
+ Object.const_set(class_name, klass)
22
+ klass
23
+ end
24
+
25
+ def assert_description
26
+ if @in_order_to || @as_a || @i_want_to
27
+ raise SyntaxError.new("Must call in_order_to if as_a and/or i_wanted_to called") unless @in_order_to
28
+ raise SyntaxError.new("Must call as_a if in_order_to and/or i_want_to called") unless @as_a
29
+ raise SyntaxError.new("Must call i_want_to if in_order_to and/or as_a called") unless @i_want_to
30
+ end
31
+ end
32
+
33
+ def Scenario(name, &test_implementation)
34
+ raise SyntaxError.new("A scenario requires a name") unless name
35
+ method_name = "test_#{name.sub(/\s/, "_").downcase}"
36
+ @scenarios ||= []
37
+ @scenarios << scenario = Scenario.new(name, &test_implementation)
38
+ if scenario.pending?
39
+ define_method(method_name) { pending }
40
+ else
41
+ define_method(method_name, &test_implementation)
42
+ end
43
+ scenario
44
+ end
45
+
46
+ def scenarios
47
+ @scenarios ||= []
48
+ end
49
+
50
+ def pending?
51
+ @scenarios.all? { |s| !s.pending? }
52
+ end
53
+ end
54
+
55
+ # Allow scenario-less features not to fail
56
+ def default_test; end
57
+ end
58
+
59
+ %w[Given When Then].each do |statement|
60
+ eval <<-HERE
61
+ def #{statement}(name, &block)
62
+ block.call
63
+ end
64
+ HERE
65
+ end
66
+ end
67
+
68
+
@@ -0,0 +1,70 @@
1
+ module Coulda
2
+ class Scenario
3
+ attr_reader :name
4
+
5
+ Statement = Struct.new(:type, :name, :block)
6
+
7
+ def initialize(name, &block)
8
+ @name = name.to_s
9
+ @block = block
10
+ @statements = []
11
+ check_statements
12
+ @pending = @statements.empty? || @statements.any? { |s| s.block.nil? }
13
+ @last_stmt_type = nil
14
+ end
15
+
16
+ %w[Given When Then].each do |statement|
17
+ eval <<-HERE
18
+ def #{statement}(name, &block)
19
+ if @validating_semantics
20
+ @statements << stmt = Statement.new(:#{statement}, name, block)
21
+ elsif pending?
22
+ # TODO
23
+ elseif
24
+ block.call
25
+ end
26
+ end
27
+ HERE
28
+ end
29
+
30
+ def pending?
31
+ @pending
32
+ end
33
+
34
+ private
35
+
36
+ def check_statements
37
+ @validating_semantics = true
38
+ if @block
39
+ instance_eval &@block
40
+ assert_statements
41
+ end
42
+ @validating_semantics = false
43
+
44
+ end
45
+
46
+ def assert_statements
47
+ if !pending? && @statements
48
+ assert_presence_of_statements
49
+ assert_order_of_statements
50
+ end
51
+ end
52
+
53
+ def assert_presence_of_statements
54
+ givens_present = @statements.any? { |s| s.type == :Given }
55
+ raise SyntaxError.new("No Givens are present") unless givens_present
56
+ whens_present = @statements.any? { |s| s.type == :When }
57
+ raise SyntaxError.new("No Whens are present") unless whens_present
58
+ thens_present = @statements.any? { |s| s.type == :Then }
59
+ raise SyntaxError.new("No Thens are present") unless thens_present
60
+ end
61
+
62
+ def assert_order_of_statements
63
+ stmt_types = @statements.collect { |s| s.type }
64
+ unless stmt_types.rindex(:Given) < stmt_types.index(:When) &&
65
+ stmt_types.rindex(:When) < stmt_types.index(:Then)
66
+ raise SyntaxError.new("Given, Whens, Thens are out of order")
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/coulda.rb ADDED
@@ -0,0 +1,18 @@
1
+ module Coulda
2
+ SyntaxError = Class.new(StandardError)
3
+ end
4
+
5
+ gem 'jeremymcanally-pending', '>= 0.1'
6
+ require 'pending'
7
+
8
+ require 'coulda/feature'
9
+ require 'coulda/scenario'
10
+
11
+ module Kernel
12
+ def Feature(name, &block)
13
+ f = Feature.for_name(name)
14
+ f.class_eval(&block)
15
+ f.assert_description
16
+ f
17
+ end
18
+ end
@@ -0,0 +1,117 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper")
2
+
3
+ class FeatureTest < Test::Unit::TestCase
4
+ def run_feature(feature)
5
+ result = Test::Unit::TestResult.new
6
+ p = Proc.new {}
7
+ feature.suite.run(result, &p)
8
+ result
9
+ end
10
+
11
+ context "A Feature class" do
12
+ should "have Test::Unit::TestCase as an ancestor" do
13
+ assert(Feature.ancestors.include?(Test::Unit::TestCase))
14
+ end
15
+
16
+ context "created by name" do
17
+ setup do
18
+ @feature = Feature.for_name "foo"
19
+ end
20
+
21
+ should "be a subclass of Feature" do
22
+ assert(@feature.ancestors.include?(Feature))
23
+ end
24
+ end
25
+
26
+
27
+ context "that calls in_order_to, as_a, and i_want_to" do
28
+ should "not raise syntax error" do
29
+ assert_nothing_raised do
30
+ Feature "one" do
31
+ in_order_to "foo"
32
+ as_a "bar"
33
+ i_want_to "blech"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ context "that calls as_a and i_want_to" do
40
+ should "raise syntax error because in_order_to was not called once" do
41
+ assert_raise Coulda::SyntaxError do
42
+ Feature "two" do
43
+ as_a "bar"
44
+ i_want_to "blech"
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ context "that calls in_order_to and i_want_to" do
51
+ should "raise syntax error because as_a was not called once" do
52
+ assert_raise Coulda::SyntaxError do
53
+ Feature "three" do
54
+ in_order_to "foo"
55
+ i_want_to "blech"
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ context "that calls in_order_to and as_a" do
62
+ should "raise syntax error because i_want_to was not called once" do
63
+ assert_raise Coulda::SyntaxError do
64
+ Feature "four" do
65
+ in_order_to "foo"
66
+ as_a "bar"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ context "without scenarios" do
73
+ setup do
74
+ @feature_without_scenarios = Feature "five" do
75
+ in_order_to "foo"
76
+ as_a "bar"
77
+ i_want_to "blech"
78
+ end
79
+ end
80
+
81
+ should "not have any errors when run" do
82
+ result = run_feature @feature_without_scenarios
83
+ assert(result.passed?, result.inspect)
84
+ end
85
+ end
86
+
87
+ context "that does not have any errors" do
88
+ @@counter = 1
89
+ setup do
90
+ @feature_without_errors = Feature @@counter.to_s do
91
+ in_order_to "foo"
92
+ as_a "bar"
93
+ i_want_to "blech"
94
+ end
95
+ @@counter += 1
96
+ end
97
+
98
+ ### Integration tests
99
+
100
+ context "with a block containing a scenario" do
101
+ should "create a Feature instance method named 'test_<underscored_scenario_name>'" do
102
+ @feature_without_errors.Scenario "pending scenario"
103
+ assert(@feature_without_errors.instance_methods.include?("test_pending_scenario"), "Feature is missing test method from scenario")
104
+ end
105
+
106
+ should "create a Scenario" do
107
+ @feature_without_errors.Scenario "pending scenario"
108
+ end
109
+
110
+ should "include the created Scenario in the return value of the 'scenarios' method" do
111
+ scenario = @feature_without_errors.Scenario "pending scenario"
112
+ assert(@feature_without_errors.scenarios.include?(scenario), "feature.scenarios doesn't contain the expected Scenario object")
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,139 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper")
2
+
3
+ class ScenarioTest < Test::Unit::TestCase
4
+ context "A Scenario" do
5
+ setup do
6
+ @scenario = Scenario.new("foobar")
7
+ end
8
+
9
+ %w[Given When Then].each do |condition|
10
+ should "have a method called '#{condition}'" do
11
+ assert(@scenario.respond_to?(condition.to_sym))
12
+ end
13
+ end
14
+
15
+ context "when instantiated" do
16
+ context "with only a String" do
17
+ setup do
18
+ @scenario = Scenario.new("foobar")
19
+ end
20
+
21
+ should "be pending" do
22
+ assert(@scenario.pending?)
23
+ end
24
+ end
25
+
26
+ context "with a block" do
27
+ context "when validating the semantics of the code in the block" do
28
+ should "raise a DSL syntax error if no givens are present" do
29
+ assert_raises Coulda::SyntaxError do
30
+ Scenario.new "foo" do
31
+ When "bar"
32
+ Then "blech"
33
+ end
34
+ end
35
+ end
36
+
37
+ should "raise a DSL syntax error if no whens are present" do
38
+ assert_raises Coulda::SyntaxError do
39
+ Scenario.new "foo" do
40
+ Given "bar"
41
+ Then "blech"
42
+ end
43
+ end
44
+ end
45
+
46
+ should "raise a DSL syntax error if no thens are present" do
47
+ assert_raises Coulda::SyntaxError do
48
+ Scenario.new "foo" do
49
+ Given "bar"
50
+ When "blech"
51
+ end
52
+ end
53
+ end
54
+
55
+ context "and all givens occur before all whens" do
56
+ context "and all whens occur before all thens" do
57
+ should "not raise an error" do
58
+ assert_nothing_raised do
59
+ Scenario.new "foo" do
60
+ Given "bar"
61
+ When "blech"
62
+ Then "baz"
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ context "and all whens do not occur before all thens" do
69
+ should "raise a DSL syntax error" do
70
+ assert_raises Coulda::SyntaxError do
71
+ Scenario.new "foo" do
72
+ Given "bar"
73
+ When "blech"
74
+ Then "baz"
75
+ When "foobarblech"
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ context "where not all givens occur before all whens" do
83
+ context "and all whens occur before all thens" do
84
+ should "raise a DSL syntax error" do
85
+ assert_raises Coulda::SyntaxError do
86
+ Scenario.new "foo" do
87
+ Given "bar"
88
+ When "blech"
89
+ Given "foobarblech"
90
+ Then "baz"
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ context "and all whens do not occur before all thens" do
97
+ should "raise a DSL syntax error" do
98
+ assert_raises Coulda::SyntaxError do
99
+ Scenario.new "foo" do
100
+ Given "bar"
101
+ When "blech"
102
+ Given "barblech"
103
+ Then "baz"
104
+ When "foobarblech"
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ context "where givens, whens, are present and in the correct order" do
112
+ context "but a Given does not have a block" do
113
+ should "declare the scenario pending" do
114
+ scenario = Scenario.new "foo" do
115
+ Given "bar"
116
+ When "blech" do; end
117
+ Then "baz" do; end
118
+ end
119
+ assert(scenario.pending?)
120
+ end
121
+ end
122
+
123
+ context "and the givens, whens, and thens have blocks" do
124
+ should "not be pending" do
125
+ scenario = Scenario.new "foo" do
126
+ Given "bar" do; end
127
+ When "blech" do; end
128
+ Then "baz" do; end
129
+ end
130
+ assert(!scenario.pending?)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "..", "lib")
6
+ require 'coulda'
7
+
8
+ include Coulda
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elight-coulda
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Evan David Light
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-12 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jeremymcanally-pending
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0.1"
24
+ version:
25
+ description: Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse
26
+ email: evan@tiggerpalace.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .gitignore
36
+ - HISTORY
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - coulda.gemspec
42
+ - example/sample.rb
43
+ - lib/coulda.rb
44
+ - lib/coulda/feature.rb
45
+ - lib/coulda/scenario.rb
46
+ - test/feature_test.rb
47
+ - test/scenario_test.rb
48
+ - test/test_helper.rb
49
+ has_rdoc: false
50
+ homepage: http://evan.tiggerpalace.com/
51
+ licenses:
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Behaviour Driven Development derived from Cucumber but as an internal DSL with methods for reuse
76
+ test_files:
77
+ - test/feature_test.rb
78
+ - test/scenario_test.rb
79
+ - test/test_helper.rb