ammeter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/.gitignore +13 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +57 -0
  4. data/Rakefile +48 -0
  5. data/ammeter.gemspec +30 -0
  6. data/features/generator_spec.feature +76 -0
  7. data/features/support/env.rb +35 -0
  8. data/features/templates/generate_example_app.rb +2 -0
  9. data/features/templates/rspec.rake +4 -0
  10. data/lib/ammeter.rb +3 -0
  11. data/lib/ammeter/rspec/generator/example.rb +7 -0
  12. data/lib/ammeter/rspec/generator/example/generator_example_group.rb +61 -0
  13. data/lib/ammeter/rspec/generator/matcher.rb +3 -0
  14. data/lib/ammeter/rspec/generator/matchers/be_a_migration.rb +7 -0
  15. data/lib/ammeter/rspec/generator/matchers/contain.rb +19 -0
  16. data/lib/ammeter/rspec/generator/matchers/exist.rb +5 -0
  17. data/lib/ammeter/version.rb +3 -0
  18. data/spec/rspec/rails/generator/example/generator_example_group_spec.rb +35 -0
  19. data/spec/rspec/rails/generator/matchers/be_a_migration_spec.rb +20 -0
  20. data/spec/rspec/rails/generator/matchers/be_a_new_spec.rb +137 -0
  21. data/spec/rspec/rails/generator/matchers/be_new_record_spec.rb +17 -0
  22. data/spec/rspec/rails/generator/matchers/be_routable_spec.rb +41 -0
  23. data/spec/rspec/rails/generator/matchers/contain_spec.rb +26 -0
  24. data/spec/rspec/rails/generator/matchers/errors_on_spec.rb +38 -0
  25. data/spec/rspec/rails/generator/matchers/exist_spec.rb +13 -0
  26. data/spec/rspec/rails/generator/matchers/redirect_to_spec.rb +79 -0
  27. data/spec/rspec/rails/generator/matchers/render_template_spec.rb +93 -0
  28. data/spec/rspec/rails/generator/matchers/route_to_spec.rb +99 -0
  29. data/spec/spec_helper.rb +25 -0
  30. data/spec/support/helpers.rb +20 -0
  31. metadata +230 -0
@@ -0,0 +1,13 @@
1
+ tmp
2
+ doc
3
+ pkg
4
+ vendor
5
+ .bundle
6
+ *.gem
7
+ Gemfile
8
+ Gemfile.lock
9
+ gemfiles/*.lock
10
+ .rvmrc
11
+ .DS_Store
12
+ *~
13
+ *.swp
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Alex Rothenberg
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.
@@ -0,0 +1,57 @@
1
+ # Ammeter
2
+
3
+ A gem that makes it easy to write specs for your Rails 3 Generators.
4
+
5
+ # Example
6
+
7
+ require 'spec_helper'
8
+
9
+ # Generators are not automatically loaded by Rails
10
+ require 'generators/rspec/model/model_generator'
11
+
12
+ describe Rspec::Generators::ModelGenerator do
13
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
14
+ destination File.expand_path("../../../../../tmp", __FILE__)
15
+ before do
16
+ prepare_destination
17
+ end
18
+
19
+ # using mocks to ensure proper methods are called
20
+ it 'should run both the model and fixture tasks' do
21
+ gen = generator %w(posts)
22
+ gen.should_receive :create_model_spec
23
+ gen.should_receive :create_fixture_file
24
+ capture(:stdout) { gen.invoke_all }
25
+ end
26
+
27
+ describe 'the generated files' do
28
+ before do
29
+ run_generator %w(posts)
30
+ end
31
+ describe 'the spec' do
32
+ subject { file('spec/models/posts_spec.rb') }
33
+ it { should exist }
34
+ it { should contain /require 'spec_helper'/ }
35
+ it { should /describe Posts/ }
36
+ end
37
+ describe 'the migration' do
38
+ subject { file('db/migrate/create_posts.rb') }
39
+ it { should be_a_migration }
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+ # Contributing
46
+
47
+ * Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
48
+ * Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
49
+ * Fork the project
50
+ * Start a feature/bugfix branch
51
+ * Commit and push until you are happy with your contribution
52
+ * Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
53
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
54
+
55
+ # Copyright
56
+
57
+ Copyright © 2011 Alex Rothenberg. See LICENSE.txt for further details.
@@ -0,0 +1,48 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/rdoctask'
5
+ require 'rspec'
6
+ require 'rspec/core/rake_task'
7
+ require 'cucumber/rake/task'
8
+
9
+ task :cleanup_rcov_files do
10
+ rm_rf 'coverage.data'
11
+ end
12
+
13
+ desc "Run all examples"
14
+ RSpec::Core::RakeTask.new(:spec) do |t|
15
+ t.rspec_opts = %w[--color]
16
+ end
17
+
18
+ Cucumber::Rake::Task.new(:cucumber)
19
+
20
+ # for cucumber features that create a sample project
21
+ def in_example_app(command)
22
+ Dir.chdir("./tmp/example_app/") do
23
+ Bundler.with_clean_env do
24
+ sh command
25
+ end
26
+ end
27
+ end
28
+ namespace :generate do
29
+ desc "generate a fresh app with rspec installed"
30
+ task :app do |t|
31
+ # unless File.directory?('./tmp/example_app')
32
+ sh "bundle exec rails new ./tmp/example_app -m 'features/templates/generate_example_app.rb'"
33
+ sh "cp 'features/templates/rspec.rake' ./tmp/example_app/lib/tasks"
34
+ in_example_app 'rake db:migrate'
35
+ in_example_app 'rails g rspec:install'
36
+ in_example_app 'bundle install'
37
+ # end
38
+ end
39
+ end
40
+
41
+ namespace :clobber do
42
+ desc "clobber the generated app"
43
+ task :app do
44
+ rm_rf "tmp/example_app"
45
+ end
46
+ end
47
+
48
+ task :default => [:spec, :'clobber:app', :'generate:app', :cucumber]
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ammeter/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ammeter"
7
+ s.version = Ammeter::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Alex Rothenberg"]
10
+ s.email = ["alex@alexrothenberg.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Write specs for your Rails 3 generators}
13
+ s.description = %q{Write specs for your Rails 3 generators}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_runtime_dependency 'railties', '~> 3'
21
+ s.add_runtime_dependency 'rspec', '~> 2'
22
+ s.add_runtime_dependency 'rspec-rails', '~> 2'
23
+
24
+ s.add_development_dependency 'rails', '~> 3'
25
+ s.add_development_dependency 'rake', '= 0.8.7'
26
+ s.add_development_dependency 'cucumber', '~> 0.10'
27
+ s.add_development_dependency 'aruba', '~> 0.3'
28
+ s.add_development_dependency 'sqlite3', '~> 1'
29
+
30
+ end
@@ -0,0 +1,76 @@
1
+ Feature: generator spec
2
+
3
+ Generator specs live in spec/generators. In order to access
4
+ the generator's methods you can call them on the "generator" object.
5
+
6
+ Background: A simple generator
7
+ Given a file named "lib/generators/awesome/awesome_generator.rb" with:
8
+ """
9
+ class AwesomeGenerator < Rails::Generators::NamedBase
10
+ source_root File.expand_path('../templates', __FILE__)
11
+
12
+ def create_awesomeness
13
+ template 'awesome.html', File.join('public', name, 'awesome.html')
14
+ end
15
+
16
+ def create_lameness
17
+ template 'lame.html', File.join('public', name, 'lame.html')
18
+ end
19
+ end
20
+ """
21
+ And a file named "lib/generators/awesome/templates/awesome.html" with:
22
+ """
23
+ This is an awesome file
24
+ """
25
+ And a file named "lib/generators/awesome/templates/lame.html" with:
26
+ """
27
+ This is a lame file
28
+ """
29
+
30
+ Scenario: A spec that runs the entire generator
31
+ Given a file named "spec/generators/awesome_generator_spec.rb" with:
32
+ """
33
+ require "spec_helper"
34
+ require 'generators/awesome/awesome_generator'
35
+
36
+ describe AwesomeGenerator do
37
+ destination File.expand_path("../../tmp", __FILE__)
38
+
39
+ before do
40
+ run_generator %w(my_dir)
41
+ end
42
+ it 'should copy the awesome file into public' do
43
+ file('public/my_dir/awesome.html').should exist
44
+ end
45
+ it 'should copy the lame file into public' do
46
+ file('public/my_dir/lame.html').should exist
47
+ end
48
+ end
49
+ """
50
+ When I run `rake spec`
51
+ Then the output should contain "2 examples, 0 failures"
52
+
53
+ Scenario: A spec that runs one task in the generator
54
+ Given a file named "spec/generators/another_awesome_generator_spec.rb" with:
55
+ """
56
+ require "spec_helper"
57
+ require 'generators/awesome/awesome_generator'
58
+
59
+ describe AwesomeGenerator do
60
+ destination File.expand_path("../../tmp", __FILE__)
61
+ arguments %w(another_dir)
62
+
63
+ before do
64
+ invoke_task :create_awesomeness
65
+ end
66
+ it 'should copy the awesome file into public' do
67
+ file('public/another_dir/awesome.html').should exist
68
+ file('public/another_dir/awesome.html').should contain 'This is an awesome file'
69
+ end
70
+ it 'should not have copied the lame file into public' do
71
+ file('public/another_dir/lame.html').should_not exist
72
+ end
73
+ end
74
+ """
75
+ When I run `rake spec`
76
+ Then the output should contain "2 examples, 0 failures"
@@ -0,0 +1,35 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 10
5
+ end
6
+
7
+ def aruba_path(file_or_dir)
8
+ File.expand_path("../../../#{file_or_dir.sub('example_app','aruba')}", __FILE__)
9
+ end
10
+
11
+ def example_app_path(file_or_dir)
12
+ File.expand_path("../../../#{file_or_dir}", __FILE__)
13
+ end
14
+
15
+ def write_symlink(file_or_dir)
16
+ source = example_app_path(file_or_dir)
17
+ target = aruba_path(file_or_dir)
18
+ system "ln -s #{source} #{target}"
19
+ end
20
+
21
+ Before do
22
+ steps %Q{
23
+ Given a directory named "spec"
24
+ }
25
+
26
+ Dir['tmp/example_app/*'].each do |file_or_dir|
27
+ if !(file_or_dir =~ /spec$/)
28
+ write_symlink(file_or_dir)
29
+ end
30
+ end
31
+
32
+ ["spec/spec_helper.rb"].each do |file_or_dir|
33
+ write_symlink("tmp/example_app/#{file_or_dir}")
34
+ end
35
+ end
@@ -0,0 +1,2 @@
1
+ gem 'rspec-rails'
2
+ gem 'ammeter', :path=>'../..'
@@ -0,0 +1,4 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ desc "Run all examples"
4
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,3 @@
1
+ require 'ammeter/rspec/generator/example.rb'
2
+ require 'ammeter/rspec/generator/matcher.rb'
3
+
@@ -0,0 +1,7 @@
1
+ require 'ammeter/rspec/generator/example/generator_example_group'
2
+
3
+ RSpec::configure do |c|
4
+ c.include RSpec::Rails::GeneratorExampleGroup, :type => :generator, :example_group => {
5
+ :file_path => c.escaped_path(%w[spec generators])
6
+ }
7
+ end
@@ -0,0 +1,61 @@
1
+ require 'rails/generators'
2
+ require 'rspec/rails'
3
+
4
+ module RSpec::Rails
5
+ # Delegates to Rails::Generators::TestCase to work with RSpec.
6
+ module GeneratorExampleGroup
7
+ extend ActiveSupport::Concern
8
+ include RSpec::Rails::RailsExampleGroup
9
+
10
+ DELEGATED_METHODS = [:generator, :destination_root_is_set?, :capture, :ensure_current_path,
11
+ :prepare_destination, :destination_root, :current_path, :generator_class]
12
+ module ClassMethods
13
+ mattr_accessor :test_unit_test_case_delegate
14
+ delegate :default_arguments, :to => :'self.test_unit_test_case_delegate'
15
+ DELEGATED_METHODS.each do |method|
16
+ delegate method, :to => :'self.test_unit_test_case_delegate'
17
+ end
18
+ delegate :destination, :arguments, :to => :'self.test_unit_test_case_delegate.class'
19
+
20
+ def initialize_delegate
21
+ self.test_unit_test_case_delegate = Rails::Generators::TestCase.new 'default_test'
22
+ self.test_unit_test_case_delegate.class.tests(describes)
23
+ end
24
+
25
+ def run_generator(given_args=self.default_arguments, config={})
26
+ args, opts = Thor::Options.split(given_args)
27
+ capture(:stdout) { generator(args, opts, config).invoke_all }
28
+ end
29
+ end
30
+
31
+ module InstanceMethods
32
+ def invoke_task name
33
+ capture(:stdout) { generator.invoke_task(generator_class.all_tasks[name.to_s]) }
34
+ end
35
+ end
36
+
37
+ included do
38
+ delegate :run_generator, :destination, :arguments, :to => :'self.class'
39
+ DELEGATED_METHODS.each do |method|
40
+ delegate method, :to => :'self.class'
41
+ end
42
+ initialize_delegate
43
+
44
+ subject { generator }
45
+
46
+ before do
47
+ self.class.initialize_delegate
48
+ destination_root_is_set?
49
+ ensure_current_path
50
+ end
51
+ after do
52
+ ensure_current_path
53
+ end
54
+ metadata[:type] = :generator
55
+ end
56
+
57
+ def file relative
58
+ File.expand_path(relative, destination_root)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ require 'ammeter/rspec/generator/matchers/be_a_migration'
2
+ require 'ammeter/rspec/generator/matchers/contain'
3
+ require 'ammeter/rspec/generator/matchers/exist'
@@ -0,0 +1,7 @@
1
+ RSpec::Matchers.define :be_a_migration do
2
+ match do |file_path|
3
+ dirname, file_name = File.dirname(file_path), File.basename(file_path).sub(/\.rb$/, '')
4
+ migration_file_path = Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
5
+ File.exist?(migration_file_path)
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ RSpec::Matchers.define :contain do |expected_content|
2
+ match do |file_path|
3
+ @actual_contents = File.new(file_path).read
4
+ case expected_content
5
+ when String
6
+ @actual_contents == expected_content
7
+ when Regexp
8
+ @actual_contents =~ expected_content
9
+ end
10
+ end
11
+
12
+ failure_message_for_should do |file_path|
13
+ "expected the file #{file_path} to contain #{expected_content.inspect} but it contained #{@actual_contents.inspect}"
14
+ end
15
+
16
+ failure_message_for_should_not do |relative|
17
+ "expected the file #{file_path} to not contain #{expected_content} but it did"
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ RSpec::Matchers.define :exist do
2
+ match do |file_path|
3
+ File.exists?(file_path)
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Ammeter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,35 @@
1
+ require "spec_helper"
2
+
3
+ module RSpec::Rails
4
+ describe GeneratorExampleGroup do
5
+ it { should be_included_in_files_in('./spec/generators/') }
6
+ it { should be_included_in_files_in('.\\spec\\generators\\') }
7
+
8
+ let(:group) do
9
+ RSpec::Core::ExampleGroup.describe do
10
+ include GeneratorExampleGroup
11
+ end
12
+ end
13
+
14
+ it "adds :type => :generator to the metadata" do
15
+ group.metadata[:type].should eq(:generator)
16
+ end
17
+
18
+ context "with implicit subject" do
19
+ it "uses the generator as the subject" do
20
+ generator = double('generator')
21
+ example = group.new
22
+ example.stub(:generator => generator)
23
+ example.subject.should == generator
24
+ end
25
+ end
26
+
27
+ describe "with explicit subject" do
28
+ it "should use the specified subject instead of the generator" do
29
+ group.subject { 'explicit' }
30
+ example = group.new
31
+ example.subject.should == 'explicit'
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe "be_a_migration" do
4
+
5
+ let(:migration_files) { ['db/migrate/20110504132601_create_posts.rb', 'db/migrate/20110520132601_create_users.rb'] }
6
+
7
+ before do
8
+ File.stub(:exist?).and_return(false)
9
+ migration_files.each do |migration_file|
10
+ File.stub(:exist?).with(migration_file).and_return(true)
11
+ end
12
+ Dir.stub!(:glob).with('db/migrate/[0-9]*_*.rb').and_return(migration_files)
13
+ end
14
+ it 'should find for the migration file with timestamp in filename' do
15
+ 'db/migrate/create_users.rb'.should be_a_migration
16
+ end
17
+ it 'should know when a migration does not exist' do
18
+ 'db/migrate/create_comments.rb'.should_not be_a_migration
19
+ end
20
+ end
@@ -0,0 +1,137 @@
1
+ require "spec_helper"
2
+
3
+ describe "be_a_new matcher" do
4
+ context "new record" do
5
+ let(:record) do
6
+ Class.new do
7
+ def new_record?; true; end
8
+ end.new
9
+ end
10
+ context "right class" do
11
+ it "passes" do
12
+ record.should be_a_new(record.class)
13
+ end
14
+ end
15
+ context "wrong class" do
16
+ it "fails" do
17
+ record.should_not be_a_new(String)
18
+ end
19
+ end
20
+ end
21
+
22
+ context "existing record" do
23
+ let(:record) do
24
+ Class.new do
25
+ def new_record?; false; end
26
+ end.new
27
+ end
28
+ context "right class" do
29
+ it "fails" do
30
+ record.should_not be_a_new(record.class)
31
+ end
32
+ end
33
+ context "wrong class" do
34
+ it "fails" do
35
+ record.should_not be_a_new(String)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "#with" do
41
+ context "right class and new record" do
42
+ let(:record) do
43
+ Class.new do
44
+ def initialize(attributes)
45
+ @attributes = attributes
46
+ end
47
+
48
+ def attributes
49
+ @attributes.stringify_keys
50
+ end
51
+
52
+ def new_record?; true; end
53
+ end.new(:foo => 'foo', :bar => 'bar')
54
+ end
55
+
56
+ context "all attributes same" do
57
+ it "passes" do
58
+ record.should be_a_new(record.class).with(:foo => 'foo', :bar => 'bar')
59
+ end
60
+ end
61
+
62
+ context "one attribute same" do
63
+ it "passes" do
64
+ record.should be_a_new(record.class).with(:foo => 'foo')
65
+ end
66
+ end
67
+
68
+ context "no attributes same" do
69
+ it "fails" do
70
+ expect {
71
+ record.should be_a_new(record.class).with(:zoo => 'zoo', :car => 'car')
72
+ }.to raise_error(
73
+ %Q(attributes {"zoo"=>"zoo", "car"=>"car"} were not set on #{record.inspect})
74
+ )
75
+ end
76
+ end
77
+
78
+ context "one attribute value not the same" do
79
+ it "fails" do
80
+ expect {
81
+ record.should be_a_new(record.class).with(:foo => 'bar')
82
+ }.to raise_error(
83
+ %Q(attribute {"foo"=>"bar"} was not set on #{record.inspect})
84
+ )
85
+ end
86
+ end
87
+ end
88
+
89
+ context "wrong class and existing record" do
90
+ let(:record) do
91
+ Class.new do
92
+ def initialize(attributes)
93
+ @attributes = attributes
94
+ end
95
+
96
+ def attributes
97
+ @attributes.stringify_keys
98
+ end
99
+
100
+ def new_record?; false; end
101
+ end.new(:foo => 'foo', :bar => 'bar')
102
+ end
103
+
104
+ context "all attributes same" do
105
+ it "fails" do
106
+ expect {
107
+ record.should be_a_new(String).with(:foo => 'foo', :bar => 'bar')
108
+ }.to raise_error(
109
+ "expected #{record.inspect} to be a new String"
110
+ )
111
+ end
112
+ end
113
+
114
+ context "no attributes same" do
115
+ it "fails" do
116
+ expect {
117
+ record.should be_a_new(String).with(:zoo => 'zoo', :car => 'car')
118
+ }.to raise_error(
119
+ "expected #{record.inspect} to be a new String and " +
120
+ %Q(attributes {"zoo"=>"zoo", "car"=>"car"} were not set on #{record.inspect})
121
+ )
122
+ end
123
+ end
124
+
125
+ context "one attribute value not the same" do
126
+ it "fails" do
127
+ expect {
128
+ record.should be_a_new(String).with(:foo => 'bar')
129
+ }.to raise_error(
130
+ "expected #{record.inspect} to be a new String and " +
131
+ %Q(attribute {"foo"=>"bar"} was not set on #{record.inspect})
132
+ )
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe "be_new_record" do
4
+ context "un-persisted record" do
5
+ it "passes" do
6
+ record = double('record', :persisted? => false)
7
+ record.should be_new_record
8
+ end
9
+ end
10
+
11
+ context "persisted record" do
12
+ it "fails" do
13
+ record = double('record', :persisted? => true)
14
+ record.should_not be_new_record
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe "be_routable" do
4
+ include RSpec::Rails::Matchers::RoutingMatchers
5
+ attr_reader :routes
6
+
7
+ before { @routes = double("routes") }
8
+
9
+ context "with should" do
10
+ it "passes if routes recognize the path" do
11
+ routes.stub(:recognize_path) { {} }
12
+ expect do
13
+ {:get => "/a/path"}.should be_routable
14
+ end.to_not raise_error
15
+ end
16
+
17
+ it "fails if routes do not recognize the path" do
18
+ routes.stub(:recognize_path) { raise ActionController::RoutingError.new('ignore') }
19
+ expect do
20
+ {:get => "/a/path"}.should be_routable
21
+ end.to raise_error(/expected \{:get=>"\/a\/path"\} to be routable/)
22
+ end
23
+ end
24
+
25
+ context "with should_not" do
26
+
27
+ it "passes if routes do not recognize the path" do
28
+ routes.stub(:recognize_path) { raise ActionController::RoutingError.new('ignore') }
29
+ expect do
30
+ {:get => "/a/path"}.should_not be_routable
31
+ end.to_not raise_error
32
+ end
33
+
34
+ it "fails if routes recognize the path" do
35
+ routes.stub(:recognize_path) { {:controller => "foo"} }
36
+ expect do
37
+ {:get => "/a/path"}.should_not be_routable
38
+ end.to raise_error(/expected \{:get=>"\/a\/path"\} not to be routable, but it routes to \{:controller=>"foo"\}/)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe "contain" do
4
+
5
+ context "when the file exists" do
6
+ let(:contents) { "This file\ncontains\nthis text" }
7
+ let(:mock_file) { mock(:read=>contents) }
8
+
9
+ subject { '/some/file/path' }
10
+ before do
11
+ File.stub(:new).with('/some/file/path').and_return(mock_file)
12
+ end
13
+ it { should contain "This file\ncontains\nthis text" }
14
+ it { should contain /This file/ }
15
+ it { should contain /this text/ }
16
+ it { should_not contain /something not there/ }
17
+ end
18
+
19
+ context "when the file is not there" do
20
+ it 'raises an error when the file does not exist' do
21
+ expect do
22
+ 'some/file/that/does/not/exist'.should contain 'something'
23
+ end.to raise_error 'No such file or directory - some/file/that/does/not/exist'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ describe "error_on" do
4
+ it "provides a description including the name of what the error is on" do
5
+ have(1).error_on(:whatever).description.should == "have 1 error on :whatever"
6
+ end
7
+
8
+ it "provides a failure message including the number actually given" do
9
+ lambda {
10
+ [].should have(1).error_on(:whatever)
11
+ }.should raise_error("expected 1 error on :whatever, got 0")
12
+ end
13
+ end
14
+
15
+ describe "errors_on" do
16
+ it "provides a description including the name of what the error is on" do
17
+ have(2).errors_on(:whatever).description.should == "have 2 errors on :whatever"
18
+ end
19
+
20
+ it "provides a failure message including the number actually given" do
21
+ lambda {
22
+ [1].should have(3).errors_on(:whatever)
23
+ }.should raise_error("expected 3 errors on :whatever, got 1")
24
+ end
25
+ end
26
+
27
+ describe "have something other than error_on or errors_on" do
28
+ it "has a standard rspec failure message" do
29
+ lambda {
30
+ [1,2,3].should have(2).elements
31
+ }.should raise_error("expected 2 elements, got 3")
32
+ end
33
+
34
+ it "has a standard rspec description" do
35
+ have(2).elements.description.should == "have 2 elements"
36
+ end
37
+ end
38
+
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe "exist" do
4
+ it 'passes when the file exists' do
5
+ File.stub(:exists?).with('/some/file/path').and_return(true)
6
+ '/some/file/path'.should exist
7
+ end
8
+ it 'fails when the file does not exist' do
9
+ File.stub(:exists?).with('/some/file/path').and_return(false)
10
+ '/some/file/path'.should_not exist
11
+ end
12
+
13
+ end
@@ -0,0 +1,79 @@
1
+ require "spec_helper"
2
+ require "active_support/test_case"
3
+
4
+ describe "redirect_to" do
5
+ include RSpec::Rails::Matchers::RedirectTo
6
+
7
+ let(:response) { ActionController::TestResponse.new }
8
+
9
+ it "delegates to assert_redirected_to" do
10
+ self.should_receive(:assert_redirected_to).with("destination")
11
+ "response".should redirect_to("destination")
12
+ end
13
+
14
+ context "with should" do
15
+ context "when assert_redirected_to passes" do
16
+ it "passes" do
17
+ self.stub!(:assert_redirected_to)
18
+ expect do
19
+ response.should redirect_to("destination")
20
+ end.to_not raise_exception
21
+ end
22
+ end
23
+
24
+ context "when assert_redirected_to fails" do
25
+ it "uses failure message from assert_redirected_to" do
26
+ self.stub!(:assert_redirected_to) do
27
+ raise ActiveSupport::TestCase::Assertion.new("this message")
28
+ end
29
+ expect do
30
+ response.should redirect_to("destination")
31
+ end.to raise_error("this message")
32
+ end
33
+ end
34
+
35
+ context "when fails due to some other exception" do
36
+ it "raises that exception" do
37
+ self.stub!(:assert_redirected_to) do
38
+ raise "oops"
39
+ end
40
+ expect do
41
+ response.should redirect_to("destination")
42
+ end.to raise_exception("oops")
43
+ end
44
+ end
45
+ end
46
+
47
+ context "with should_not" do
48
+ context "when assert_redirected_to fails" do
49
+ it "passes" do
50
+ self.stub!(:assert_redirected_to) do
51
+ raise ActiveSupport::TestCase::Assertion.new("this message")
52
+ end
53
+ expect do
54
+ response.should_not redirect_to("destination")
55
+ end.to_not raise_exception
56
+ end
57
+ end
58
+
59
+ context "when assert_redirected_to passes" do
60
+ it "fails with custom failure message" do
61
+ self.stub!(:assert_redirected_to)
62
+ expect do
63
+ response.should_not redirect_to("destination")
64
+ end.to raise_error(/expected not to redirect to \"destination\", but did/)
65
+ end
66
+ end
67
+
68
+ context "when fails due to some other exception" do
69
+ it "raises that exception" do
70
+ self.stub!(:assert_redirected_to) do
71
+ raise "oops"
72
+ end
73
+ expect do
74
+ response.should_not redirect_to("destination")
75
+ end.to raise_exception("oops")
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,93 @@
1
+ require "spec_helper"
2
+
3
+ describe "render_template" do
4
+ include RSpec::Rails::Matchers::RenderTemplate
5
+ let(:response) { ActionController::TestResponse.new }
6
+
7
+ context "given a hash" do
8
+ it "delegates to assert_template" do
9
+ self.should_receive(:assert_template).with({:this => "hash"}, "this message")
10
+ "response".should render_template({:this => "hash"}, "this message")
11
+ end
12
+ end
13
+
14
+ context "given a string" do
15
+ it "delegates to assert_template" do
16
+ self.should_receive(:assert_template).with("this string", "this message")
17
+ "response".should render_template("this string", "this message")
18
+ end
19
+ end
20
+
21
+ context "given a symbol" do
22
+ it "converts to_s and delegates to assert_template" do
23
+ self.should_receive(:assert_template).with("template_name", "this message")
24
+ "response".should render_template(:template_name, "this message")
25
+ end
26
+ end
27
+
28
+ context "with should" do
29
+ context "when assert_template passes" do
30
+ it "passes" do
31
+ self.stub!(:assert_template)
32
+ expect do
33
+ response.should render_template("template_name")
34
+ end.to_not raise_exception
35
+ end
36
+ end
37
+
38
+ context "when assert_template fails" do
39
+ it "uses failure message from assert_template" do
40
+ self.stub!(:assert_template) do
41
+ raise ActiveSupport::TestCase::Assertion.new("this message")
42
+ end
43
+ expect do
44
+ response.should render_template("template_name")
45
+ end.to raise_error("this message")
46
+ end
47
+ end
48
+
49
+ context "when fails due to some other exception" do
50
+ it "raises that exception" do
51
+ self.stub!(:assert_template) do
52
+ raise "oops"
53
+ end
54
+ expect do
55
+ response.should render_template("template_name")
56
+ end.to raise_exception("oops")
57
+ end
58
+ end
59
+ end
60
+
61
+ context "with should_not" do
62
+ context "when assert_template fails" do
63
+ it "passes" do
64
+ self.stub!(:assert_template) do
65
+ raise ActiveSupport::TestCase::Assertion.new("this message")
66
+ end
67
+ expect do
68
+ response.should_not render_template("template_name")
69
+ end.to_not raise_exception
70
+ end
71
+ end
72
+
73
+ context "when assert_template passes" do
74
+ it "fails with custom failure message" do
75
+ self.stub!(:assert_template)
76
+ expect do
77
+ response.should_not render_template("template_name")
78
+ end.to raise_error(/expected not to render \"template_name\", but did/)
79
+ end
80
+ end
81
+
82
+ context "when fails due to some other exception" do
83
+ it "raises that exception" do
84
+ self.stub!(:assert_template) do
85
+ raise "oops"
86
+ end
87
+ expect do
88
+ response.should_not render_template("template_name")
89
+ end.to raise_exception("oops")
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,99 @@
1
+ require "spec_helper"
2
+
3
+ describe "route_to" do
4
+ include RSpec::Rails::Matchers::RoutingMatchers
5
+ include RSpec::Rails::Matchers::RoutingMatchers::RouteHelpers
6
+
7
+ it "delegates to assert_recognizes" do
8
+ self.should_receive(:assert_recognizes).with({ "these" => "options" }, { :method=> :get, :path=>"path" })
9
+ {:get => "path"}.should route_to("these" => "options")
10
+ end
11
+
12
+ context "with shortcut syntax" do
13
+
14
+ it "routes with extra options" do
15
+ self.should_receive(:assert_recognizes).with({ :controller => "controller", :action => "action", :extra => "options"}, { :method=> :get, :path=>"path" })
16
+ get("path").should route_to("controller#action", :extra => "options")
17
+ end
18
+
19
+ it "routes without extra options" do
20
+ self.should_receive(:assert_recognizes).with({ :controller => "controller", :action => "action"}, { :method=> :get, :path=>"path" })
21
+ get("path").should route_to("controller#action")
22
+ end
23
+
24
+ end
25
+
26
+ context "with should" do
27
+ context "when assert_recognizes passes" do
28
+ it "passes" do
29
+ self.stub!(:assert_recognizes)
30
+ expect do
31
+ {:get => "path"}.should route_to("these" => "options")
32
+ end.to_not raise_exception
33
+ end
34
+ end
35
+
36
+ context "when assert_recognizes fails" do
37
+ it "fails with message from assert_recognizes" do
38
+ self.stub!(:assert_recognizes) do
39
+ raise ActiveSupport::TestCase::Assertion.new("this message")
40
+ end
41
+ expect do
42
+ {:get => "path"}.should route_to("these" => "options")
43
+ end.to raise_error("this message")
44
+ end
45
+ end
46
+
47
+ context "when an exception is raised" do
48
+ it "raises that exception" do
49
+ self.stub!(:assert_recognizes) do
50
+ raise "oops"
51
+ end
52
+ expect do
53
+ {:get => "path"}.should route_to("these" => "options")
54
+ end.to raise_exception("oops")
55
+ end
56
+ end
57
+ end
58
+
59
+ context "with should_not" do
60
+ context "when assert_recognizes passes" do
61
+ it "fails with custom message" do
62
+ self.stub!(:assert_recognizes)
63
+ expect do
64
+ {:get => "path"}.should_not route_to("these" => "options")
65
+ end.to raise_error(/expected .* not to route to .*/)
66
+ end
67
+ end
68
+
69
+ context "when assert_recognizes fails" do
70
+ it "passes" do
71
+ self.stub!(:assert_recognizes) do
72
+ raise ActiveSupport::TestCase::Assertion.new("this message")
73
+ end
74
+ expect do
75
+ {:get => "path"}.should_not route_to("these" => "options")
76
+ end.to_not raise_error
77
+ end
78
+ end
79
+
80
+ context "when an exception is raised" do
81
+ it "raises that exception" do
82
+ self.stub!(:assert_recognizes) do
83
+ raise "oops"
84
+ end
85
+ expect do
86
+ {:get => "path"}.should_not route_to("these" => "options")
87
+ end.to raise_exception("oops")
88
+ end
89
+ end
90
+ end
91
+ it "uses failure message from assert_recognizes" do
92
+ self.stub!(:assert_recognizes).and_raise(
93
+ ActiveSupport::TestCase::Assertion.new("this message"))
94
+ expect do
95
+ {"this" => "path"}.should route_to("these" => "options")
96
+ end.to raise_error("this message")
97
+ end
98
+ end
99
+
@@ -0,0 +1,25 @@
1
+ require 'rails/all'
2
+ require 'rspec/rails'
3
+ require 'ammeter'
4
+
5
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
6
+
7
+ # TODO - most of this is borrowed from rspec-rails's spec_helper - which
8
+ # is copied from rspec-core's
9
+ module MatchesForRSpecRailsSpecs
10
+ extend RSpec::Matchers::DSL
11
+
12
+ matcher :be_included_in_files_in do |path|
13
+ match do |mod|
14
+ stub_metadata(
15
+ :example_group => {:file_path => "#{path}whatever_spec.rb:15"}
16
+ )
17
+ group = RSpec::Core::ExampleGroup.describe
18
+ group.included_modules.include?(mod)
19
+ end
20
+ end
21
+ end
22
+
23
+ RSpec.configure do |c|
24
+ c.include MatchesForRSpecRailsSpecs
25
+ end
@@ -0,0 +1,20 @@
1
+ module Helpers
2
+ def stub_metadata(additional_metadata)
3
+ stub_metadata = metadata_with(additional_metadata)
4
+ RSpec::Core::ExampleGroup.stub(:metadata) { stub_metadata }
5
+ end
6
+
7
+ def metadata_with(additional_metadata)
8
+ m = RSpec::Core::Metadata.new
9
+ m.process("example group")
10
+
11
+ group_metadata = additional_metadata.delete(:example_group)
12
+ if group_metadata
13
+ m[:example_group].merge!(group_metadata)
14
+ end
15
+ m.merge!(additional_metadata)
16
+ m
17
+ end
18
+
19
+ RSpec.configure {|c| c.include self}
20
+ end
metadata ADDED
@@ -0,0 +1,230 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ammeter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Alex Rothenberg
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-09 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: railties
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 5
30
+ segments:
31
+ - 3
32
+ version: "3"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 7
44
+ segments:
45
+ - 2
46
+ version: "2"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec-rails
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ hash: 7
58
+ segments:
59
+ - 2
60
+ version: "2"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rails
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ hash: 5
72
+ segments:
73
+ - 3
74
+ version: "3"
75
+ type: :development
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: rake
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - "="
84
+ - !ruby/object:Gem::Version
85
+ hash: 49
86
+ segments:
87
+ - 0
88
+ - 8
89
+ - 7
90
+ version: 0.8.7
91
+ type: :development
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: cucumber
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ hash: 31
102
+ segments:
103
+ - 0
104
+ - 10
105
+ version: "0.10"
106
+ type: :development
107
+ version_requirements: *id006
108
+ - !ruby/object:Gem::Dependency
109
+ name: aruba
110
+ prerelease: false
111
+ requirement: &id007 !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ~>
115
+ - !ruby/object:Gem::Version
116
+ hash: 13
117
+ segments:
118
+ - 0
119
+ - 3
120
+ version: "0.3"
121
+ type: :development
122
+ version_requirements: *id007
123
+ - !ruby/object:Gem::Dependency
124
+ name: sqlite3
125
+ prerelease: false
126
+ requirement: &id008 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ hash: 1
132
+ segments:
133
+ - 1
134
+ version: "1"
135
+ type: :development
136
+ version_requirements: *id008
137
+ description: Write specs for your Rails 3 generators
138
+ email:
139
+ - alex@alexrothenberg.com
140
+ executables: []
141
+
142
+ extensions: []
143
+
144
+ extra_rdoc_files: []
145
+
146
+ files:
147
+ - .gitignore
148
+ - Gemfile
149
+ - LICENSE.txt
150
+ - README.md
151
+ - Rakefile
152
+ - ammeter.gemspec
153
+ - features/generator_spec.feature
154
+ - features/support/env.rb
155
+ - features/templates/generate_example_app.rb
156
+ - features/templates/rspec.rake
157
+ - lib/.DS_Store
158
+ - lib/ammeter.rb
159
+ - lib/ammeter/rspec/generator/example.rb
160
+ - lib/ammeter/rspec/generator/example/generator_example_group.rb
161
+ - lib/ammeter/rspec/generator/matcher.rb
162
+ - lib/ammeter/rspec/generator/matchers/be_a_migration.rb
163
+ - lib/ammeter/rspec/generator/matchers/contain.rb
164
+ - lib/ammeter/rspec/generator/matchers/exist.rb
165
+ - lib/ammeter/version.rb
166
+ - spec/rspec/rails/generator/example/generator_example_group_spec.rb
167
+ - spec/rspec/rails/generator/matchers/be_a_migration_spec.rb
168
+ - spec/rspec/rails/generator/matchers/be_a_new_spec.rb
169
+ - spec/rspec/rails/generator/matchers/be_new_record_spec.rb
170
+ - spec/rspec/rails/generator/matchers/be_routable_spec.rb
171
+ - spec/rspec/rails/generator/matchers/contain_spec.rb
172
+ - spec/rspec/rails/generator/matchers/errors_on_spec.rb
173
+ - spec/rspec/rails/generator/matchers/exist_spec.rb
174
+ - spec/rspec/rails/generator/matchers/redirect_to_spec.rb
175
+ - spec/rspec/rails/generator/matchers/render_template_spec.rb
176
+ - spec/rspec/rails/generator/matchers/route_to_spec.rb
177
+ - spec/spec_helper.rb
178
+ - spec/support/helpers.rb
179
+ has_rdoc: true
180
+ homepage: ""
181
+ licenses: []
182
+
183
+ post_install_message:
184
+ rdoc_options: []
185
+
186
+ require_paths:
187
+ - lib
188
+ required_ruby_version: !ruby/object:Gem::Requirement
189
+ none: false
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ hash: 3
194
+ segments:
195
+ - 0
196
+ version: "0"
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ none: false
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ hash: 3
203
+ segments:
204
+ - 0
205
+ version: "0"
206
+ requirements: []
207
+
208
+ rubyforge_project:
209
+ rubygems_version: 1.5.0
210
+ signing_key:
211
+ specification_version: 3
212
+ summary: Write specs for your Rails 3 generators
213
+ test_files:
214
+ - features/generator_spec.feature
215
+ - features/support/env.rb
216
+ - features/templates/generate_example_app.rb
217
+ - features/templates/rspec.rake
218
+ - spec/rspec/rails/generator/example/generator_example_group_spec.rb
219
+ - spec/rspec/rails/generator/matchers/be_a_migration_spec.rb
220
+ - spec/rspec/rails/generator/matchers/be_a_new_spec.rb
221
+ - spec/rspec/rails/generator/matchers/be_new_record_spec.rb
222
+ - spec/rspec/rails/generator/matchers/be_routable_spec.rb
223
+ - spec/rspec/rails/generator/matchers/contain_spec.rb
224
+ - spec/rspec/rails/generator/matchers/errors_on_spec.rb
225
+ - spec/rspec/rails/generator/matchers/exist_spec.rb
226
+ - spec/rspec/rails/generator/matchers/redirect_to_spec.rb
227
+ - spec/rspec/rails/generator/matchers/render_template_spec.rb
228
+ - spec/rspec/rails/generator/matchers/route_to_spec.rb
229
+ - spec/spec_helper.rb
230
+ - spec/support/helpers.rb