rspec_for_generators 0.2.0

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.
Files changed (38) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +111 -0
  5. data/Rakefile +48 -0
  6. data/VERSION +1 -0
  7. data/lib/generators/demo/demo_generator.rb +91 -0
  8. data/lib/rspec_for_generators.rb +11 -0
  9. data/lib/rspec_for_generators/fixtures/routes.rb +2 -0
  10. data/lib/rspec_for_generators/generator_spec_helper.rb +73 -0
  11. data/lib/rspec_for_generators/main.rb +7 -0
  12. data/lib/rspec_for_generators/matchers/content/all.rb +1 -0
  13. data/lib/rspec_for_generators/matchers/content/have_class.rb +36 -0
  14. data/lib/rspec_for_generators/matchers/content/have_method.rb +49 -0
  15. data/lib/rspec_for_generators/matchers/content/have_module.rb +34 -0
  16. data/lib/rspec_for_generators/matchers/content/include_module.rb +36 -0
  17. data/lib/rspec_for_generators/matchers/content/inherit_from.rb +33 -0
  18. data/lib/rspec_for_generators/matchers/file/all.rb +1 -0
  19. data/lib/rspec_for_generators/matchers/file/generate_file.rb +73 -0
  20. data/lib/rspec_for_generators/matchers/file/generate_migration.rb +43 -0
  21. data/lib/rspec_for_generators/matchers/helpers/content.rb +20 -0
  22. data/lib/rspec_for_generators/matchers/helpers/file.rb +28 -0
  23. data/lib/rspec_for_generators/rails_helpers/all.rb +6 -0
  24. data/lib/rspec_for_generators/rails_helpers/rails_app.rb +55 -0
  25. data/lib/rspec_for_generators/rails_helpers/rails_controller.rb +34 -0
  26. data/lib/rspec_for_generators/rails_helpers/rails_helper.rb +36 -0
  27. data/lib/rspec_for_generators/rails_helpers/rails_mailer.rb +29 -0
  28. data/lib/rspec_for_generators/rails_helpers/rails_model.rb +94 -0
  29. data/lib/rspec_for_generators/rails_helpers/rails_view.rb +29 -0
  30. data/lib/rspec_for_generators/rails_spec_helper.rb +17 -0
  31. data/lib/rspec_for_generators/rspec_test_case.rb +26 -0
  32. data/rspec_for_generators.gemspec +96 -0
  33. data/spec/rspec_for_generators/rspec_for_generators_spec.rb +43 -0
  34. data/spec/spec.opts +1 -0
  35. data/spec/spec_helper.rb +10 -0
  36. data/tmp/rails/config/routes.rb +2 -0
  37. data/wiki/Custom Rails 3 Generators.textile +110 -0
  38. metadata +195 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Kristian Mandrup
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.
data/README.markdown ADDED
@@ -0,0 +1,111 @@
1
+ # RSpec 2 library for specifying and testing generators
2
+
3
+ RSpec 2 matchers, helpers and various utilities to assist in writing generator specs especially Rails 3 generators.
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).
6
+
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!
9
+
10
+ ## Install
11
+
12
+ <code>gem install rspec_for_generators</code>
13
+
14
+ To install using edge
15
+
16
+ <code>rake install</code>
17
+
18
+ ## Usage
19
+
20
+ The following demonstrates an example usage. There are many more options and cool DSL convenience methods. Check out the code!
21
+
22
+ <pre>
23
+ # spec/spec_helper.rb
24
+ require 'rspec'
25
+
26
+ # This is required for rails_spec_helper.rb to work. Not sure how to better set this configuration value.
27
+ # It's the relative root for which the Rails mock app is created. So if it's set to point to the spec folder,
28
+ # then rails will be put under ../tmp, relative to /spec, so that /tmp will be a folder in the current project root.
29
+ # Note: In the near future I will provide a better way to achieve this by hooking into some step in the Rails 3 loading behavior
30
+
31
+ module Rails
32
+ def config_root_dir
33
+ File.dirname(__FILE)
34
+ end
35
+ end
36
+
37
+ # load this rspec toolbox to help spec generators
38
+ require 'rspec_for_generators'
39
+
40
+ <pre>
41
+
42
+ <pre>
43
+ # spec/generators/canable.rb
44
+ require_generators :canable => ['model', 'user']
45
+ </pre>
46
+
47
+ <pre>
48
+ # spec/generators/model_generator_spec.rb
49
+
50
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
51
+
52
+ # list of generators to spec are loaded
53
+ require 'generators/canable'
54
+
55
+ describe 'model_generator' do
56
+ # include Rails model helpers for AciveRecord
57
+ # also available are: MongoMapper, Mongoid and DataMapper
58
+ # mongo_mapper, :data_mapper, :mongoid
59
+
60
+ model_helper_for :active_record
61
+
62
+ before :each do
63
+ # define generator to test
64
+ RSpec::Generator.setup_generator 'model_generator' do
65
+ tests Canable::Generators::ModelGenerator
66
+ end
67
+ # ensure clean state before run
68
+ remove_model 'account'
69
+ end
70
+
71
+ after :each do
72
+ # ensure clean state after run
73
+ remove_model 'account'
74
+ end
75
+
76
+ it "should not work without an existing Account model file" do
77
+ RSpec::Generator.with_generator do |g|
78
+ name = 'account'
79
+ g.run_generator %w{account}
80
+ g.should_not generate_file name, :model
81
+ end
82
+ end
83
+
84
+ it "should decorate an existing Account model file with 'include Canable:Ables'" do
85
+ RSpec::Generator.with_generator do |g|
86
+ name = 'account'
87
+ create_model name
88
+ g.run_generator %w{account}
89
+ g.should generate_file name, :model do |content|
90
+ content.should have_class name.camelize do |klass|
91
+ klass.should include_module 'Canable::Ables'
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ </pre>
98
+
99
+ ## Note on Patches/Pull Requests
100
+
101
+ * Fork the project.
102
+ * Make your feature addition or bug fix.
103
+ * Add tests for it. This is important so I don't break it in a
104
+ future version unintentionally.
105
+ * Commit, do not mess with rakefile, version, or history.
106
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
107
+ * Send me a pull request. Bonus points for topic branches.
108
+
109
+ ## Copyright
110
+
111
+ Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,48 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "rspec_for_generators"
5
+ gem.summary = %Q{RSpec 2 matchers, helpers and utils for writing generator specs}
6
+ gem.description = %Q{RSpec 2 matchers, helpers and utils to assist in writing generator specs}
7
+ gem.email = "kmandrup@gmail.com"
8
+ gem.homepage = "http://github.com/kristianmandrup/rspec_for_generators"
9
+ gem.authors = ["Kristian Mandrup"]
10
+ gem.add_development_dependency "rspec", ">= 2.0.0.beta19"
11
+ gem.add_dependency "rspec", ">= 2.0.0.beta.19"
12
+ gem.add_dependency "rake", ">= 0.8.7"
13
+ gem.add_dependency "rails", ">= 3.0.0.rc"
14
+ gem.add_dependency "test-unit", ">= 2.0.9"
15
+ gem.add_dependency "require_all", ">= 1.1.0"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ # require 'spec/rake/spectask'
24
+ # Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ # spec.libs << 'lib' << 'spec'
26
+ # spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ # end
28
+ #
29
+ # Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ # spec.libs << 'lib' << 'spec'
31
+ # spec.pattern = 'spec/**/*_spec.rb'
32
+ # spec.rcov = true
33
+ # end
34
+ #
35
+ # task :spec => :check_dependencies
36
+ #
37
+ # task :default => :spec
38
+ #
39
+ # require 'rake/rdoctask'
40
+ # Rake::RDocTask.new do |rdoc|
41
+ # version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+ #
43
+ # rdoc.rdoc_dir = 'rdoc'
44
+ # rdoc.title = "rspec_for_generators #{version}"
45
+ # rdoc.rdoc_files.include('README*')
46
+ # rdoc.rdoc_files.include('lib/**/*.rb')
47
+ # end
48
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,91 @@
1
+ class DemoGenerator < Rails::Generators::Base
2
+ desc "Adds Canable::Ables permission system to Model"
3
+
4
+ argument :name, :type => :string, :default => 'User', :desc => 'Name of model to make Canable:Able', :required => false
5
+
6
+ def self.source_root
7
+ @source_root ||= File.expand_path("../../templates", __FILE__)
8
+ end
9
+
10
+ def make_canable_able
11
+ if File.exist?(model_file_name)
12
+ @model_file_txt = File.open(model_file_name).read
13
+ after_txt = find_after_txt(model_file_txt)
14
+ inject_into_file(model_file_name, canable_include_txt, :after => after_txt) if after_txt
15
+ else
16
+ say "#{model_file_name} does not exist. Please create it first before you can make it Canable:Able", :red
17
+ end
18
+ end
19
+
20
+ def post_log
21
+ say "Your model #{model_class_name} is now Canable:Able. Please define your permission login in #{model_file_name}", :green
22
+ end
23
+
24
+ protected
25
+
26
+ attr_accessor :model_file_txt
27
+
28
+ def find_after_txt model_file_txt
29
+ # after first include statement
30
+ match = (model_file_txt =~ /(include\s+\S+)/)
31
+ return $1 if match
32
+
33
+ # or after class definition if no includes
34
+ match = model_file_txt =~ /(class\s+#{model_class_name}\s+<\s+ActiveRecord::Base)/ # first try match AR model
35
+ match = model_file_txt =~ /(class\s+#{model_class_name})/ if !match
36
+ $1 || nil
37
+ end
38
+
39
+ def model_class_name
40
+ name.camelize
41
+ end
42
+
43
+ def model_file_name
44
+ File.join(Rails.root, "app/models/#{name}.rb")
45
+ end
46
+
47
+ def canable_include_txt
48
+ %Q{
49
+ include Canable::Ables
50
+ #{add_userstamps}
51
+
52
+ # permission logic
53
+ #{add_methods}
54
+ }
55
+ end
56
+
57
+ def has_userstamps?
58
+ model_file_txt =~ /userstamps!/
59
+ end
60
+
61
+ def add_userstamps
62
+ if !has_userstamps?
63
+ "userstamps! # adds creator and updater\n" if options[:userstamps]
64
+ end
65
+ end
66
+
67
+ def has_method? name
68
+ model_file_txt =~ /(def #{name}_by\?)/
69
+ end
70
+
71
+ def add_methods
72
+ methods = []
73
+ %w{creatable destroyable updatable viewable}.each do |name|
74
+ if !has_method?(name)
75
+ method = add_method(name)
76
+ methods << method if method
77
+ end
78
+ end
79
+ methods.join("\n ")
80
+ end
81
+
82
+ def add_method(name)
83
+ if options[name.to_sym]
84
+ %Q{
85
+ def #{name}_by?(user)
86
+ true
87
+ end
88
+ }
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,11 @@
1
+ require 'rspec'
2
+ require 'rake'
3
+ require 'rails'
4
+ require 'require_all'
5
+ require 'rails/generators'
6
+ require 'rspec_for_generators/main'
7
+
8
+ RSpec.configure do |config|
9
+ config.include(RSpec::FileMatchers)
10
+ config.include(RSpec::RubyContentMatchers)
11
+ end
@@ -0,0 +1,2 @@
1
+ TestApp.routes.draw do |map|
2
+ end
@@ -0,0 +1,73 @@
1
+ require 'test/unit'
2
+ require 'rails/all'
3
+ require 'rails/generators'
4
+ require 'rails/generators/test_case'
5
+
6
+ require 'rspec_for_generators/rails_spec_helper'
7
+
8
+ # Call configure to load the settings from
9
+ # Rails.application.config.generators to Rails::Generators
10
+
11
+ Rails::Generators.configure!
12
+
13
+ # require the generators
14
+ def require_generators generator_list
15
+ generator_list.each do |name, generators|
16
+ generators.each do |generator_name|
17
+ require File.join('generators', name.to_s, generator_name.to_s, "#{generator_name}_generator")
18
+ end
19
+ end
20
+ end
21
+
22
+ module RSpec
23
+ module Generator
24
+ class << self
25
+ attr_accessor :generator, :test_method_name
26
+
27
+ def run_generator *args, &block
28
+ generator.run_generator *args
29
+ if block
30
+ block.arity < 1 ? generator.instance_eval(&block) : block.call(generator, self)
31
+ end
32
+ end
33
+
34
+ def check(&block)
35
+ if block
36
+ block.arity < 1 ? self.instance_eval(&block) : block.call(self)
37
+ end
38
+ end
39
+
40
+ def with(generator, &block)
41
+ if block
42
+ block.arity < 1 ? generator.instance_eval(&block) : block.call(generator, self, generator.class)
43
+ end
44
+ end
45
+
46
+ def with_generator &block
47
+ with(get_generator, &block)
48
+ end
49
+
50
+ def setup_generator test_method_name=nil, &block
51
+ clean! if test_method_name
52
+ generator = get_generator(test_method_name).extend(RSpec::Generator::Helpers)
53
+ if block
54
+ block.arity < 1 ? generator.class.instance_eval(&block) : block.call(generator.class)
55
+ end
56
+ end
57
+
58
+ protected
59
+
60
+ def clean!
61
+ if generator
62
+ generator.class.generator_class = nil
63
+ end
64
+ @generator = nil
65
+ end
66
+
67
+ def get_generator test_method_name=nil
68
+ @generator ||= RSpec::Generators::TestCase.new(test_method_name + '_spec')
69
+ end
70
+
71
+ end # class self
72
+ end
73
+ end
@@ -0,0 +1,7 @@
1
+ require 'rspec_for_generators/rails_spec_helper'
2
+ require 'rspec_for_generators/rspec_test_case'
3
+ require 'rspec_for_generators/generator_spec_helper'
4
+
5
+ require_all File.dirname(__FILE__) + '/matchers/helpers'
6
+ require_all File.dirname(__FILE__) + '/matchers/content'
7
+ require_all File.dirname(__FILE__) + '/matchers/file'
@@ -0,0 +1 @@
1
+ require_all File.dirname(__FILE__)
@@ -0,0 +1,36 @@
1
+ module RSpec
2
+ module RubyContentMatchers
3
+ class HaveClass
4
+
5
+ attr_reader :klass
6
+
7
+ def initialize(klass)
8
+ @klass = klass
9
+ end
10
+
11
+ def matches?(content)
12
+ @content = content
13
+ match_res = (@content =~ /class\s+#{@klass}\s+(.*)end/m)
14
+ if block_given? && $1
15
+ ruby_content = $1.strip.extend(RSpec::RubyContent::Helpers)
16
+ yield ruby_content
17
+ else
18
+ match_res
19
+ end
20
+ end
21
+
22
+ def failure_message
23
+ "Expected there to be the class #{klass}"
24
+ end
25
+
26
+ def negative_failure_message
27
+ "Did no expected there to be the class #{klass}"
28
+ end
29
+
30
+ end
31
+
32
+ def have_class(klass)
33
+ HaveClass.new(klass)
34
+ end
35
+ end
36
+ end