rspec-set 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile CHANGED
@@ -1,13 +1,4 @@
1
- source "http://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
1
+ source 'https://rubygems.org'
5
2
 
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem "shoulda", ">= 0"
10
- gem "bundler", "~> 1.0.0"
11
- gem "jeweler", "~> 1.5.1"
12
- gem "rcov", ">= 0"
13
- end
3
+ # Specify your gem's dependencies in rspec-set.gemspec
4
+ gemspec
data/LICENSE.txt CHANGED
@@ -1,4 +1,6 @@
1
- Copyright (c) 2010 Philippe Creux
1
+ Copyright (c) 2013 Philippe Creux
2
+
3
+ MIT License
2
4
 
3
5
  Permission is hereby granted, free of charge, to any person obtaining
4
6
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -1,16 +1,18 @@
1
1
  = rspec-set
2
2
 
3
- <tt>#set</tt> is a little helper for RSpec to speed-up your specs.
3
+ <tt>#set</tt> is a little RSpec helper that speeds-up drastically integration tests that relies on active record objects.
4
4
 
5
- <tt>#set</tt> can be used as a replacement of <tt>#let</tt>: <tt>#set</tt> will create the resource <tt>before(:all)</tt> your examples and will reload the resource <tt>before(:each)</tt> example.
5
+ <tt>#set</tt> takes advantage of the fact that RSpec rails runs each examples in SQL transactions.
6
+ Since all the changes made to the database are rolledback after each example we can create an active record object before all examples
7
+ and use it in each examples without any collisions as long as we reload the object from the database before each example.
6
8
 
7
- <tt>#let</tt> on the other hand creates the resource for every single example.
9
+ <tt>#set</tt> can be used as a replacement of <tt>#let</tt>: <tt>#set</tt> will create the resource <tt>before(:all)</tt> your examples and will reload the resource <tt>before(:each)</tt> example.
8
10
 
9
11
  You can drastically improve the time spent to run your specs. On an application with 3000 examples we decreased the specs duration by 70%!
10
12
 
11
13
  == Usage
12
14
 
13
- The following code will create a flight before running the examples and reload the flight from the DB before each example.
15
+ The following code will create one (and only one!) flight before running the examples and reload the flight from the DB before each example.
14
16
 
15
17
  require 'spec_helper'
16
18
 
@@ -19,6 +21,10 @@ The following code will create a flight before running the examples and reload t
19
21
  Flight.create!
20
22
  end
21
23
 
24
+ it "should be on_time" do
25
+ flight.should be_on_time
26
+ end
27
+
22
28
  it "should be cancellable" do
23
29
  flight.cancel
24
30
  flight.should be_cancelled
@@ -36,6 +42,8 @@ RSpec wraps each example in an SQL transaction which gets rolled back at the end
36
42
 
37
43
  <tt>#set</tt> creates a flight once before running any example. Each example uses this flight and changes its state. Since RSpec rolls back the SQL transaction, the flight gets back to its initial state before each example. <tt>#set</tt> takes care of reloading the flight from the DB before each example. Examples won't affect each others then.
38
44
 
45
+ You can find more examples in https://github.com/pcreux/rspec-set/blob/master/features/lib/rspec-set.feature
46
+
39
47
  == Notes
40
48
 
41
49
  * <tt>#set</tt> works only with ActiveRecord objects saved to the DB so far.
@@ -43,13 +51,19 @@ RSpec wraps each example in an SQL transaction which gets rolled back at the end
43
51
  * <tt>#set</tt> does not handle multi-level transactions.
44
52
  * You will have to call <tt>DatabaseCleaner.clean</tt> <tt>before(:all)</tt> specs which rely on having an empty database. <tt>#set</tt> don't clean the database for you.
45
53
 
54
+ == Install
55
+
56
+ Add rspec-set to you Gemfile
57
+
58
+ gem 'rspec-set'
59
+
60
+ and replace calls to <tt>#let</tt> creating active record objects by <tt>#set</tt>.
61
+
46
62
  == TODO
47
63
 
48
- * add cukes
49
- * support non active record objects
50
- * support non saved active record objects
64
+ * support non saved active record objects (changes made to non saved active record objects won't be rolledback after each example)
51
65
  * make <tt>before(:all) running in a transaction - See: http://rhnh.net/2010/10/06/transactional-before-all-with-rspec-and-datamapper
52
- * support multi-level transactions
66
+ * support multi-level transactions (combinations of subcontext with set and changes made in before(:all) leads to weird behaviour sometimes
53
67
 
54
68
 
55
69
  == Contributing to rspec-set
data/Rakefile CHANGED
@@ -1,57 +1 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'rake'
11
-
12
- require 'jeweler'
13
- Jeweler::Tasks.new do |gem|
14
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
- gem.name = "rspec-set"
16
- gem.homepage = "http://github.com/pcreux/rspec-set"
17
- gem.license = "MIT"
18
- gem.summary = %{set() is a helper for RSpec which setup active record
19
- objects before all tests and restore them to there original state
20
- before each test}
21
- gem.description = %{set() is a helper for RSpec which setup active record
22
- objects before all tests and restore them to there original state
23
- before each test}
24
- gem.email = "pcreux@gmail.com"
25
- gem.authors = ["Philippe Creux"]
26
- # Include your dependencies below. Runtime dependencies are required when using your gem,
27
- # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
28
- gem.add_runtime_dependency 'rspec', '>= 2'
29
- # gem.add_development_dependency 'rspec', '> 1.2.3'
30
- end
31
- Jeweler::RubygemsDotOrgTasks.new
32
-
33
- require 'rake/testtask'
34
- Rake::TestTask.new(:test) do |test|
35
- test.libs << 'lib' << 'test'
36
- test.pattern = 'test/**/test_*.rb'
37
- test.verbose = true
38
- end
39
-
40
- require 'rcov/rcovtask'
41
- Rcov::RcovTask.new do |test|
42
- test.libs << 'test'
43
- test.pattern = 'test/**/test_*.rb'
44
- test.verbose = true
45
- end
46
-
47
- task :default => :test
48
-
49
- require 'rake/rdoctask'
50
- Rake::RDocTask.new do |rdoc|
51
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
52
-
53
- rdoc.rdoc_dir = 'rdoc'
54
- rdoc.title = "rspec-set #{version}"
55
- rdoc.rdoc_files.include('README*')
56
- rdoc.rdoc_files.include('lib/**/*.rb')
57
- end
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,118 @@
1
+ Feature: set
2
+
3
+ As a rails developer willing to speed-up my integration tests
4
+ In order to take advantage of examples running in transactions
5
+ I want to use #set that store the data before all example and
6
+ reload active record objects before each examples
7
+
8
+ Scenario: Examples run in transactions (no side effects between examples)
9
+ Given a file named "spec/models/widget_spec.rb" with:
10
+ """
11
+ require "spec_helper"
12
+
13
+ describe Widget do
14
+ set(:widget) { Widget.create!(:name => 'widget_1') }
15
+
16
+ subject { widget }
17
+
18
+ context "when name is changed to 'widget_2" do
19
+ before do
20
+ widget.update_attributes!(:name => 'widget_2')
21
+ end
22
+
23
+ its(:name) { should == 'widget_2' }
24
+ end
25
+
26
+ context "when name is 'widget_1" do
27
+ its(:name) { should == 'widget_1' }
28
+ end
29
+ end
30
+ """
31
+ When I run "rspec spec/models/widget_spec.rb"
32
+ Then the examples should all pass
33
+
34
+ Scenario: We can use sub sub contexts just fine
35
+ Given a file named "spec/models/widget_spec.rb" with:
36
+ """
37
+ require "spec_helper"
38
+
39
+ describe Widget do
40
+ set(:widget) { Widget.create(:name => 'apple') }
41
+
42
+ subject { widget }
43
+
44
+ context "when name is changed to 'banana" do
45
+ before do
46
+ widget.update_attributes!(:name => 'banana')
47
+ end
48
+
49
+ its(:name) { should == 'banana' }
50
+
51
+ context "when we append ' is good'" do
52
+ before do
53
+ widget.name << ' is good'
54
+ widget.save!
55
+ end
56
+
57
+ its(:name) { should == 'banana is good' }
58
+ end
59
+
60
+ context "when we append ' is bad'" do
61
+ before do
62
+ widget.name << ' is bad'
63
+ widget.save!
64
+ end
65
+
66
+ its(:name) { should == 'banana is bad' }
67
+
68
+ context "when we append ' for you'" do
69
+ before do
70
+ widget.name << ' for you'
71
+ widget.save!
72
+ end
73
+
74
+ its(:name) { should == 'banana is bad for you' }
75
+ end
76
+ end
77
+ end
78
+
79
+ context "when name is 'apple" do
80
+ its(:name) { should == 'apple' }
81
+ end
82
+ end
83
+ """
84
+ When I run "rspec spec/models/widget_spec.rb"
85
+ Then the examples should all pass
86
+
87
+
88
+ Scenario: I can delete an object, it will be available in the next example.
89
+ Given a file named "spec/models/widget_spec.rb" with:
90
+ """
91
+ require "spec_helper"
92
+
93
+ describe Widget do
94
+ set(:widget) { Widget.create(:name => 'apple') }
95
+
96
+ subject { widget }
97
+
98
+ context "when I destroy the widget" do
99
+ before do
100
+ widget.destroy
101
+ end
102
+
103
+ it "should be destroyed" do
104
+ Widget.find_by_id(widget.id).should be_nil
105
+ end
106
+ end
107
+
108
+ context "when name is 'apple" do
109
+ its(:name) { should == 'apple' }
110
+ end
111
+ end
112
+ """
113
+ When I run "rspec spec/models/widget_spec.rb"
114
+ Then the examples should all pass
115
+
116
+ Scenario: I can update a model in a before block
117
+
118
+ Scenario: I can use a set model in another set definition
data/lib/rspec-set.rb CHANGED
@@ -1,6 +1,8 @@
1
+ require "version"
2
+
1
3
  module RSpec
2
4
  module Core
3
- module Set
5
+ module Set
4
6
  module ClassMethods
5
7
  # Set @variable_name in a before(:all) block and give access to it
6
8
  # via let(:variable_name)
@@ -15,16 +17,29 @@ module RSpec
15
17
  #
16
18
  def set(variable_name, &block)
17
19
  before(:all) do
18
- self.class.send(:class_variable_set, "@@#{variable_name}".to_sym, instance_eval(&block))
20
+ # Create model
21
+ self.class.send(:class_variable_set, "@@__rspec_set_#{variable_name}".to_sym, instance_eval(&block))
19
22
  end
20
-
21
- let(variable_name) do
22
- self.class.send(:class_variable_get, "@@#{variable_name}".to_sym).tap do |i|
23
- if i.respond_to?(:new_record?) && i.respond_to?(:reload)
24
- i.reload unless i.new_record?
23
+
24
+ before(:each) do
25
+ model = send(variable_name)
26
+
27
+ if model.is_a?(ActiveRecord::Base)
28
+ if model.destroyed?
29
+ # Relig destroyed model
30
+ model.class.find(i.id)
31
+ elsif !model.new_record?
32
+ # Reload saved model
33
+ model.reload
25
34
  end
35
+ else
36
+ warn "#{variable_name} is a #{model.class} - rspec-set works with ActiveRecord models only"
26
37
  end
27
38
  end
39
+
40
+ define_method(variable_name) do
41
+ self.class.send(:class_variable_get, "@@__rspec_set_#{variable_name}".to_sym)
42
+ end
28
43
  end # set()
29
44
 
30
45
  end # ClassMethods
@@ -35,7 +50,7 @@ module RSpec
35
50
  end # Set
36
51
 
37
52
  class ExampleGroup
38
- include Set
53
+ include Set
39
54
  end # ExampleGroup
40
55
 
41
56
  end # Core
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Rspec
2
+ module Set
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
data/rspec-set.gemspec CHANGED
@@ -1,63 +1,25 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = %q{rspec-set}
8
- s.version = "0.0.1"
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-set"
8
+ spec.version = Rspec::Set::VERSION
9
+ spec.authors = ["Philippe Creux"]
10
+ spec.email = ["pcreux@gmail.com"]
11
+ spec.description = "#set(), speed-up your specs"
12
+ spec.summary = "#set() is a helper for RSpec which setup active record
13
+ objects before all tests and restore them to there original state
14
+ before each test"
15
+ spec.homepage = "http://github.com/pcreux/rspec-set"
16
+ spec.license = "MIT"
9
17
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Philippe Creux"]
12
- s.date = %q{2011-02-04}
13
- s.description = %q{set() is a helper for RSpec which setup active record
14
- objects before all tests and restore them to there original state
15
- before each test}
16
- s.email = %q{pcreux@gmail.com}
17
- s.extra_rdoc_files = [
18
- "LICENSE.txt",
19
- "README.rdoc"
20
- ]
21
- s.files = [
22
- ".document",
23
- "Gemfile",
24
- "Gemfile.lock",
25
- "LICENSE.txt",
26
- "README.rdoc",
27
- "Rakefile",
28
- "VERSION",
29
- "lib/rspec-set.rb",
30
- "rspec-set.gemspec"
31
- ]
32
- s.homepage = %q{http://github.com/pcreux/rspec-set}
33
- s.licenses = ["MIT"]
34
- s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.7}
36
- s.summary = %q{set() is a helper for RSpec which setup active record objects before all tests and restore them to there original state before each test}
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
37
22
 
38
- if s.respond_to? :specification_version then
39
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
40
- s.specification_version = 3
41
-
42
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
- s.add_development_dependency(%q<shoulda>, [">= 0"])
44
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
45
- s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
46
- s.add_development_dependency(%q<rcov>, [">= 0"])
47
- s.add_runtime_dependency(%q<rspec>, [">= 2"])
48
- else
49
- s.add_dependency(%q<shoulda>, [">= 0"])
50
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
51
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
52
- s.add_dependency(%q<rcov>, [">= 0"])
53
- s.add_dependency(%q<rspec>, [">= 2"])
54
- end
55
- else
56
- s.add_dependency(%q<shoulda>, [">= 0"])
57
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
58
- s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
59
- s.add_dependency(%q<rcov>, [">= 0"])
60
- s.add_dependency(%q<rspec>, [">= 2"])
61
- end
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
62
25
  end
63
-
metadata CHANGED
@@ -1,152 +1,85 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rspec-set
3
- version: !ruby/object:Gem::Version
4
- hash: 29
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Philippe Creux
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-02-04 00:00:00 -08:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
22
- prerelease: false
23
- type: :development
24
- name: shoulda
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
26
- none: false
27
- requirements:
28
- - - ">="
29
- - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 0
33
- version: "0"
34
- requirement: *id001
35
- - !ruby/object:Gem::Dependency
36
- prerelease: false
37
- type: :development
12
+ date: 2013-07-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
38
15
  name: bundler
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
16
+ requirement: &70356762024000 !ruby/object:Gem::Requirement
40
17
  none: false
41
- requirements:
18
+ requirements:
42
19
  - - ~>
43
- - !ruby/object:Gem::Version
44
- hash: 23
45
- segments:
46
- - 1
47
- - 0
48
- - 0
49
- version: 1.0.0
50
- requirement: *id002
51
- - !ruby/object:Gem::Dependency
52
- prerelease: false
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
53
22
  type: :development
54
- name: jeweler
55
- version_requirements: &id003 !ruby/object:Gem::Requirement
56
- none: false
57
- requirements:
58
- - - ~>
59
- - !ruby/object:Gem::Version
60
- hash: 1
61
- segments:
62
- - 1
63
- - 5
64
- - 1
65
- version: 1.5.1
66
- requirement: *id003
67
- - !ruby/object:Gem::Dependency
68
23
  prerelease: false
69
- type: :development
70
- name: rcov
71
- version_requirements: &id004 !ruby/object:Gem::Requirement
24
+ version_requirements: *70356762024000
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70356762019460 !ruby/object:Gem::Requirement
72
28
  none: false
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- hash: 3
77
- segments:
78
- - 0
79
- version: "0"
80
- requirement: *id004
81
- - !ruby/object:Gem::Dependency
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
82
34
  prerelease: false
83
- type: :runtime
84
- name: rspec
85
- version_requirements: &id005 !ruby/object:Gem::Requirement
86
- none: false
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- hash: 7
91
- segments:
92
- - 2
93
- version: "2"
94
- requirement: *id005
95
- description: |-
96
- set() is a helper for RSpec which setup active record
97
- objects before all tests and restore them to there original state
98
- before each test
99
- email: pcreux@gmail.com
35
+ version_requirements: *70356762019460
36
+ description: ! '#set(), speed-up your specs'
37
+ email:
38
+ - pcreux@gmail.com
100
39
  executables: []
101
-
102
40
  extensions: []
103
-
104
- extra_rdoc_files:
105
- - LICENSE.txt
106
- - README.rdoc
107
- files:
108
- - .document
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
109
44
  - Gemfile
110
- - Gemfile.lock
111
45
  - LICENSE.txt
112
46
  - README.rdoc
113
47
  - Rakefile
114
- - VERSION
48
+ - features/rspec-set.feature
115
49
  - lib/rspec-set.rb
50
+ - lib/version.rb
116
51
  - rspec-set.gemspec
117
- has_rdoc: true
118
52
  homepage: http://github.com/pcreux/rspec-set
119
- licenses:
53
+ licenses:
120
54
  - MIT
121
55
  post_install_message:
122
56
  rdoc_options: []
123
-
124
- require_paths:
57
+ require_paths:
125
58
  - lib
126
- required_ruby_version: !ruby/object:Gem::Requirement
59
+ required_ruby_version: !ruby/object:Gem::Requirement
127
60
  none: false
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- hash: 3
132
- segments:
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ segments:
133
66
  - 0
134
- version: "0"
135
- required_rubygems_version: !ruby/object:Gem::Requirement
67
+ hash: -2867062105310348299
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
69
  none: false
137
- requirements:
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- hash: 3
141
- segments:
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ segments:
142
75
  - 0
143
- version: "0"
76
+ hash: -2867062105310348299
144
77
  requirements: []
145
-
146
78
  rubyforge_project:
147
- rubygems_version: 1.3.7
79
+ rubygems_version: 1.8.11
148
80
  signing_key:
149
81
  specification_version: 3
150
- summary: set() is a helper for RSpec which setup active record objects before all tests and restore them to there original state before each test
151
- test_files: []
152
-
82
+ summary: ! '#set() is a helper for RSpec which setup active record objects before
83
+ all tests and restore them to there original state before each test'
84
+ test_files:
85
+ - features/rspec-set.feature
data/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/Gemfile.lock DELETED
@@ -1,20 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- git (1.2.5)
5
- jeweler (1.5.1)
6
- bundler (~> 1.0.0)
7
- git (>= 1.2.5)
8
- rake
9
- rake (0.8.7)
10
- rcov (0.9.9)
11
- shoulda (2.11.3)
12
-
13
- PLATFORMS
14
- ruby
15
-
16
- DEPENDENCIES
17
- bundler (~> 1.0.0)
18
- jeweler (~> 1.5.1)
19
- rcov
20
- shoulda
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.1