rspec_for_generators 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,65 +1,102 @@
1
1
  # RSpec 2 library for specifying and testing generators
2
2
 
3
- RSpec 2 matchers, helpers and various utilities to assist in writing generator specs especially Rails 3 generators.
3
+ This project contains RSpec 2 matchers, helpers and various utilities to assist in writing Rails 3 generator specs.
4
4
 
5
- This project was extracted from my experiments with creating generators for jnunemaker's *Canable*, see [My fork of Canable](http://github.com/kristianmandrup/canable).
5
+ Rails 3 has a Rails::Generators::TestCase class for use with Test-Unit, to help test generators, containing specific assertion methods that can be used to assert generator behavior. Theres was no RSpec 2 equivalent, so I wrapped Rails::Generators::TestCase for use with RSpec 2 and created some RSpec 2 matchers that mimic the assertion methods
6
+ of TestCase and also added some extra goodies to the mix. It should now be pretty easy to test your Rails 3 generators with RSpec 2 :)
6
7
 
7
- I attempted to test the generators I built but I noticed, that the only option I could find, was to use a special Rails TestCase class created for Test-Unit.
8
- So I thought I could wrap it to be used with RSpec 2; my BDD testing framework of choice!
8
+ Please advice if you find any issues or have suggestions for improvements. The code is not as pretty as it could be, so feel free to refactor and improve it to your hearts desire!
9
9
 
10
10
  ## Install
11
11
 
12
12
  <code>gem install rspec_for_generators</code>
13
13
 
14
- To install using edge
14
+ The gem is a jewel (using jeweler), so to install the gem from the code - simply use the jeweler rake task:
15
15
 
16
16
  <code>rake install</code>
17
17
 
18
18
  ## Usage
19
19
 
20
- The following demonstrates an example usage. There are many more options and cool DSL convenience methods. Check out the code!
20
+ The following demonstrates an example usage. There are many more options and DSL convenience methods.
21
21
 
22
- ### spec/spec_helper.rb
22
+ ### Configuration
23
23
 
24
- <pre>require 'rspec'
24
+ First setup the *spec_helper.rb*. Here is an example configuration.
25
25
 
26
- # The following somewhat ugly 'hack' is currently required for rails_spec_helper.rb to work.
27
- # It's the relative root for which the Rails mock app is created.
28
- # So if it's set to point to the spec folder, then the temporary rails application
29
- # will be generated in ../tmp, relative to the folder of this file : File.dirname(__FILE__)
30
- # Thus in this example the /tmp folder will be in the current project root.
26
+ <pre># spec/spec_helper.rb
27
+
28
+ require 'rspec'
29
+ require 'rspec_for_generators'
31
30
 
32
- # Note: In the near future I will provide a better way to achieve this, by hooking into the Rails 3 loading
33
- # behavior as described in a *Rails Dispatch* article by *wycatz*
31
+ Rails.application.configure do
32
+ # use default rails tmp dir
33
+ config.root_dir = TmpRails.root_dir(__FILE__)
34
+
35
+ # or specify custom rails tmp dir
36
+ # config.root_dir = TmpRails.root_dir(File.dirname(__FILE__) + '/../tmp', :custom)
37
+ end
34
38
 
35
- module Rails
36
- def config_root_dir
37
- File.dirname(__FILE__)
38
- end
39
- end
39
+ # configure it!
40
+ RSpec::Generator.configure!
41
+ </pre>
40
42
 
41
- # load this rspec toolbox to help spec generators
42
- require 'rspec_for_generators'</pre>
43
+ ### Specs for generators
43
44
 
44
- ### spec/generators/canable.rb
45
+ I recommend having a separate spec for each generator. A generator spec can include *this* file to ensure all generators are loaded.
46
+ Put a *require_generator* statement in each spec file, to ensure that particular generator is loaded and thus available for the spec.
47
+
48
+ <pre>require_generator :canable</pre>
49
+
50
+ This will load the generator : `generators/canabale_generator.rb`
51
+
52
+ If the generator is namespaced, use a nested approach like so:
45
53
 
46
- Convenience way to define which generators to require
47
-
48
54
  <pre>require_generators :canable => ['model', 'user']</pre>
49
55
 
50
- ### spec/generators/model_generator_spec.rb
56
+ This will load the generators: `generators/canable/model_generator.rb` and `generators/canable/user_generator.rb`
57
+
58
+ If you have multiple generators in a shared namespace, the following approach can be used.
59
+ Create a file that loads all the generators in the namespace. Include this file for each spec that tests a particular generator in that namespace:
60
+
61
+ <pre># spec/generators/canable.rb
62
+ require_generators :canable => ['model', 'user']</pre>
63
+
64
+ <pre># spec/generators/canable/model_generator_spec.rb
65
+ ...
66
+ # load generators to spec
67
+ require 'generators/canable'
68
+
69
+ describe 'model_generator' do
70
+ ...
71
+ end
72
+ </pre>
73
+
74
+ <pre># spec/generators/canable/user_generator_spec.rb
75
+ ...
76
+ # load generators to spec
77
+ require 'generators/canable'
78
+
79
+ describe 'user_generator' do
80
+ ...
81
+ end
82
+ </pre>
83
+
84
+
85
+
86
+ ### Example of full generator spec
87
+
88
+ <pre># spec/generators/model_generator_spec.rb
51
89
 
52
- <pre>require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
90
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
53
91
 
54
92
  # list of generators to spec are loaded
55
93
  require 'generators/canable'
56
94
 
57
95
  describe 'model_generator' do
58
- # include Rails model helpers for AciveRecord
59
- # also available are: MongoMapper, Mongoid and DataMapper
60
- # mongo_mapper, :data_mapper, :mongoid
96
+ # include Rails model helpers for ActiveRecord
97
+ # available: MongoMapper, Mongoid and DataMapper
61
98
 
62
- model_helper_for :active_record
99
+ include RSpec::Rails::Orm::ActiveRecord
63
100
 
64
101
  before :each do
65
102
  # define generator to test
@@ -89,7 +126,7 @@ describe 'model_generator' do
89
126
  create_model name
90
127
  g.run_generator %w{account}
91
128
  g.should generate_file name, :model do |content|
92
- content.should have_class name.camelize do |klass|
129
+ content.should have_class name do |klass|
93
130
  klass.should include_module 'Canable::Ables'
94
131
  end
95
132
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -37,7 +37,7 @@ class DemoGenerator < Rails::Generators::Base
37
37
  end
38
38
 
39
39
  def model_class_name
40
- name.camelize
40
+ name.to_s.camelize
41
41
  end
42
42
 
43
43
  def model_file_name
@@ -1,2 +1,2 @@
1
- TestApp.routes.draw do |map|
1
+ Rails.application.routes.draw do |map|
2
2
  end
@@ -8,8 +8,6 @@ require 'rspec_for_generators/rails_spec_helper'
8
8
  # Call configure to load the settings from
9
9
  # Rails.application.config.generators to Rails::Generators
10
10
 
11
- Rails::Generators.configure!
12
-
13
11
  # require the generators
14
12
  def require_generators *generator_list
15
13
  generator_list.each do |name, generators|
@@ -21,13 +19,29 @@ def require_generators *generator_list
21
19
  end
22
20
  end
23
21
  end
24
- end
22
+ end
23
+ alias :require_generator :require_generators
25
24
 
26
25
  module RSpec
27
26
  module Generator
28
27
  class << self
29
28
  attr_accessor :generator, :test_method_name
30
29
 
30
+ def remove_rails_dir!
31
+ FileUtils.rm_rf ::TmpRails.root
32
+ end
33
+
34
+ def configure!
35
+ ::RSpec::Generators::TestCase.destination ::Rails.root
36
+ ::Rails::Generators.configure!
37
+
38
+ ::RSpec.configure do |config|
39
+ config.after(:suite) do
40
+ ::RSpec::Generator.remove_rails_dir!
41
+ end
42
+ end
43
+ end
44
+
31
45
  def run_generator *args, &block
32
46
  generator.run_generator *args
33
47
  if block
@@ -5,7 +5,7 @@ module RSpec
5
5
  attr_reader :klass
6
6
 
7
7
  def initialize(klass)
8
- @klass = klass
8
+ @klass = klass.to_s.camelize
9
9
  end
10
10
 
11
11
  def matches?(content)
@@ -13,7 +13,7 @@ module RSpec
13
13
 
14
14
  def initialize(method, type)
15
15
  @type = type
16
- @method = method
16
+ @method = method.to_s
17
17
  end
18
18
 
19
19
  def matches?(content)
@@ -9,7 +9,7 @@ module RSpec
9
9
  end
10
10
 
11
11
  def matches?(module_name)
12
- @module_name = module_name
12
+ @module_name = module_name.to_s.camelize
13
13
  @content =~ /module\s+#{@module_name}\s+(.*)end/m
14
14
  if block_given?
15
15
  ruby_content = $2.strip.extend(RSpec::RubyContent::Helpers)
@@ -5,7 +5,7 @@ module RSpec
5
5
  attr_reader :module_name
6
6
 
7
7
  def initialize module_name
8
- @module_name = module_name
8
+ @module_name = module_name.to_s.camelize
9
9
  end
10
10
 
11
11
  def matches?(content)
@@ -5,7 +5,7 @@ module RSpec
5
5
  attr_reader :klass
6
6
 
7
7
  def initialize(content)
8
- @klass = klass
8
+ @klass = klass.to_s.camelize
9
9
  end
10
10
 
11
11
  def matches?(content)
@@ -15,7 +15,7 @@ module RSpec
15
15
 
16
16
  def check_model(name, clazz, options = {})
17
17
  self.should generate_file("#{name.underscore}.rb", :model) do |file_content|
18
- file_content.should have_class clazz.camelize do |content|
18
+ file_content.should have_class clazz do |content|
19
19
  check_matchings options[:matchings]
20
20
  check_methods(options[:methods])
21
21
  check_class_methods(options[:class_methods])
@@ -1,5 +1,5 @@
1
1
  require 'rspec_for_generators/rails_helpers/rails_app'
2
- require 'rspec_for_generators/rails_helpers/rails_model'
2
+ require 'rspec_for_generators/rails_helpers/rails_orm'
3
3
  require 'rspec_for_generators/rails_helpers/rails_controller'
4
4
  require 'rspec_for_generators/rails_helpers/rails_helper'
5
5
  require 'rspec_for_generators/rails_helpers/rails_view'
@@ -12,7 +12,7 @@ module RSpec
12
12
  end
13
13
 
14
14
  def controller_content name
15
- %Q{class #{name.camelize}Controller < ActionController::Base
15
+ %Q{class #{name.to_s.camelize}Controller < ActionController::Base
16
16
  end}
17
17
  end
18
18
 
@@ -12,7 +12,7 @@ module RSpec
12
12
  end
13
13
 
14
14
  def helper_content name
15
- %Q{class #{name.camelize}Helper
15
+ %Q{class #{name.to_s.camelize}Helper
16
16
  end}
17
17
  end
18
18
 
@@ -1,94 +1,29 @@
1
- module RSpec
2
- module Rails
3
- module Model
4
- module ActiveRecord
5
- def file_content name
6
- %Q{class #{name.camelize} < ActiveRecord::Base
7
- end}
8
- end
9
- end
10
-
11
- module MongoMapper
12
- def file_content name
13
- %Q{class #{name.camelize}
14
- include MongoMapper::Document
15
- end}
16
- end
17
-
18
- def field name, type = nil
19
- return "key :#{name}, #{type}" if type
20
- "key :#{name}"
21
- end
22
- end
23
-
24
- module Mongoid
25
- def file_content name
26
- %Q{class #{name.camelize}
27
- include Mongoid::Document
28
- end}
29
- end
30
-
31
- def field name, type = nil
32
- return "field :#{name}, :type => #{type}" if type
33
- "field :#{name}"
34
- end
35
- end
36
-
37
- module DataMapper
38
- def file_content name
39
- %Q{class #{name.camelize}
40
- include DataMapper::Resource
41
- end}
42
- end
43
-
44
- def field name, type = nil
45
- return "property :#{name}, #{type}" if type
46
- "property :#{name}"
47
- end
48
- end
49
-
50
- def set_orm orm
51
- orm_module = case orm
52
- when :active_record
53
- ActiveRecord
54
- when :data_mapper
55
- DataMapper
56
- when :mongo_mapper
57
- MongoMapper
58
- when :mongoid
59
- Mongoid
60
- end
61
- include orm_module
62
- end
1
+ module RSpec::Rails
2
+ module Model
3
+ def create_model name, &block
4
+ puts "create_model: #{name}"
63
5
 
64
- def create_model name, &block
65
- file = model_file_name(name)
66
- unless File.exist?(file)
67
- FileUtils.mkdir_p File.dirname(file)
68
- File.open(file, 'w') do |f|
69
- f.puts file_content(name)
70
- yield f if block_given?
71
- end
6
+ file = model_file_name(name)
7
+ unless File.exist?(file)
8
+ FileUtils.mkdir_p File.dirname(file)
9
+ File.open(file, 'w') do |f|
10
+ f.puts file_content(name)
11
+ yield f if block_given?
72
12
  end
73
- end
74
-
75
- def remove_model name
76
- file = model_file_name(name)
77
- FileUtils.rm_f(file) if File.exist?(file)
78
13
  end
14
+ end
79
15
 
80
- def remove_models *names
81
- names.each{|name| remove_model name }
82
- end
83
-
84
- def model_file_name name
85
- File.join(::Rails.root, "app/models/#{name}.rb")
86
- end
16
+ def remove_model name
17
+ file = model_file_name(name)
18
+ FileUtils.rm_f(file) if File.exist?(file)
87
19
  end
88
- end
89
- end
90
20
 
91
- def model_helper_for orm
92
- include RSpec::Rails::Model
93
- set_orm orm
21
+ def remove_models *names
22
+ names.each{|name| remove_model name }
23
+ end
24
+
25
+ def model_file_name name
26
+ File.join(::Rails.root, "app/models/#{name}.rb")
27
+ end
28
+ end
94
29
  end
@@ -0,0 +1,77 @@
1
+ require 'rspec_for_generators/rails_helpers/rails_model'
2
+
3
+ module RSpec::Rails
4
+ module Orm
5
+ module Base
6
+ include RSpec::Rails::Model
7
+
8
+ protected
9
+
10
+ def clazz name
11
+ "class #{name.to_s.camelize}"
12
+ end
13
+
14
+ def file name
15
+ %Q{#{clazz name}
16
+ #{yield if block_given?}
17
+ end}
18
+ end
19
+
20
+ def file_w_include name
21
+ file name { "include #{yield}" if block_given?}
22
+ end
23
+
24
+ def file_w_inherit name
25
+ %Q{#{clazz name} < #{yield if block_given?}
26
+ end}
27
+ end
28
+ end
29
+
30
+ module ActiveRecord
31
+ include RSpec::Rails::Orm::Base
32
+
33
+ def file_content(name)
34
+ file_w_inherit(name) {'ActiveRecord::Base'}
35
+ end
36
+ end
37
+
38
+ module MongoMapper
39
+ include RSpec::Rails::Orm::Base
40
+
41
+ def file_content name
42
+ file_w_include(name) { 'MongoMapper::Document' }
43
+ end
44
+
45
+ def field name, type = nil
46
+ return "key :#{name}, #{type}" if type
47
+ "key :#{name}"
48
+ end
49
+ end
50
+
51
+ module Mongoid
52
+ include RSpec::Rails::Orm::Base
53
+
54
+ def file_content name
55
+ file_w_include(name) { 'Mongoid::Document' }
56
+ end
57
+
58
+ def field name, type = nil
59
+ return "field :#{name}, :type => #{type}" if type
60
+ "field :#{name}"
61
+ end
62
+ end
63
+
64
+ module DataMapper
65
+ include RSpec::Rails::Orm::Base
66
+
67
+ def file_content name
68
+ file_w_include(name) { 'DataMapper::Resource' }
69
+ end
70
+
71
+ def field name, type = nil
72
+ return "property :#{name}, #{type}" if type
73
+ "property :#{name}"
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,17 +1,35 @@
1
1
  require 'rspec_for_generators/rails_helpers/all'
2
2
 
3
- class TestApp < Rails::Application
4
- raise StandardError, "You must define a location for Rails.config_root_dir" if !Rails.config_root_dir
5
- config.root = Rails.config_root_dir
6
- end
3
+ module TmpRails
4
+ class << self
5
+ attr_accessor :root
6
+
7
+ def root_dir path, options = {}
8
+ @root = options == :custom ? custom_root_dir(path) : default_root_dir(path)
9
+ end
10
+
11
+ protected
12
+
13
+ def default_root_dir path
14
+ File.expand_path(File.join(File.dirname(path), '..', 'tmp'))
15
+ end
7
16
 
17
+ def custom_root_dir path
18
+ File.expand_path(path)
19
+ end
20
+ end
21
+ end
22
+
8
23
  module Rails
9
24
  def self.root
10
- raise StandardError, "You must define a location for Rails.config_root_dir" if !Rails.config_root_dir
11
- @root ||= File.expand_path(File.join(Rails.config_root_dir, '..', 'tmp', 'rails'))
25
+ # raise StandardError, "You must define a location for Rails.config_root_dir" if !Rails.config_root_dir
26
+ # @root ||= File.expand_path(File.join(Rails.config_root_dir, '..', 'tmp', 'rails'))
27
+ @root ||= File.join(Rails.application.config.root_dir, 'rails')
12
28
  end
13
29
  end
14
30
 
31
+ class TestApp < Rails::Application
32
+ end
33
+
15
34
  Rails.application = TestApp
16
- Rails.application.config.root = Rails.root
17
35
 
@@ -3,7 +3,7 @@ module RSpec
3
3
  class TestCase < ::Rails::Generators::TestCase
4
4
  setup :prepare_destination
5
5
  # setup :copy_routes
6
- destination File.join(::Rails.root)
6
+
7
7
 
8
8
  def initialize(test_method_name)
9
9
  @method_name = test_method_name
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rspec_for_generators}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kristian Mandrup"]
12
- s.date = %q{2010-08-03}
12
+ s.date = %q{2010-08-04}
13
13
  s.description = %q{RSpec 2 matchers, helpers and utils to assist in writing generator specs}
14
14
  s.email = %q{kmandrup@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
45
45
  "lib/rspec_for_generators/rails_helpers/rails_helper.rb",
46
46
  "lib/rspec_for_generators/rails_helpers/rails_mailer.rb",
47
47
  "lib/rspec_for_generators/rails_helpers/rails_model.rb",
48
+ "lib/rspec_for_generators/rails_helpers/rails_orm.rb",
48
49
  "lib/rspec_for_generators/rails_helpers/rails_view.rb",
49
50
  "lib/rspec_for_generators/rails_spec_helper.rb",
50
51
  "lib/rspec_for_generators/rspec_test_case.rb",
@@ -52,7 +53,6 @@ Gem::Specification.new do |s|
52
53
  "spec/rspec_for_generators/rspec_for_generators_spec.rb",
53
54
  "spec/spec.opts",
54
55
  "spec/spec_helper.rb",
55
- "tmp/rails/config/routes.rb",
56
56
  "wiki/Custom Rails 3 Generators.textile"
57
57
  ]
58
58
  s.homepage = %q{http://github.com/kristianmandrup/rspec_for_generators}
@@ -1,9 +1,8 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
- require_generators :demo
2
+ require_generator :demo
3
3
 
4
4
  describe 'model_generator' do
5
- include RSpec::Rails::Model
6
- include RSpec::Rails::Model::ActiveRecord
5
+ include RSpec::Rails::Orm::ActiveRecord
7
6
 
8
7
  before :each do
9
8
  RSpec::Generator.setup_generator 'model_generator' do
@@ -30,7 +29,7 @@ describe 'model_generator' do
30
29
  create_model name
31
30
  g.run_generator %w{account}
32
31
  g.should generate_file name, :model do |content|
33
- content.should have_class name.camelize do |klass|
32
+ content.should have_class name do |klass|
34
33
  klass.should include_module 'Canable::Ables'
35
34
  end
36
35
  end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  require 'rspec'
2
2
  require 'rspec/autorun'
3
+ require 'rspec_for_generators'
3
4
 
4
- module Rails
5
- def self.config_root_dir
6
- File.dirname(__FILE__)
7
- end
5
+ Rails.application.configure do
6
+ # config.root_dir = TmpRails.root_dir(__FILE__)
7
+ config.root_dir = TmpRails.root_dir(File.dirname(__FILE__) + '/../tmp', :custom)
8
8
  end
9
9
 
10
- require 'rspec_for_generators'
10
+ RSpec::Generator.configure!
11
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Kristian Mandrup
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-08-03 00:00:00 +02:00
17
+ date: 2010-08-04 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -149,6 +149,7 @@ files:
149
149
  - lib/rspec_for_generators/rails_helpers/rails_helper.rb
150
150
  - lib/rspec_for_generators/rails_helpers/rails_mailer.rb
151
151
  - lib/rspec_for_generators/rails_helpers/rails_model.rb
152
+ - lib/rspec_for_generators/rails_helpers/rails_orm.rb
152
153
  - lib/rspec_for_generators/rails_helpers/rails_view.rb
153
154
  - lib/rspec_for_generators/rails_spec_helper.rb
154
155
  - lib/rspec_for_generators/rspec_test_case.rb
@@ -156,7 +157,6 @@ files:
156
157
  - spec/rspec_for_generators/rspec_for_generators_spec.rb
157
158
  - spec/spec.opts
158
159
  - spec/spec_helper.rb
159
- - tmp/rails/config/routes.rb
160
160
  - wiki/Custom Rails 3 Generators.textile
161
161
  has_rdoc: true
162
162
  homepage: http://github.com/kristianmandrup/rspec_for_generators
@@ -1,2 +0,0 @@
1
- TestApp.routes.draw do |map|
2
- end