mocked_fixtures 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +49 -0
  4. data/README.txt +206 -0
  5. data/Rakefile +4 -0
  6. data/TODO.txt +5 -0
  7. data/config/hoe.rb +73 -0
  8. data/config/requirements.rb +15 -0
  9. data/init.rb +2 -0
  10. data/lib/mocked_fixtures/connection_adapters/sqlserver_adapter.rb +25 -0
  11. data/lib/mocked_fixtures/mock_connection.rb +61 -0
  12. data/lib/mocked_fixtures/mock_factory.rb +12 -0
  13. data/lib/mocked_fixtures/mock_fixtures.rb +58 -0
  14. data/lib/mocked_fixtures/mocks/flexmock.rb +35 -0
  15. data/lib/mocked_fixtures/mocks/mocha.rb +47 -0
  16. data/lib/mocked_fixtures/mocks/rspec.rb +40 -0
  17. data/lib/mocked_fixtures/schema_parser.rb +30 -0
  18. data/lib/mocked_fixtures/spec/configuration.rb +19 -0
  19. data/lib/mocked_fixtures/testcase.rb +122 -0
  20. data/lib/mocked_fixtures/version.rb +9 -0
  21. data/lib/mocked_fixtures.rb +15 -0
  22. data/script/console +10 -0
  23. data/script/txt2html +82 -0
  24. data/spec/connection_adapters/sqlserver_adapter_spec.rb +44 -0
  25. data/spec/mock_connection_spec.rb +6 -0
  26. data/spec/mock_factory_spec.rb +59 -0
  27. data/spec/mock_fixtures_spec.rb +30 -0
  28. data/spec/resources/companies.yml +3 -0
  29. data/spec/resources/company.rb +5 -0
  30. data/spec/resources/employee.rb +3 -0
  31. data/spec/resources/employees.yml +8 -0
  32. data/spec/resources/schema.rb +18 -0
  33. data/spec/rspec-rails/MIT-LICENSE +31 -0
  34. data/spec/rspec-rails/mocks.rb +115 -0
  35. data/spec/rspec-rails/rails_example_group.rb +27 -0
  36. data/spec/rspec-rails/rspec-rails.rb +15 -0
  37. data/spec/schema_parser_spec.rb +41 -0
  38. data/spec/spec.opts +6 -0
  39. data/spec/spec_helper.rb +27 -0
  40. data/spec/testcase_spec.rb +73 -0
  41. data/tasks/deployment.rake +34 -0
  42. data/tasks/environment.rake +7 -0
  43. data/tasks/rspec.rake +21 -0
  44. data/tasks/website.rake +17 -0
  45. data/website/index.html +86 -0
  46. data/website/index.txt +81 -0
  47. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  48. data/website/stylesheets/screen.css +138 -0
  49. data/website/template.html.erb +48 -0
  50. metadata +117 -0
@@ -0,0 +1,30 @@
1
+ module MockedFixtures
2
+ class SchemaParser
3
+ cattr_accessor :schema_path
4
+
5
+ # Parses schema.rb file and pulls out all the columns names and types into
6
+ # an array, with each row being an array of the column name and type
7
+ # respectively.
8
+ def self.load_schema
9
+ schema = {}
10
+ table_name = ""
11
+ open(schema_path, 'r').each do |line|
12
+ if /create_table "(\w+)".*? do \|t\|/ =~ line
13
+ table_name = $1
14
+ schema[table_name] = {:columns => [], :primary_key => nil}
15
+ schema[table_name][:columns]
16
+ if line =~ /:primary_key => "(.*?)"/
17
+ schema[table_name][:columns] << [$1, 'integer']
18
+ schema[table_name][:primary_key] = $1
19
+ elsif line !~ /:id => false/
20
+ schema[table_name][:columns] << ['id', 'integer']
21
+ schema[table_name][:primary_key] = 'id'
22
+ end
23
+ elsif /t\.(\w+)\s+"(\w+)"/ =~ line
24
+ schema[table_name][:columns] << [$2, $1]
25
+ end
26
+ end
27
+ schema
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module MockedFixtures
2
+ module Spec
3
+ module Configuration
4
+ def global_mock_fixtures
5
+ Test::Unit::TestCase.mock_fixture_table_names
6
+ end
7
+
8
+ def global_mock_fixtures=(fixtures)
9
+ Test::Unit::TestCase.mock_fixtures(*fixtures)
10
+ end
11
+
12
+ def mock_fixtures_with(mock_framework)
13
+ Test::Unit::TestCase.mock_fixtures_with mock_framework
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Spec::Example::Configuration.send(:include, MockedFixtures::Spec::Configuration)
@@ -0,0 +1,122 @@
1
+ # Many of these methods are renamed and modified from the Rails Fixtures
2
+ # TestCase class extensions.
3
+ module Test
4
+ module Unit
5
+ class TestCase
6
+
7
+ superclass_delegating_accessor :mock_fixture_table_names
8
+ superclass_delegating_accessor :loaded_mock_fixtures
9
+ superclass_delegating_accessor :mock_fixtures_loaded
10
+ superclass_delegating_accessor :global_mock_fixtures
11
+ superclass_delegating_accessor :mocked_fixtures_mock_framework
12
+
13
+ self.mock_fixture_table_names = []
14
+ self.loaded_mock_fixtures = {}
15
+ self.mock_fixtures_loaded = false
16
+
17
+ def self.global_mock_fixtures=(*table_names)
18
+ table_names = self.all_fixture_table_names if table_names.first == :all
19
+ self.mock_fixtures table_names.flatten.map { |n| n.to_s }
20
+ end
21
+
22
+ def self.mock_fixtures_with(mock_framework)
23
+ require "mocked_fixtures/mocks/#{mock_framework}"
24
+ self.mocked_fixtures_mock_framework = mock_framework
25
+ unless mock_framework == :rspec
26
+ self.send(:alias_method, :mock_model, "mock_model_with_#{mock_framework}".to_sym)
27
+ end
28
+ end
29
+
30
+ def self.mock_fixtures(*table_names)
31
+ table_names = self.all_fixture_table_names if table_names.first == :all
32
+
33
+ table_names = table_names.flatten.map { |n| n.to_s }
34
+
35
+ self.mock_fixture_table_names |= table_names
36
+
37
+ require_fixture_classes(table_names)
38
+ setup_mock_fixture_accessors(table_names)
39
+ end
40
+
41
+ def self.all_fixture_table_names
42
+ table_names = Dir["#{fixture_path}/*.yml"] + Dir["#{fixture_path}/*.csv"]
43
+ table_names.map { |f| File.basename(f).split('.')[0..-2].join('.') }
44
+ end
45
+
46
+ # Adds test case setup method to run before each test to load fixture
47
+ # files and setup mock fixture accessors for test class. This runs before
48
+ # each test as the test class is recreated each time.
49
+ def self.method_added_with_mock_fixtures(method)
50
+ return if @__disable_method_added__
51
+ @__disable_method_added__ = true
52
+
53
+ if method.to_s == 'setup'
54
+ unless method_defined?(:setup_without_mock_fixtures)
55
+ alias_method :setup_without_mock_fixtures, :setup
56
+ define_method(:mock_fixture_setup) do
57
+ setup_with_mock_fixtures
58
+ setup_without_mock_fixtures
59
+ end
60
+ end
61
+ alias_method :setup, :mock_fixture_setup
62
+ end
63
+
64
+ @__disable_method_added__ = false
65
+ method_added_without_mock_fixtures(method)
66
+ end
67
+
68
+ class << self
69
+ alias_method_chain :method_added, :mock_fixtures
70
+ end
71
+
72
+ # This creates the fixture accessors and retrieves the fixture and creates
73
+ # mock object from it. Mock fixture is then cached.
74
+ def self.setup_mock_fixture_accessors(table_names = nil)
75
+ (table_names || mock_fixture_table_names).each do |table_name|
76
+ table_name = table_name.to_s.tr('.', '_')
77
+
78
+ define_method('mock_' + table_name) do |*fixtures|
79
+ @mock_fixture_cache ||= {}
80
+ @mock_fixture_cache[table_name] ||= {}
81
+ if fixtures.first == :all
82
+ fixtures = self.class.loaded_mock_fixtures[table_name].keys
83
+ end
84
+
85
+ mock_type = self.class.mocked_fixtures_mock_framework
86
+
87
+ instances = fixtures.map do |fixture_name|
88
+ if fixture = self.class.loaded_mock_fixtures[table_name][fixture_name.to_s]
89
+ unless model_class = self.class.loaded_mock_fixtures[table_name].send(:model_class)
90
+ raise StandardError, "No model class found for table name '#{table_name}'. Specify it explicitly 'set_fixture_class :table_name => 'ClassName'."
91
+ end
92
+
93
+ @mock_fixture_cache[table_name][fixture_name] ||= MockedFixtures::MockFactory.create_mock(mock_type, model_class, fixture, self)
94
+ else
95
+ raise StandardError, "No fixture named '#{fixture_name}' was found for table '#{table_name}'"
96
+ end
97
+ end
98
+
99
+ instances.size == 1 ? instances.first : instances
100
+ end
101
+
102
+ end
103
+ end
104
+
105
+ def setup_with_mock_fixtures
106
+ fixtures_to_load = self.class.mock_fixture_table_names - self.class.loaded_mock_fixtures.keys
107
+ return if fixtures_to_load.empty?
108
+ load_mock_fixtures(fixtures_to_load)
109
+ end
110
+ alias_method :setup, :setup_with_mock_fixtures
111
+
112
+ # Loads fixtures to be mocked and cache them in class variable
113
+ def load_mock_fixtures(fixtures_to_load)
114
+ fixtures = MockedFixtures::MockFixtures.create_fixtures(fixture_path, fixtures_to_load, fixture_class_names)
115
+ unless fixtures.nil?
116
+ fixtures.each { |f| self.class.loaded_mock_fixtures[f.table_name] = f }
117
+ end
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,9 @@
1
+ module MockedFixtures
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ require 'active_record/fixtures'
2
+
3
+ require 'mocked_fixtures/testcase'
4
+ require 'mocked_fixtures/schema_parser'
5
+ require 'mocked_fixtures/mock_fixtures'
6
+ require 'mocked_fixtures/mock_factory'
7
+ require 'mocked_fixtures/mock_connection'
8
+ require 'mocked_fixtures/version'
9
+
10
+ if defined?(Spec::Example)
11
+ require 'mocked_fixtures/spec/configuration'
12
+ Test::Unit::TestCase.mocked_fixtures_mock_framework = :rspec
13
+ end
14
+
15
+ MockedFixtures::SchemaParser.schema_path = RAILS_ROOT + '/db/schema.rb'
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/mocked_fixtures.rb'}"
9
+ puts "Loading mocked_fixtures gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/txt2html ADDED
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'mocked_fixtures' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'mocked_fixtures'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
19
+
20
+ version = MockedFixtures::VERSION::STRING
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ begin
4
+ gem 'activerecord-sqlserver-adapter'
5
+ require 'mocked_fixtures/connection_adapters/sqlserver_adapter'
6
+ rescue LoadError
7
+ puts 'Testing ActiveRecord SQLServer Adapter skipped'
8
+ end
9
+
10
+ if defined?(MockedFixtures::ConnectionAdapters::SQLServerAdapter)
11
+ conn = {
12
+ :adapter => 'sqlserver',
13
+ :host => 'localhost',
14
+ :mode => 'odbc',
15
+ :dsn => 'activerecord_unittest',
16
+ :database => 'activerecord_unittest',
17
+ :username => 'rails',
18
+ :password => nil
19
+ }
20
+
21
+ ActiveRecord::Base.establish_connection(conn)
22
+
23
+ ActiveRecord::ConnectionAdapters::SQLServerAdapter.send(:include, MockedFixtures::ConnectionAdapters::SQLServerAdapter)
24
+
25
+ require 'resources/schema.rb'
26
+
27
+ describe MockedFixtures::ConnectionAdapters::SQLServerAdapter do
28
+
29
+ before do
30
+ ActiveRecord::Base.connection.reconnect! unless ActiveRecord::Base.connection.active?
31
+ end
32
+
33
+ it "should allow SchemDumper to dump primary key option for pk other than 'id'" do
34
+ schema = StringIO.new
35
+ dumper = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, schema)
36
+ schema.rewind
37
+ schema.read.should match(/create_table "companies", :primary_key => "cid"/)
38
+ end
39
+
40
+ it "should return primary key and sequence" do
41
+ ActiveRecord::Base.connection.pk_and_sequence_for('companies').should == ['cid', nil]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,6 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe MockedFixtures::MockConnection do
4
+
5
+
6
+ end
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe MockedFixtures::MockFactory do
4
+ before do
5
+ @fixture = {:id => 6, :cid => 6, :name => 'Hot Mocks'}
6
+ end
7
+
8
+ [:rspec, :flexmock, :mocha].each do |type|
9
+ require "mocked_fixtures/mocks/#{type}"
10
+
11
+ describe " with #{type.to_s.titleize} integration" do
12
+ attr_accessor :a_mock
13
+
14
+ before do
15
+ @a_mock = MockedFixtures::MockFactory.create_mock(type, Company, @fixture, self)
16
+ end
17
+
18
+ it "should create mock fixture object" do
19
+ a_mock.should_not be_nil
20
+ end
21
+
22
+ it "should create mock object with all attributes" do
23
+ a_mock.should respond_to(:cid, :name, :address, :created_at, :updated_at)
24
+ end
25
+
26
+ it "should create mock object with attributes value from fixture" do
27
+ a_mock.cid.should == 6
28
+ a_mock.name.should == 'Hot Mocks'
29
+ end
30
+
31
+ it "should create mock with id stubbed to fixture" do
32
+ a_mock.id.should == 6
33
+ end
34
+
35
+ it "should create mock with new_record? stubbed to false" do
36
+ a_mock.new_record?.should be_false
37
+ end
38
+
39
+ it "should create mock with to_param stubbed to id as string" do
40
+ a_mock.to_param.should == "6"
41
+ end
42
+
43
+ it "should create mock with errors stubbed" do
44
+ a_mock.should respond_to(:errors)
45
+ end
46
+
47
+ describe "mock object errors stub" do
48
+ it "should return 0 for count" do
49
+ a_mock.errors.count.should == 0
50
+ end
51
+
52
+ it "should return nil for on(:attribute)" do
53
+ a_mock.errors.on(:name).should be_nil
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe MockedFixtures::MockFixtures do
4
+
5
+ before(:all) do
6
+ # just making sure we don't hit the database at all
7
+ ActiveRecord::Base.connection.disconnect! rescue nil
8
+ end
9
+
10
+ before(:each) do
11
+ @fixture_path = Test::Unit::TestCase.fixture_path
12
+ end
13
+
14
+ it "should return primary key for fixture table" do
15
+ fixtures = MockedFixtures::MockFixtures.create_fixtures(@fixture_path, [:companies])
16
+ fixtures[0].primary_key_name.should == 'cid'
17
+ end
18
+
19
+ it "should create fixtures" do
20
+ fixtures = MockedFixtures::MockFixtures.create_fixtures(@fixture_path, [:companies])
21
+ fixtures.should have(1).instance_of(Fixture)
22
+ fixtures.first['mega_corp'][:name].should == 'Mega Corporation'
23
+ end
24
+
25
+ it "should create fixtures with association values inserted" do
26
+ fixtures = MockedFixtures::MockFixtures.create_fixtures(@fixture_path, [:employees])
27
+ fixtures.first['adam'][:company_id].should == Fixtures.identify('mega_corp')
28
+ end
29
+
30
+ end
@@ -0,0 +1,3 @@
1
+ mega_corp:
2
+ cid: 1
3
+ name: Mega Corporation
@@ -0,0 +1,5 @@
1
+ class Company < ActiveRecord::Base
2
+ set_primary_key 'cid'
3
+
4
+ has_many :employees
5
+ end
@@ -0,0 +1,3 @@
1
+ class Employee < ActiveRecord::Base
2
+ belongs_to :company
3
+ end
@@ -0,0 +1,8 @@
1
+ adam:
2
+ company: mega_corp
3
+ first_name: Adam
4
+ last_name: Meehan
5
+ jane:
6
+ company: mega_corp
7
+ first_name: Jane
8
+ last_name: Doe
@@ -0,0 +1,18 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table "companies", :primary_key => "cid", :force => true do |t|
4
+ t.string "name", :null => false, :unique => true
5
+ t.string "address"
6
+ t.datetime "created_at"
7
+ t.datetime "updated_at"
8
+ end
9
+
10
+ create_table "employees", :force => true do |t|
11
+ t.integer "company_id", :null => false
12
+ t.string "first_name", :null => false, :limit => 25
13
+ t.string "last_name", :null => false, :limit => 25
14
+ t.datetime "created_at"
15
+ t.datetime "updated_at"
16
+ end
17
+
18
+ end
@@ -0,0 +1,31 @@
1
+ ====================================================================
2
+ == RSpec
3
+ Copyright (c) 2005-2007 The RSpec Development Team
4
+ ====================================================================
5
+ == ARTS
6
+ Copyright (c) 2006 Kevin Clark, Jake Howerton
7
+ ====================================================================
8
+ == ZenTest
9
+ Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
10
+ ====================================================================
11
+ == AssertSelect
12
+ Copyright (c) 2006 Assaf Arkin
13
+ ====================================================================
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
16
+ this software and associated documentation files (the "Software"), to deal in
17
+ the Software without restriction, including without limitation the rights to
18
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
19
+ of the Software, and to permit persons to whom the Software is furnished to do
20
+ so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
@@ -0,0 +1,115 @@
1
+ module Spec
2
+ module Rails
3
+
4
+ class IllegalDataAccessException < StandardError; end
5
+
6
+ module Mocks
7
+
8
+ # Creates a mock object instance for a +model_class+ with common
9
+ # methods stubbed out. Additional methods may be easily stubbed (via
10
+ # add_stubs) if +stubs+ is passed.
11
+ def mock_model(model_class, options_and_stubs = {})
12
+ id = options_and_stubs[:id] || next_id
13
+ options_and_stubs.reverse_merge!({
14
+ :id => id,
15
+ :to_param => id.to_s,
16
+ :new_record? => false,
17
+ :errors => stub("errors", :count => 0)
18
+ })
19
+ m = mock("#{model_class.name}_#{options_and_stubs[:id]}", options_and_stubs)
20
+ m.send(:__mock_proxy).instance_eval <<-CODE
21
+ def @target.is_a?(other)
22
+ #{model_class}.ancestors.include?(other)
23
+ end
24
+ def @target.kind_of?(other)
25
+ #{model_class}.ancestors.include?(other)
26
+ end
27
+ def @target.instance_of?(other)
28
+ other == #{model_class}
29
+ end
30
+ def @target.class
31
+ #{model_class}
32
+ end
33
+ CODE
34
+ yield m if block_given?
35
+ m
36
+ end
37
+
38
+ # :call-seq:
39
+ # stub_model(Model)
40
+ # stub_model(Model).as_new_record
41
+ # stub_model(Model, hash_of_stubs)
42
+ #
43
+ # Creates an instance of +Model+ that is prohibited from accessing the
44
+ # database. For each key in +hash_of_stubs+, if the model has a
45
+ # matching attribute (determined by asking it, which it answers based
46
+ # on schema.rb) are simply assigned the submitted values. If the model
47
+ # does not have a matching attribute, the key/value pair is assigned
48
+ # as a stub return value using RSpec's mocking/stubbing framework.
49
+ #
50
+ # new_record? is overridden to return the result of id.nil? This means
51
+ # that by default new_record? will return false. If you want the
52
+ # object to behave as a new record, sending it +as_new_record+ will
53
+ # set the id to nil. You can also explicitly set :id => nil, in which
54
+ # case new_record? will return true, but using +as_new_record+ makes
55
+ # the example a bit more descriptive.
56
+ #
57
+ # While you can use stub_model in any example (model, view,
58
+ # controller, helper), it is especially useful in view examples,
59
+ # which are inherently more state-based than interaction-based.
60
+ #
61
+ # == Examples
62
+ #
63
+ # stub_model(Person)
64
+ # stub_model(Person).as_new_record
65
+ # stub_model(Person, :id => 37)
66
+ # stub_model(Person) do |person|
67
+ # model.first_name = "David"
68
+ # end
69
+ def stub_model(model_class, stubs = {})
70
+ stubs = {:id => next_id}.merge(stubs)
71
+ returning model_class.new do |model|
72
+ model.id = stubs.delete(:id)
73
+ (class << model; self; end).class_eval do
74
+ def connection
75
+ raise Spec::Rails::IllegalDataAccessException.new("stubbed models are not allowed to access the database")
76
+ end
77
+ def new_record?
78
+ id.nil?
79
+ end
80
+ def as_new_record
81
+ self.id = nil
82
+ self
83
+ end
84
+ end
85
+ stubs.each do |k,v|
86
+ if model.has_attribute?(k)
87
+ model[k] = stubs.delete(k)
88
+ end
89
+ end
90
+ add_stubs(model, stubs)
91
+ yield model if block_given?
92
+ end
93
+ end
94
+
95
+ #--
96
+ # TODO - Shouldn't this just be an extension of stub! ??
97
+ # - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc)
98
+ #++
99
+ # Stubs methods on +object+ (if +object+ is a symbol or string a new mock
100
+ # with that name will be created). +stubs+ is a Hash of <tt>method=>value</tt>
101
+ def add_stubs(object, stubs = {}) #:nodoc:
102
+ m = [String, Symbol].index(object.class) ? mock(object.to_s) : object
103
+ stubs.each {|k,v| m.stub!(k).and_return(v)}
104
+ m
105
+ end
106
+
107
+ private
108
+ @@model_id = 1000
109
+ def next_id
110
+ @@model_id += 1
111
+ end
112
+
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec/interop/test'
2
+
3
+ ActionView::Base.cache_template_extensions = false
4
+
5
+ module Spec
6
+ module Rails
7
+
8
+ module Example
9
+ class RailsExampleGroup < Test::Unit::TestCase
10
+
11
+ # Rails >= r8570 uses setup/teardown_fixtures explicitly
12
+ before(:each) do
13
+ setup_fixtures if self.respond_to?(:setup_fixtures)
14
+ end
15
+ after(:each) do
16
+ teardown_fixtures if self.respond_to?(:teardown_fixtures)
17
+ end
18
+
19
+ include Spec::Rails::Matchers
20
+ include Spec::Rails::Mocks
21
+
22
+ Spec::Example::ExampleGroupFactory.default(self)
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Spec
2
+ module Rails
3
+ module Matchers; end
4
+ end
5
+ end
6
+
7
+ module ActionView
8
+ class Base
9
+ def self.cache_template_extensions=(arg)
10
+ end
11
+ end
12
+ end
13
+
14
+ require 'rspec-rails/mocks'
15
+ require 'rspec-rails/rails_example_group'