generator-spec 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +144 -0
  5. data/Rakefile +48 -0
  6. data/VERSION +1 -0
  7. data/generator-spec.gemspec +106 -0
  8. data/lib/generators/demo/demo_generator.rb +91 -0
  9. data/lib/rspec_for_generators.rb +11 -0
  10. data/lib/rspec_for_generators/fixtures/routes.rb +2 -0
  11. data/lib/rspec_for_generators/generator_spec_helper.rb +95 -0
  12. data/lib/rspec_for_generators/main.rb +18 -0
  13. data/lib/rspec_for_generators/matchers/content/have_block.rb +47 -0
  14. data/lib/rspec_for_generators/matchers/content/have_call.rb +42 -0
  15. data/lib/rspec_for_generators/matchers/content/have_class.rb +32 -0
  16. data/lib/rspec_for_generators/matchers/content/have_method.rb +41 -0
  17. data/lib/rspec_for_generators/matchers/content/have_module.rb +32 -0
  18. data/lib/rspec_for_generators/matchers/content/include_module.rb +32 -0
  19. data/lib/rspec_for_generators/matchers/content/inherit_from.rb +31 -0
  20. data/lib/rspec_for_generators/matchers/file/generate_directory.rb +71 -0
  21. data/lib/rspec_for_generators/matchers/file/generate_file.rb +71 -0
  22. data/lib/rspec_for_generators/matchers/file/generate_migration.rb +50 -0
  23. data/lib/rspec_for_generators/matchers/helpers/content.rb +18 -0
  24. data/lib/rspec_for_generators/matchers/helpers/file.rb +26 -0
  25. data/lib/rspec_for_generators/matchers/helpers/migration.rb +102 -0
  26. data/lib/rspec_for_generators/matchers/migration/have_column.rb +13 -0
  27. data/lib/rspec_for_generators/matchers/migration/have_index.rb +9 -0
  28. data/lib/rspec_for_generators/matchers/migration/have_migration.rb +5 -0
  29. data/lib/rspec_for_generators/matchers/migration/have_table.rb +18 -0
  30. data/lib/rspec_for_generators/matchers/migration/have_tbl_column.rb +25 -0
  31. data/lib/rspec_for_generators/matchers/migration/have_up_down.rb +13 -0
  32. data/lib/rspec_for_generators/rails_helpers/all.rb +6 -0
  33. data/lib/rspec_for_generators/rails_helpers/rails_app.rb +53 -0
  34. data/lib/rspec_for_generators/rails_helpers/rails_controller.rb +36 -0
  35. data/lib/rspec_for_generators/rails_helpers/rails_helper.rb +36 -0
  36. data/lib/rspec_for_generators/rails_helpers/rails_mailer.rb +29 -0
  37. data/lib/rspec_for_generators/rails_helpers/rails_model.rb +27 -0
  38. data/lib/rspec_for_generators/rails_helpers/rails_orm.rb +77 -0
  39. data/lib/rspec_for_generators/rails_helpers/rails_view.rb +29 -0
  40. data/lib/rspec_for_generators/rails_spec_helper.rb +35 -0
  41. data/lib/rspec_for_generators/rspec_test_case.rb +26 -0
  42. data/rspec_for_generators.gemspec +96 -0
  43. data/spec/rspec_for_generators/rspec_for_generators_spec.rb +41 -0
  44. data/spec/spec.opts +1 -0
  45. data/spec/spec_helper.rb +6 -0
  46. data/wiki/Custom Rails 3 Generators.textile +110 -0
  47. data/wiki/rails_view_helpers.textile +167 -0
  48. metadata +205 -0
@@ -0,0 +1,36 @@
1
+ module RSpec::Rails
2
+ module Helper
3
+ def create_helper name, content=nil
4
+ file = helper_file_name(name)
5
+ unless File.exist?(file)
6
+ FileUtils.mkdir_p File.dirname(file)
7
+ content ||= yield if block_given?
8
+ File.open(file, 'w') do |f|
9
+ f.puts helper_content(content)
10
+ end
11
+ end
12
+ end
13
+
14
+ def helper_content name, content=nil
15
+ %Q{class #{name.to_s.camelize}Helper
16
+ #{content}
17
+ end}
18
+ end
19
+
20
+ def remove_model name
21
+ file = helper_file_name(name)
22
+ FileUtils.rm_f(file) if File.exist?(file)
23
+ end
24
+
25
+ def remove_helpers *names
26
+ names.each{|name| remove_helper name }
27
+ end
28
+
29
+ protected
30
+
31
+ def helper_file_name name
32
+ File.join(::Rails.root, "app/helpers/#{name}.rb")
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ module RSpec::Rails
2
+ module Mailer
3
+ def create_mailer name, content=nil
4
+ file = mailer_file_name(name)
5
+ unless File.exist?(file)
6
+ FileUtils.mkdir_p File.dirname(file)
7
+ content ||= yield if block_given?
8
+ return if !content
9
+ File.open(file, 'w') do |f|
10
+ f.puts content
11
+ end
12
+ end
13
+ end
14
+
15
+ def remove_mailer name
16
+ file = mailer_file_name(name)
17
+ FileUtils.rm_f(file) if File.exist?(file)
18
+ end
19
+
20
+ def remove_mailers *names
21
+ names.each{|name| remove_mailer name }
22
+ end
23
+
24
+ def mailer_file_name name
25
+ File.join(::Rails.root, "app/mailers/#{name}.rb")
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module RSpec::Rails
2
+ module Model
3
+ def create_model name, &block
4
+ file = model_file_name(name)
5
+ unless File.exist?(file)
6
+ FileUtils.mkdir_p File.dirname(file)
7
+ File.open(file, 'w') do |f|
8
+ f.puts file_content(name)
9
+ yield f if block_given?
10
+ end
11
+ end
12
+ end
13
+
14
+ def remove_model name
15
+ file = model_file_name(name)
16
+ FileUtils.rm_f(file) if File.exist?(file)
17
+ end
18
+
19
+ def remove_models *names
20
+ names.each{|name| remove_model name }
21
+ end
22
+
23
+ def model_file_name name
24
+ File.join(::Rails.root, "app/models/#{name}.rb")
25
+ end
26
+ end
27
+ 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
@@ -0,0 +1,29 @@
1
+ module RSpec::Rails
2
+ module View
3
+ def create_view name, content=nil
4
+ file = view_file_name(name)
5
+ unless File.exist?(file)
6
+ FileUtils.mkdir_p File.dirname(file)
7
+ content ||= yield if block_given?
8
+ return if !content
9
+ File.open(file, 'w') do |f|
10
+ f.puts content
11
+ end
12
+ end
13
+ end
14
+
15
+ def remove_view name
16
+ file = view_file_name(name)
17
+ FileUtils.rm_f(file) if File.exist?(file)
18
+ end
19
+
20
+ def remove_views *names
21
+ names.each{|name| remove_view name }
22
+ end
23
+
24
+ def view_file_name name
25
+ File.join(::Rails.root, "app/views/#{name}.rb")
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ require 'rspec_for_generators/rails_helpers/all'
2
+
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
16
+
17
+ def custom_root_dir path
18
+ File.expand_path(path)
19
+ end
20
+ end
21
+ end
22
+
23
+ module Rails
24
+ def self.root
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')
28
+ end
29
+ end
30
+
31
+ class TestApp < Rails::Application
32
+ end
33
+
34
+ Rails.application = TestApp
35
+
@@ -0,0 +1,26 @@
1
+ module RSpec
2
+ module Generators
3
+ class TestCase < ::Rails::Generators::TestCase
4
+ setup :prepare_destination
5
+ # setup :copy_routes
6
+
7
+
8
+ def initialize(test_method_name)
9
+ @method_name = test_method_name
10
+ @test_passed = true
11
+ @interrupted = false
12
+ routes_file = File.join(File.dirname(__FILE__), 'fixtures', 'routes.rb')
13
+ copy_routes routes_file
14
+ end
15
+
16
+ def copy_routes routes_file
17
+ routes = File.expand_path(routes_file)
18
+ raise ArgumentError, "No routes file exists at #{routes_file}" if !File.exist?(routes)
19
+ destination = File.join(::Rails.root, "config")
20
+ FileUtils.mkdir_p(destination) # create dir
21
+ FileUtils.cp routes, destination # copy
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,96 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rspec_for_generators}
8
+ s.version = "0.3.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = %q{2010-08-04}
13
+ s.description = %q{RSpec 2 matchers, helpers and utils to assist in writing generator specs}
14
+ s.email = %q{kmandrup@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/generators/demo/demo_generator.rb",
27
+ "lib/rspec_for_generators.rb",
28
+ "lib/rspec_for_generators/fixtures/routes.rb",
29
+ "lib/rspec_for_generators/generator_spec_helper.rb",
30
+ "lib/rspec_for_generators/main.rb",
31
+ "lib/rspec_for_generators/matchers/content/all.rb",
32
+ "lib/rspec_for_generators/matchers/content/have_class.rb",
33
+ "lib/rspec_for_generators/matchers/content/have_method.rb",
34
+ "lib/rspec_for_generators/matchers/content/have_module.rb",
35
+ "lib/rspec_for_generators/matchers/content/include_module.rb",
36
+ "lib/rspec_for_generators/matchers/content/inherit_from.rb",
37
+ "lib/rspec_for_generators/matchers/file/all.rb",
38
+ "lib/rspec_for_generators/matchers/file/generate_file.rb",
39
+ "lib/rspec_for_generators/matchers/file/generate_migration.rb",
40
+ "lib/rspec_for_generators/matchers/helpers/content.rb",
41
+ "lib/rspec_for_generators/matchers/helpers/file.rb",
42
+ "lib/rspec_for_generators/rails_helpers/all.rb",
43
+ "lib/rspec_for_generators/rails_helpers/rails_app.rb",
44
+ "lib/rspec_for_generators/rails_helpers/rails_controller.rb",
45
+ "lib/rspec_for_generators/rails_helpers/rails_helper.rb",
46
+ "lib/rspec_for_generators/rails_helpers/rails_mailer.rb",
47
+ "lib/rspec_for_generators/rails_helpers/rails_model.rb",
48
+ "lib/rspec_for_generators/rails_helpers/rails_orm.rb",
49
+ "lib/rspec_for_generators/rails_helpers/rails_view.rb",
50
+ "lib/rspec_for_generators/rails_spec_helper.rb",
51
+ "lib/rspec_for_generators/rspec_test_case.rb",
52
+ "rspec_for_generators.gemspec",
53
+ "spec/rspec_for_generators/rspec_for_generators_spec.rb",
54
+ "spec/spec.opts",
55
+ "spec/spec_helper.rb",
56
+ "wiki/Custom Rails 3 Generators.textile"
57
+ ]
58
+ s.homepage = %q{http://github.com/kristianmandrup/rspec_for_generators}
59
+ s.rdoc_options = ["--charset=UTF-8"]
60
+ s.require_paths = ["lib"]
61
+ s.rubygems_version = %q{1.3.7}
62
+ s.summary = %q{RSpec 2 matchers, helpers and utils for writing generator specs}
63
+ s.test_files = [
64
+ "spec/rspec_for_generators/rspec_for_generators_spec.rb",
65
+ "spec/spec_helper.rb"
66
+ ]
67
+
68
+ if s.respond_to? :specification_version then
69
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
70
+ s.specification_version = 3
71
+
72
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
73
+ s.add_development_dependency(%q<rspec>, [">= 2.0.0.beta19"])
74
+ s.add_runtime_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
75
+ s.add_runtime_dependency(%q<rake>, [">= 0.8.7"])
76
+ s.add_runtime_dependency(%q<rails>, [">= 3.0.0.rc"])
77
+ s.add_runtime_dependency(%q<test-unit>, [">= 2.0.9"])
78
+ s.add_runtime_dependency(%q<require_all>, [">= 1.1.0"])
79
+ else
80
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta19"])
81
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
82
+ s.add_dependency(%q<rake>, [">= 0.8.7"])
83
+ s.add_dependency(%q<rails>, [">= 3.0.0.rc"])
84
+ s.add_dependency(%q<test-unit>, [">= 2.0.9"])
85
+ s.add_dependency(%q<require_all>, [">= 1.1.0"])
86
+ end
87
+ else
88
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta19"])
89
+ s.add_dependency(%q<rspec>, [">= 2.0.0.beta.19"])
90
+ s.add_dependency(%q<rake>, [">= 0.8.7"])
91
+ s.add_dependency(%q<rails>, [">= 3.0.0.rc"])
92
+ s.add_dependency(%q<test-unit>, [">= 2.0.9"])
93
+ s.add_dependency(%q<require_all>, [">= 1.1.0"])
94
+ end
95
+ end
96
+
@@ -0,0 +1,41 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require_generator :demo
3
+
4
+ describe 'model_generator' do
5
+ include RSpec::Rails::Orm::ActiveRecord
6
+
7
+ before :each do
8
+ RSpec::Generator.setup_generator 'model_generator' do
9
+ tests DemoGenerator
10
+ end
11
+ remove_model 'account'
12
+ end
13
+
14
+ after :each do
15
+ remove_model 'account'
16
+ end
17
+
18
+ it "should not work without an Account model file" do
19
+ RSpec::Generator.with_generator do |g|
20
+ name = 'account'
21
+ g.run_generator %w{account}
22
+ g.should_not generate_file name, :model
23
+ end
24
+ end
25
+
26
+ it "should decorate an existing Account model file with include Canable:Ables" do
27
+ RSpec::Generator.with_generator do |g|
28
+ name = 'account'
29
+ create_model name
30
+ g.run_generator %w{account}
31
+ g.should generate_file name, :model do |content|
32
+ content.should have_class name do |klass|
33
+ klass.should include_module 'Canable::Ables'
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+
41
+
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require 'rspec/autorun'
3
+ require 'rspec_for_generators'
4
+
5
+ RSpec::Generator.configure_root_dir __FILE__
6
+
@@ -0,0 +1,110 @@
1
+ h2. Custom generators
2
+
3
+ <pre>
4
+ # my_plugin/lib/generators/install_generator.rb
5
+ module MyGem
6
+ class InstallGenerator < Rails::Generators::Base
7
+ source_root File.expand_path("../templates", __FILE__)
8
+
9
+ # all public methods in here will be run in order
10
+ def add_my_initializer
11
+ template "initializer.rb", "config/initializers/my_gem_initializer.rb"
12
+ end
13
+ end
14
+ end
15
+ </pre>
16
+
17
+ If you inherit from NamedBase, you will have access to several inflections of the name passed in both in the body of your generator class, as well as in your templates.
18
+
19
+ * class_path and file_name are extracted from the name passed in. For instance, if the user passes in admin/posts, the class_path is admin and the file_name is posts
20
+ * file_path is the class_path and file_name joined by /
21
+ * class_name is the file_path, camelized. For instance, admin/posts becomes Admin::Posts
22
+ * human_name is the file_name, humanized. For instance, admin_posts would become Admin posts
23
+ * plural_name is the file_name, pluralized. For instance, post becomes posts
24
+ * i18n_scope is the file_path, with / replaced with .. For instance, admin/posts becomes admin.posts
25
+
26
+ <pre>
27
+ # my_plugin/lib/generators/templates/initializer.rb
28
+ Rails.application.configure do
29
+ # Uncomment this to turn on verbose mode
30
+ # config.my_gem.verbose = true
31
+ end
32
+ </pre>
33
+
34
+ h2. Overriding and replacing built-in Rails 3 generator
35
+
36
+ Simply inherit from the generator you want to replace and change the template source root to your own template directory
37
+ <pre>
38
+ require 'rails/generators/rails/scaffold_controller/scaffold_controller_generator'
39
+ module Rails
40
+ module Generators
41
+ class RespondersControllerGenerator < ScaffoldControllerGenerator
42
+ def self.source_root
43
+ @_source_root ||= File.expand_path("templates", File.dirname(__FILE__))
44
+ end
45
+
46
+ protected
47
+
48
+ def flash?
49
+ !ApplicationController.responder.ancestors.include?(Responders::FlashResponder)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ </pre>
55
+
56
+ To hook a generator into Rails scaffold, all you need to do is to create a Rails::Railtie, which was also introduced in Rails 3.
57
+ The responders gem *railtie* is only a few lines of code:
58
+
59
+ <pre>
60
+ module Responders
61
+ class Railtie < ::Rails::Railtie
62
+ config.responders = ActiveSupport::OrderedOptions.new
63
+ config.generators.scaffold_controller = :responders_controller # important! signifies override by ResponderControllerGenerator
64
+
65
+ initializer "responders.flash_responder" do |app|
66
+ if app.config.responders.flash_keys
67
+ Responders::FlashResponder.flash_keys = app.config.responders.flash_keys
68
+ end
69
+ end
70
+ end
71
+ end
72
+ </pre>
73
+
74
+ The first line sets an instance of ActiveSupport::OrderedOptions at config.responders. This allows you to do the following inside your
75
+ Rails::Application at <code>config/application.rb</code>
76
+
77
+ <pre>
78
+ # config/application.rb
79
+ module Rails
80
+ class Blog < Rails::Application
81
+ config.responders.flash_keys = [:success, :failure]
82
+ end
83
+ end
84
+ </pre>
85
+
86
+ The second line is where the generator configuration happens. In case you are wondering, the config.generators object available in
87
+ Rails::Railtie is exactly the same object as the one in our Rails::Application.
88
+ That said, any gem can configure and manipulate the whole generators workflow in the application.
89
+
90
+ In Rails 3, gems are loaded before your application initializes. This is quite easy to notice if you look at the config/application.rb file:
91
+
92
+ <pre>
93
+ # config/application.rb
94
+
95
+ require File.expand_path('../boot', __FILE__)
96
+ require 'rails/all'
97
+
98
+ # If you have a Gemfile, require the gems listed there, including any gems
99
+ # you've limited to :test, :development, or :production.
100
+ Bundler.require(:default, Rails.env) if defined?(Bundler)
101
+
102
+ module Foo
103
+ class Application < Rails::Application
104
+ </pre>
105
+
106
+ By requiring gems earlier, Rails 3 can give more power to gems because we are sure that the final configuration value will be set by the application developer. The official API for configuring a Rails application is a Rails::Railtie as we just saw above. There is much more you can do inside a railtie, like configuring the middleware stack or any other Rails framework. Since all Rails frameworks (like Active Record, Active Resource, Action Pack…) are also railties, they are a great source of knowledge in case you are interested in learning more.
107
+
108
+ If we want to customize the _form partial generated on scaffold, all you need to do is to copy the _form partial template from Rails source code to lib/templates/erb/scaffold/_form.html.erb.
109
+
110
+ If you want to customize the show view, you just need to copy it as well, and this is true for all generators and all templates! This allows generators to grow and adapt as your application changes! For example, the simple form gem creates a template to change scaffold to use the simple_form_for instead of form_for.