mocked_fixtures 0.1.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 (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'