unit_record 0.4.1 → 0.9.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 (48) hide show
  1. data/CHANGELOG +14 -0
  2. data/LICENSE +20 -0
  3. data/README.markdown +137 -0
  4. data/Rakefile +63 -56
  5. data/lib/active_record/connection_adapters/unit_record_adapter.rb +97 -0
  6. data/lib/unit_record.rb +8 -1
  7. data/lib/unit_record/association_stubbing.rb +39 -0
  8. data/lib/unit_record/column_extension.rb +11 -0
  9. data/lib/unit_record/disconnected_active_record.rb +10 -32
  10. data/lib/unit_record/disconnected_test_case.rb +6 -0
  11. data/test/active_record/connection_adapters/unit_record_adapter_test.rb +103 -0
  12. data/test/db/schema.rb +9 -0
  13. data/test/sample_spec.rb +40 -0
  14. data/test/test_helper.rb +28 -4
  15. data/test/unit_record/association_stubbing_test.rb +37 -0
  16. data/test/unit_record/column_cacher_test.rb +26 -0
  17. data/test/{unit → unit_record}/column_extension_test.rb +1 -1
  18. data/test/{functional → unit_record}/column_test.rb +1 -1
  19. data/test/{functional → unit_record}/controller_test.rb +1 -1
  20. data/test/unit_record/disconnected_active_record_test.rb +52 -0
  21. data/test/{functional → unit_record}/disconnected_fixtures_test.rb +1 -1
  22. data/test/unit_record/disconnected_test_case_test.rb +19 -0
  23. data/vendor/dust-0.1.6/lib/array_extension.rb +5 -0
  24. data/vendor/dust-0.1.6/lib/definition_error.rb +20 -0
  25. data/vendor/dust-0.1.6/lib/dust.rb +8 -0
  26. data/vendor/dust-0.1.6/lib/nil_extension.rb +5 -0
  27. data/vendor/dust-0.1.6/lib/object_extension.rb +62 -0
  28. data/vendor/dust-0.1.6/lib/string_extension.rb +5 -0
  29. data/vendor/dust-0.1.6/lib/symbol_extension.rb +5 -0
  30. data/vendor/dust-0.1.6/lib/test_case_extension.rb +76 -0
  31. data/vendor/dust-0.1.6/rakefile.rb +50 -0
  32. data/vendor/dust-0.1.6/test/all_tests.rb +1 -0
  33. data/vendor/dust-0.1.6/test/failing_with_helper_unit_test.rb +16 -0
  34. data/vendor/dust-0.1.6/test/failing_with_setup_unit_test.rb +16 -0
  35. data/vendor/dust-0.1.6/test/functional_test.rb +12 -0
  36. data/vendor/dust-0.1.6/test/passing_unit_test.rb +11 -0
  37. data/vendor/dust-0.1.6/test/passing_with_helper_unit_test.rb +10 -0
  38. data/vendor/dust-0.1.6/test/passing_with_helpers_unit_test.rb +13 -0
  39. data/vendor/dust-0.1.6/test/passing_with_setup_unit_test.rb +10 -0
  40. data/vendor/dust-0.1.6/test/test_helper.rb +1 -0
  41. metadata +75 -52
  42. data/README +0 -60
  43. data/lib/unit_record/column_cacher.rb +0 -45
  44. data/test/functional/column_cacher_test.rb +0 -19
  45. data/test/functional/disconnected_active_record_test.rb +0 -33
  46. data/test/functional/disconnected_test_case_test.rb +0 -7
  47. data/test/functional/functional_test_helper.rb +0 -4
  48. data/test/unit/unit_test_helper.rb +0 -5
@@ -0,0 +1,39 @@
1
+ module UnitRecord
2
+ module AssociationStubbing
3
+
4
+ private
5
+
6
+ def initialize_with_association_stubbing(attributes = {})
7
+ attributes ||= {}
8
+ associations = extract_associations attributes
9
+ initialize_without_association_stubbing attributes
10
+ stub_associations associations
11
+ end
12
+
13
+ protected
14
+
15
+ def extract_associations(attributes = {})
16
+ attributes.inject({}) do |associations,(attr,value)|
17
+ next associations unless self.class.reflections.keys.include? attr
18
+ unless value.is_a?(self.class.reflections[attr].klass)
19
+ associations[attr] = attributes.delete attr
20
+ end
21
+ associations
22
+ end
23
+ end
24
+
25
+ def stub_associations(associations = {})
26
+ associations.each do |attr,value|
27
+ self.stubs(attr).returns(value)
28
+ end
29
+ end
30
+
31
+ def self.included(klass)
32
+ klass.class_eval do
33
+ unless (instance_methods + private_instance_methods).include?("initialize_without_association_stubbing")
34
+ alias_method_chain :initialize, :association_stubbing
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,16 @@
1
1
  module UnitRecord
2
2
  module ColumnExtension
3
+ def self.included(base)
4
+ base.class_eval do
5
+ alias_method_chain :simplified_type, :boolean
6
+ end
7
+ end
8
+
9
+ def simplified_type_with_boolean(field_type)
10
+ return :boolean if field_type.to_s.downcase.index("tinyint(1)")
11
+ simplified_type_without_boolean field_type
12
+ end
13
+
3
14
  def ==(other)
4
15
  other && instance_variables.all? { |ivar| instance_variable_get(ivar) == other.instance_variable_get(ivar) }
5
16
  end
@@ -1,43 +1,21 @@
1
1
  module UnitRecord
2
2
  module DisconnectedActiveRecord
3
3
  def disconnected?
4
- false
4
+ connected? && connection.is_a?(ActiveRecord::ConnectionAdapters::UnitRecordAdapter)
5
5
  end
6
- def disconnect!
6
+
7
+ def disconnect!(options = {})
7
8
  return if disconnected?
8
- (class << self; self; end).class_eval do
9
- def cache
10
- yield
11
- end
12
-
13
- def cached_columns
14
- @@_cached_columns ||= {}
15
- end
16
-
17
- def columns
18
- cached_columns[table_name] ||
19
- raise("Columns are not cached for '#{table_name}' - check schema.rb")
20
- end
21
-
22
- def connection
23
- raise "(from #{to_s}): ActiveRecord is disconnected; database access is unavailable in unit tests."
24
- end
25
-
26
- def connected?
27
- false
28
- end
29
-
30
- def disconnected?
31
- true
32
- end
33
-
34
- def table_exists?
35
- true
36
- end
9
+ establish_connection options.merge(:adapter => "unit_record")
10
+ if options[:stub_associations]
11
+ ActiveRecord::Base.send :include, UnitRecord::AssociationStubbing
37
12
  end
38
13
  Fixtures.disconnect!
39
14
  Test::Unit::TestCase.disconnect!
40
- ColumnCacher.cache(RAILS_ROOT + "/db/schema.rb")
15
+ ActiveRecord::Migration.verbose = false
16
+ ActiveRecord::Base.connection.change_strategy(:noop) do
17
+ load(RAILS_ROOT + "/db/schema.rb")
18
+ end
41
19
  end
42
20
  end
43
21
  end
@@ -2,6 +2,12 @@ module UnitRecord
2
2
  module DisconnectedTestCase
3
3
  def disconnect!
4
4
  self.use_transactional_fixtures = false
5
+
6
+ class_eval do
7
+ def self.fixtures(*args)
8
+ raise "Fixtures cannot be used with UnitRecord. ActiveRecord is disconnected; database access is unavailable in unit tests."
9
+ end
10
+ end
5
11
  end
6
12
  end
7
13
  end
@@ -0,0 +1,103 @@
1
+ require File.dirname(__FILE__) + "/../../test_helper"
2
+
3
+ functional_tests do
4
+
5
+ test "reconnect works" do
6
+ ActiveRecord::Base.connection.reconnect!
7
+ assert_kind_of ActiveRecord::ConnectionAdapters::UnitRecordAdapter,
8
+ ActiveRecord::Base.connection
9
+ end
10
+
11
+ test "find(:all)" do
12
+ ActiveRecord::Base.connection.change_strategy(:raise) do
13
+ assert_raises(RuntimeError) { Person.find(:all) }
14
+ end
15
+ ActiveRecord::Base.connection.change_strategy(:noop) do
16
+ assert_equal [], Person.find(:all)
17
+ end
18
+ end
19
+
20
+ test "execute raises an exception" do
21
+ assert_raises_disconnected_exception do
22
+ ActiveRecord::Base.connection.execute "SELECT 1"
23
+ end
24
+ end
25
+
26
+ test "select_rows raises an exception" do
27
+ assert_raises_disconnected_exception do
28
+ ActiveRecord::Base.connection.select_rows "SELECT * FROM people"
29
+ end
30
+ end
31
+
32
+ test "select raises an exception" do
33
+ assert_raises_disconnected_exception do
34
+ ActiveRecord::Base.connection.send :select, "SELECT * FROM people"
35
+ end
36
+ end
37
+
38
+ test "rename_table raises an exception" do
39
+ assert_raises_disconnected_exception do
40
+ ActiveRecord::Base.connection.rename_table "people", "persons"
41
+ end
42
+ end
43
+
44
+ test "change_column raises an exception" do
45
+ assert_raises_disconnected_exception do
46
+ ActiveRecord::Base.connection.change_column "people", "first_name", :string, :null => false
47
+ end
48
+ end
49
+
50
+ test "change_column_default raises an exception" do
51
+ assert_raises_disconnected_exception do
52
+ ActiveRecord::Base.connection.change_column_default "people", "first_person", "george"
53
+ end
54
+ end
55
+
56
+ test "rename_column raises an exception" do
57
+ assert_raises_disconnected_exception do
58
+ ActiveRecord::Base.connection.rename_column "people", "first_name", "name_first"
59
+ end
60
+ end
61
+
62
+ test "insert raises an exception" do
63
+ assert_raises_disconnected_exception do
64
+ ActiveRecord::Base.connection.rename_column "people", "first_name", "name_first"
65
+ end
66
+ end
67
+
68
+ test "initialize can set strategy" do
69
+ ActiveRecord::Base.establish_connection :adapter => "unit_record", :strategy => :noop
70
+ assert_nil ActiveRecord::Base.connection.execute("SELECT 1")
71
+ ActiveRecord::Base.establish_connection :adapter => "unit_record", :strategy => :raise
72
+ assert_raises(RuntimeError) { ActiveRecord::Base.connection.execute("SELECT 1") }
73
+ end
74
+
75
+ test "noop" do
76
+ ActiveRecord::Base.connection.change_strategy(:noop) do
77
+ assert_nil ActiveRecord::Base.connection.execute("SELECT 1")
78
+ assert_nil ActiveRecord::Base.connection.insert("INSERT INTO ...")
79
+ assert_equal [], ActiveRecord::Base.connection.select_rows("SELECT * FROM people")
80
+ assert_equal [], ActiveRecord::Base.connection.send(:select, "SELECT * FROM people")
81
+ assert_nil ActiveRecord::Base.connection.rename_table("people", "persons")
82
+ assert_nil ActiveRecord::Base.connection.change_column("people", "first_name", :string, :null => false)
83
+ assert_nil ActiveRecord::Base.connection.change_column_default("people", "first_person", "george")
84
+ assert_nil ActiveRecord::Base.connection.rename_column("people", "first_name", "name_first")
85
+ end
86
+ end
87
+
88
+ test "change_strategy raises if invalid strategy" do
89
+ assert_nothing_raised { ActiveRecord::Base.connection.change_strategy(:noop) {} }
90
+ assert_nothing_raised { ActiveRecord::Base.connection.change_strategy(:raise) {} }
91
+ assert_raises(ArgumentError) { ActiveRecord::Base.connection.change_strategy(:bogus) {} }
92
+ end
93
+
94
+ def assert_raises_disconnected_exception(&block)
95
+ exception = nil
96
+ begin
97
+ yield
98
+ rescue Exception => exception
99
+ end
100
+ assert_not_nil exception
101
+ assert_equal "ActiveRecord is disconnected; database access is unavailable in unit tests.", exception.message
102
+ end
103
+ end
data/test/db/schema.rb CHANGED
@@ -9,6 +9,15 @@ ActiveRecord::Schema.define(:version => 0) do
9
9
  t.column :last_name, :string
10
10
  end
11
11
 
12
+ create_table "profiles", :force => true do |t|
13
+ t.column "description", :string
14
+ t.column "person_id", :integer
15
+ end
16
+
17
+ create_table :pets, :force => true do |t|
18
+ t.column :name, :string
19
+ end
20
+
12
21
  create_table :foofoo, :force => true do |t|
13
22
  t.column :bar, :string
14
23
  end
@@ -0,0 +1,40 @@
1
+ require "rubygems"
2
+ gem "rspec", "1.1.11"
3
+ require "test/unit"
4
+ require "spec"
5
+
6
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
7
+
8
+ RAILS_ROOT = File.dirname(__FILE__)
9
+
10
+ if rails_version = ENV['RAILS_VERSION']
11
+ gem "rails", rails_version
12
+ end
13
+ require "rails/version"
14
+ puts "==== Testing with Rails #{Rails::VERSION::STRING} ===="
15
+ require 'active_record'
16
+ require 'active_record/fixtures'
17
+ require "action_controller"
18
+ require "action_controller/test_process"
19
+
20
+ require "unit_record"
21
+
22
+ # Needed because of this line in setup_with_fixtures and teardown_with_fixtures:
23
+ # return unless defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
24
+ ActiveRecord::Base.configurations = {"irrelevant" => {:adapter => "stub"}}
25
+
26
+ ActiveRecord::Base.disconnect! :strategy => :raise, :stub_associations => true
27
+
28
+ describe UnitRecord do
29
+ it "disconnects tests from the database" do
30
+ lambda do
31
+ ActiveRecord::Base.connection.select_value("SELECT 1")
32
+ end.should raise_error
33
+ end
34
+
35
+ it "can change strategy to noop" do
36
+ ActiveRecord::Base.connection.change_strategy(:noop) do
37
+ ActiveRecord::Base.connection.select_value("SELECT 1").should == nil
38
+ end
39
+ end
40
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ unless defined?(TEST_HELPER_LOADED)
2
+ TEST_HELPER_LOADED = true
1
3
  $:.unshift(File.dirname(__FILE__) + '/../lib')
2
4
  RAILS_ROOT = File.dirname(__FILE__)
3
5
 
@@ -8,6 +10,7 @@ if rails_version = ENV['RAILS_VERSION']
8
10
  gem "rails", rails_version
9
11
  end
10
12
  require "rails/version"
13
+ puts "==== Testing with Rails #{Rails::VERSION::STRING} ===="
11
14
  require 'active_record'
12
15
  require 'active_record/fixtures'
13
16
  require "action_controller"
@@ -17,14 +20,17 @@ end
17
20
  require "action_controller/test_process"
18
21
 
19
22
  begin
23
+ gem "mocha"
20
24
  require 'mocha'
21
- require 'dust'
22
- rescue LoadError
23
- raise "Need Mocha and Dust gems to Test"
25
+ rescue LoadError, Gem::LoadError
26
+ raise "need mocha to test"
24
27
  end
28
+ $LOAD_PATH << File.dirname(__FILE__) + "/../vendor/dust-0.1.6/lib"
29
+ require 'dust'
25
30
  Test::Unit::TestCase.disallow_setup!
26
31
 
27
- require "#{File.dirname(__FILE__)}/../init"
32
+ $LOAD_PATH << File.dirname(__FILE__) + "/../lib"
33
+ require "unit_record"
28
34
 
29
35
  Test::Unit::TestCase.use_transactional_fixtures = true
30
36
 
@@ -34,11 +40,29 @@ ActiveRecord::Base.configurations = {"irrelevant" => {:adapter => "stub"}}
34
40
 
35
41
  class Preference < ActiveRecord::Base
36
42
  end
43
+
37
44
  class Person < ActiveRecord::Base
45
+ has_many :pets
46
+ has_one :profile
47
+ end
48
+
49
+ class Profile < ActiveRecord::Base
50
+ belongs_to :person
51
+ end
52
+
53
+ class Pet < ActiveRecord::Base
54
+ belongs_to :person
38
55
  end
56
+
39
57
  class Foo < ActiveRecord::Base
40
58
  set_table_name :foofoo
41
59
  end
60
+
42
61
  class DoesNotExist < ActiveRecord::Base
43
62
  set_table_name "table_does_not_exist"
44
63
  end
64
+
65
+ ActiveRecord::Base.disconnect! :strategy => :raise, :stub_associations => true
66
+ # make sure calling disconnect multiple times does not cause problems
67
+ ActiveRecord::Base.disconnect! :strategy => :raise, :stub_associations => true
68
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ functional_tests do
4
+
5
+ test "stubbing a has_many" do
6
+ pets = [stub, stub]
7
+ person = Person.new :pets => pets
8
+ assert_equal pets, person.pets
9
+ end
10
+
11
+ test "stubbing a belongs_to" do
12
+ person = stub
13
+ pet = Pet.new :person => person
14
+ assert_equal person, pet.person
15
+ end
16
+
17
+ test "using correct classes does not stub" do
18
+ person = Person.new(:first_name => "Dan")
19
+ pet = Pet.new :person => person
20
+ pet.person = Person.new(:first_name => "Tom")
21
+ assert_equal "Tom", pet.person.first_name
22
+ end
23
+
24
+ test "using other than correct classes does stub" do
25
+ person = Object.new
26
+ def person.first_name; "Dan"; end
27
+ pet = Pet.new :person => person
28
+ pet.person = Person.new(:first_name => "Tom")
29
+ assert_equal "Dan", pet.person.first_name
30
+ end
31
+
32
+ test "multiple includes doesn't hurt" do
33
+ ActiveRecord::Base.send :include, UnitRecord::AssociationStubbing
34
+ Person.new
35
+ end
36
+
37
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ functional_tests do
4
+ test "caching columns with no defaults or not nulls" do
5
+ expected = [
6
+ ActiveRecord::ConnectionAdapters::Column.new("id", nil, "int(11) DEFAULT NULL auto_increment PRIMARY KEY", nil),
7
+ ActiveRecord::ConnectionAdapters::Column.new("first_name", nil, "varchar(255)", nil),
8
+ ActiveRecord::ConnectionAdapters::Column.new("last_name", nil, "varchar(255)", nil)
9
+ ]
10
+ expected[0].primary = true
11
+ expected[1..-1].each { |column| column.primary = false }
12
+ assert_equal expected, Person.columns
13
+ end
14
+
15
+ test "caching column with default" do
16
+ expected = ActiveRecord::ConnectionAdapters::Column.new("show_help", true, "tinyint(1)", nil)
17
+ expected.primary = false
18
+ assert_equal expected, Preference.columns.detect { |c| c.name == "show_help" }
19
+ end
20
+
21
+ test "boolean columns" do
22
+ expected = ActiveRecord::ConnectionAdapters::Column.new("show_help", true, "tinyint(1)", nil)
23
+ expected.primary = false
24
+ assert_equal :boolean, Preference.columns.detect { |c| c.name == "show_help" }.type
25
+ end
26
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/unit_test_helper"
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
2
 
3
3
  unit_tests do
4
4
  test "equality" do
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/functional_test_helper"
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
2
 
3
3
  functional_tests do
4
4
  test "instantiating" do
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/functional_test_helper'
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
2
 
3
3
  class SampleController < ActionController::Base
4
4
  def sample_action
@@ -0,0 +1,52 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ functional_tests do
4
+ test "find_by_sql gives disconnected exception message" do
5
+ exception = nil
6
+ begin
7
+ Person.find_by_sql "SELECT * FROM people"
8
+ rescue => exception
9
+ end
10
+ assert_not_nil exception
11
+ assert_equal "ActiveRecord is disconnected; database access is unavailable in unit tests.", exception.message
12
+ end
13
+
14
+ test "connected? is true" do
15
+ assert_equal true, ActiveRecord::Base.connected?
16
+ end
17
+
18
+ test "disconnected? is true" do
19
+ assert_equal true, ActiveRecord::Base.disconnected?
20
+ end
21
+
22
+ test "inspect does not blow up" do
23
+ assert_nothing_raised { Person.inspect }
24
+ end
25
+
26
+ test "table_exists?" do
27
+ assert_equal true, Person.table_exists?
28
+ if ActiveRecord::Base.connection.respond_to?(:table_exists?)
29
+ assert_equal false, ActiveRecord::Base.connection.table_exists?("bogus_table")
30
+ end
31
+ end
32
+
33
+ test "setting a has_one association" do
34
+ person = Person.new
35
+ person.profile = Profile.new
36
+ end
37
+
38
+ test "boolean columns do type casting" do
39
+ pref = Preference.new
40
+ pref.show_help = "0"
41
+ assert_equal false, pref.send(:read_attribute, :show_help)
42
+ assert_equal false, pref.show_help
43
+ assert_equal false, pref.show_help?
44
+ pref.show_help = "1"
45
+ assert_equal true, pref.show_help
46
+ assert_equal true, pref.show_help?
47
+ end
48
+
49
+ test "migrations are not verbose" do
50
+ assert_equal false, ActiveRecord::Migration.verbose
51
+ end
52
+ end