unit_record 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -17,11 +17,7 @@ One huge benefit to disconnecting unit tests from the database is having a faste
17
17
 
18
18
  == Installation
19
19
 
20
- The traditional way:
21
- ruby script/plugin install http://unit-test-ar.rubyforge.org/svn/trunk/unit_record/
22
-
23
- Or with piston:
24
- piston import http://unit-test-ar.rubyforge.org/svn/trunk/unit_record/ vendor/plugins/unit_record
20
+ gem install unit_record
25
21
 
26
22
  == Usage
27
23
 
@@ -46,24 +42,23 @@ The <tt>functional_test_helper.rb</tt> file should require <tt>test_helper.rb</t
46
42
 
47
43
  For moving unit tests, you have a few options. I recommend moving them to unit/models and then disconnecting your unit tests from the database. Any tests that fail should then be modified to not hit the database or moved to functional/models.
48
44
 
49
- == Caching Columns
50
-
51
- The plugin disconnects models from the database by caching the column metadata. This is done through a rake task:
52
- rake db:columns:dump
53
-
54
- The rake task creates a db/columns.rb file which will be used in the tests. If you have a custom build/test rake task, you may just want to insert this task before you run your unit tests. Otherwise, you can automatically have it run before <tt>test:units</tt> as so:
55
- Rake::Task["test:units"].enhance ["db:columns:dump"]
56
-
57
45
  == Disconnecting
58
46
 
59
47
  In the <tt>test/unit/unit_test_helper.rb</tt> file you created when restructuring your test directory, you should add these lines:
60
48
  require File.dirname(__FILE__) + "/../test_helper"
49
+ require "unit_record"
61
50
  ActiveRecord::Base.disconnect!
62
51
 
63
- The <tt>disconnect!</tt> method will do everything necessary (including loading the columns.rb file) to run your unit tests without hitting the database.
52
+ The <tt>disconnect!</tt> method will do everything necessary to run your unit tests without hitting the database. For now, it connects to the database and caches the columns in a file (db/columns.rb) before disconnecting. A later version will not need to connect at all.
53
+
54
+ == Limitations
55
+
56
+ * UnitRecord currently only works when all models use convention for table names.
64
57
 
65
58
  == Thanks
66
59
  Thanks to Jay Fields for the original implementation:
67
60
  http://blog.jayfields.com/2007/03/rails-activerecord-unit-testing-part-ii.html
68
61
 
69
- Copyright (c) 2007 Dan Manges, released under the MIT license.
62
+ == License
63
+ Released under Ruby's license.
64
+ http://www.ruby-lang.org/en/LICENSE.txt
data/Rakefile CHANGED
@@ -8,24 +8,22 @@ desc "Default: run tests"
8
8
  task :default => :test
9
9
 
10
10
  desc "Run all tests"
11
- task :test => %w[test:caching test:disconnecting]
11
+ task :test => %w[test:unit test:functional]
12
12
 
13
- desc "Run the tests for caching columns"
14
- Rake::TestTask.new("test:caching") do |t|
13
+ Rake::TestTask.new("test:unit") do |t|
15
14
  t.libs << 'lib'
16
- t.pattern = 'test/caching/**/*_test.rb'
15
+ t.pattern = 'test/unit/**/*_test.rb'
17
16
  t.verbose = true
18
17
  end
19
18
 
20
- desc "Run the tests for disconnecting"
21
- Rake::TestTask.new("test:disconnecting") do |t|
19
+ Rake::TestTask.new("test:functional") do |t|
22
20
  t.libs << 'lib'
23
- t.pattern = 'test/disconnecting/**/*_test.rb'
21
+ t.pattern = 'test/functional/**/*_test.rb'
24
22
  t.verbose = true
25
23
  end
26
24
 
27
25
  desc "Generate documentation"
28
- Rake::RDocTask.new(:doc) do |rdoc|
26
+ Rake::RDocTask.new(:rdoc) do |rdoc|
29
27
  rdoc.rdoc_dir = "doc"
30
28
  rdoc.title = "UnitRecord"
31
29
  rdoc.options << '--line-numbers'
@@ -42,7 +40,7 @@ Gem::manage_gems
42
40
  specification = Gem::Specification.new do |s|
43
41
  s.name = "unit_record"
44
42
  s.summary = "UnitRecord enables unit testing without hitting the database."
45
- s.version = "0.1.0"
43
+ s.version = "0.2.0"
46
44
  s.author = "Dan Manges"
47
45
  s.description = "UnitRecord enables unit testing without hitting the database."
48
46
  s.email = "daniel.manges@gmail.com"
data/lib/unit_record.rb CHANGED
@@ -1,8 +1,12 @@
1
- require "unit_record/column_dumper"
1
+ require "unit_record/column_cacher"
2
+ require "unit_record/column_extension"
2
3
  require "unit_record/disconnected_active_record"
3
4
  require "unit_record/disconnected_test_case"
4
5
  require "unit_record/disconnected_fixtures"
6
+
7
+ require "active_record/fixtures"
8
+
9
+ ActiveRecord::ConnectionAdapters::Column.send :include, UnitRecord::ColumnExtension
5
10
  ActiveRecord::Base.extend UnitRecord::DisconnectedActiveRecord
6
11
  Test::Unit::TestCase.extend UnitRecord::DisconnectedTestCase
7
- require "active_record/fixtures"
8
12
  Fixtures.extend UnitRecord::DisconnectedFixtures
@@ -0,0 +1,54 @@
1
+ module UnitRecord
2
+ class ColumnCacher
3
+ include ActiveRecord::ConnectionAdapters::SchemaStatements
4
+
5
+ def self.cache(file)
6
+ (class << ActiveRecord::Schema; self; end).class_eval do
7
+ def define(options={}, &block)
8
+ UnitRecord::ColumnCacher.new.instance_eval(&block)
9
+ end
10
+ end
11
+ load file
12
+ end
13
+
14
+ def add_index(table_name, column_name, options = {})
15
+ end
16
+
17
+ def create_table(table_name, options={})
18
+ table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
19
+ table_definition.primary_key(options[:primary_key] || "id") unless options[:id] == false
20
+ yield table_definition
21
+ if model = model_for_table(table_name)
22
+ (class << model; self; end).class_eval do
23
+ define_method(:columns) do
24
+ table_definition.columns.map do |c|
25
+ ActiveRecord::ConnectionAdapters::Column.new(c.name.to_s, c.default, c.sql_type, c.null)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def native_database_types
33
+ # Copied from the MysqlAdapter so ColumnDefinition#sql_type will work
34
+ {
35
+ :primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY",
36
+ :string => { :name => "varchar", :limit => 255 },
37
+ :text => { :name => "text" },
38
+ :integer => { :name => "int", :limit => 11 },
39
+ :float => { :name => "float" },
40
+ :decimal => { :name => "decimal" },
41
+ :datetime => { :name => "datetime" },
42
+ :timestamp => { :name => "datetime" },
43
+ :time => { :name => "time" },
44
+ :date => { :name => "date" },
45
+ :binary => { :name => "blob" },
46
+ :boolean => { :name => "tinyint", :limit => 1 }
47
+ }
48
+ end
49
+
50
+ def model_for_table(table)
51
+ table.to_s.classify.constantize rescue nil
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ module UnitRecord
2
+ module ColumnExtension
3
+ def ==(other)
4
+ other && instance_variables.all? { |ivar| instance_variable_get(ivar) == other.instance_variable_get(ivar) }
5
+ end
6
+ end
7
+ end
@@ -5,10 +5,6 @@ module UnitRecord
5
5
  end
6
6
  def disconnect!
7
7
  return if disconnected?
8
- columns_file = File.join(RAILS_ROOT, "db", "columns.rb")
9
- File.open(columns_file, "w") do |file|
10
- UnitRecord::ColumnDumper.dump(ActiveRecord::Base.connection, file)
11
- end
12
8
  (class << self; self; end).class_eval do
13
9
  def connection
14
10
  raise "ActiveRecord is disconnected; database access is unavailable in unit tests."
@@ -20,9 +16,11 @@ module UnitRecord
20
16
  true
21
17
  end
22
18
  end
23
- load columns_file
24
19
  Fixtures.disconnect!
25
20
  Test::Unit::TestCase.disconnect!
21
+ old_columns_file = File.join(RAILS_ROOT, 'db', 'columns.rb')
22
+ File.delete old_columns_file if File.exists?(old_columns_file)
23
+ ColumnCacher.cache(RAILS_ROOT + "/db/schema.rb")
26
24
  end
27
25
  end
28
26
  end
data/test/db/schema.rb ADDED
@@ -0,0 +1,13 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :preferences, :force => true do |t|
3
+ t.column :some_count, :integer
4
+ t.column :show_help, :boolean, :default => true
5
+ end
6
+
7
+ create_table :people, :force => true do |t|
8
+ t.column :first_name, :string
9
+ t.column :last_name, :string
10
+ end
11
+
12
+ add_index "people", ["first_name"]
13
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/functional_test_helper"
2
+
3
+ functional_tests do
4
+ test "caching columns with no defaults or not nulls" do
5
+ assert_equal [
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
+ ], Person.columns
10
+ end
11
+
12
+ test "caching column with default" do
13
+ assert_equal ActiveRecord::ConnectionAdapters::Column.new("show_help", true, "tinyint(1)", nil), Preference.columns.detect { |c| c.name == "show_help" }
14
+ end
15
+
16
+ test "add_index does not blow up" do
17
+ assert_nothing_raised { UnitRecord::ColumnCacher.new.add_index("people", "first_name") }
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + "/functional_test_helper"
2
+
3
+ functional_tests do
4
+ test "instantiating" do
5
+ person = Person.new :first_name => "Dan", :last_name => "Manges"
6
+ assert_equal "Dan", person.first_name
7
+ assert_equal "Manges", person.last_name
8
+ end
9
+
10
+ test "using model with column with a default" do
11
+ record = Preference.new
12
+ assert_equal true, record.show_help?
13
+ end
14
+
15
+ test "typecasting happens for integer attributes" do
16
+ record = Preference.new
17
+ record.some_count = "42"
18
+ assert_equal 42, record.some_count
19
+ end
20
+
21
+ test "" do
22
+ end
23
+ end
@@ -1,7 +1,7 @@
1
- require File.dirname(__FILE__) + "/./disconnecting_test_helper"
1
+ require File.dirname(__FILE__) + "/./functional_test_helper"
2
2
  # The '.' is intentional to have a TestCase require a different relative path.
3
3
 
4
- class DisconnectedActiveRecordTest < Test::Unit::TestCase
4
+ functional_tests do
5
5
  test "accessing connection raises" do
6
6
  assert_raises(RuntimeError) { ActiveRecord::Base.connection }
7
7
  end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + "/functional_test_helper"
2
+
3
+ functional_tests do
4
+ test "create_fixtures does nothing" do
5
+ assert_nothing_raised { Fixtures.create_fixtures }
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
- require File.dirname(__FILE__) + "/disconnecting_test_helper"
1
+ require File.dirname(__FILE__) + "/functional_test_helper"
2
2
 
3
- class DisconnectedTestCaseTest < Test::Unit::TestCase
3
+ functional_tests do
4
4
  test "use_transactional_fixtures is false" do
5
5
  assert_equal false, Test::Unit::TestCase.use_transactional_fixtures
6
6
  end
data/test/test_helper.rb CHANGED
@@ -13,17 +13,13 @@ begin
13
13
  rescue LoadError
14
14
  raise "Need Mocha and Dust gems to Test"
15
15
  end
16
-
17
- ActiveRecord::Base.configurations['test'] = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
18
- ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
19
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'][ENV['DB'] || 'sqlite3'])
16
+ Test::Unit::TestCase.disallow_setup!
20
17
 
21
18
  require "#{File.dirname(__FILE__)}/../init"
22
- silence_stream(STDOUT) do
23
- load(File.dirname(__FILE__) + "/schema.rb") if File.exist?(File.dirname(__FILE__) + "/schema.rb")
24
- end
25
19
 
26
20
  Test::Unit::TestCase.use_transactional_fixtures = true
27
21
 
22
+ class Preference < ActiveRecord::Base
23
+ end
28
24
  class Person < ActiveRecord::Base
29
25
  end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + "/../test_helper"
2
+
3
+ unit_tests do
4
+ test "equality" do
5
+ column1 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
6
+ column2 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
7
+ assert_equal column1, column2
8
+ end
9
+
10
+ test "non-equality on name" do
11
+ column1 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
12
+ column2 = ActiveRecord::ConnectionAdapters::Column.new("different name", nil, :string, nil)
13
+ assert column1 != column2
14
+ end
15
+
16
+ test "non-equality on sql_type" do
17
+ column1 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
18
+ column2 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :text, nil)
19
+ assert column1 != column2
20
+ end
21
+
22
+ test "non-equality on default" do
23
+ column1 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
24
+ column2 = ActiveRecord::ConnectionAdapters::Column.new("name", "Dan", :string, nil)
25
+ assert column1 != column2
26
+ end
27
+
28
+ test "non-equality on null" do
29
+ column1 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, nil)
30
+ column2 = ActiveRecord::ConnectionAdapters::Column.new("name", nil, :string, true)
31
+ assert column1 != column2
32
+ end
33
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.3
3
3
  specification_version: 1
4
4
  name: unit_record
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2007-08-15 00:00:00 -04:00
6
+ version: 0.2.0
7
+ date: 2007-08-16 00:00:00 -04:00
8
8
  summary: UnitRecord enables unit testing without hitting the database.
9
9
  require_paths:
10
10
  - lib
@@ -30,18 +30,20 @@ authors:
30
30
  - Dan Manges
31
31
  files:
32
32
  - lib/unit_record.rb
33
- - lib/unit_record/column_dumper.rb
33
+ - lib/unit_record/column_cacher.rb
34
+ - lib/unit_record/column_extension.rb
34
35
  - lib/unit_record/disconnected_active_record.rb
35
36
  - lib/unit_record/disconnected_fixtures.rb
36
37
  - lib/unit_record/disconnected_test_case.rb
37
- - test/schema.rb
38
38
  - test/test_helper.rb
39
- - test/caching/column_dumper_test.rb
40
- - test/db/columns.rb
41
- - test/disconnecting/disconnected_active_record_test.rb
42
- - test/disconnecting/disconnected_fixtures_test.rb
43
- - test/disconnecting/disconnected_test_case_test.rb
44
- - test/disconnecting/disconnecting_test_helper.rb
39
+ - test/db/schema.rb
40
+ - test/functional/column_cacher_test.rb
41
+ - test/functional/column_test.rb
42
+ - test/functional/disconnected_active_record_test.rb
43
+ - test/functional/disconnected_fixtures_test.rb
44
+ - test/functional/disconnected_test_case_test.rb
45
+ - test/functional/functional_test_helper.rb
46
+ - test/unit/column_extension_test.rb
45
47
  - Rakefile
46
48
  - init.rb
47
49
  - README
@@ -1,52 +0,0 @@
1
- require 'erb'
2
- module UnitRecord
3
- class ColumnDumper
4
- private_class_method :new
5
-
6
- def self.dump(connection, stream)
7
- new(connection).write_to(stream)
8
- end
9
-
10
- def initialize(connection)
11
- @connection = connection
12
- end
13
-
14
- def columns_by_model
15
- @columns_by_model ||= tables.inject({}) do |hash,table|
16
- model = model_for_table(table)
17
- hash[model.to_s] = columns(table) if model
18
- hash
19
- end
20
- end
21
-
22
- def columns(table)
23
- @connection.columns(table)
24
- end
25
-
26
- def model_for_table(table)
27
- table.classify.constantize rescue nil
28
- end
29
-
30
- def tables
31
- @connection.tables
32
- end
33
-
34
- def write_to(stream)
35
- template = ERB.new <<-END, nil, '-'
36
- <% columns_by_model.keys.sort.each do |model| -%>
37
- <%= model %>.class_eval do
38
- def self.columns
39
- [
40
- <%- columns_by_model[model].each do |column| -%>
41
- ActiveRecord::ConnectionAdapters::Column.new(<%= column.name.to_s.inspect %>, <%= column.default.inspect %>, <%= column.sql_type.inspect %>, <%= column.null.inspect%>),
42
- <%- end -%>
43
- ]
44
- end
45
- end
46
- <%- end -%>
47
- END
48
- text = template.result binding
49
- stream.write text
50
- end
51
- end
52
- end
@@ -1,20 +0,0 @@
1
- require File.dirname(__FILE__) + "/../test_helper"
2
-
3
- class ColumnDumperTest < Test::Unit::TestCase
4
- test "dumping columns" do
5
- stream = StringIO.new
6
- UnitRecord::ColumnDumper.dump(ActiveRecord::Base.connection, stream)
7
- expected = <<-END
8
- Person.class_eval do
9
- def self.columns
10
- [
11
- ActiveRecord::ConnectionAdapters::Column.new("id", nil, "INTEGER", false),
12
- ActiveRecord::ConnectionAdapters::Column.new("first_name", nil, "varchar(255)", true),
13
- ActiveRecord::ConnectionAdapters::Column.new("last_name", nil, "varchar(255)", true),
14
- ]
15
- end
16
- end
17
- END
18
- assert_equal expected, stream.string
19
- end
20
- end
data/test/db/columns.rb DELETED
@@ -1,9 +0,0 @@
1
- Person.class_eval do
2
- def self.columns
3
- [
4
- ActiveRecord::ConnectionAdapters::Column.new("id", nil, "INTEGER", false),
5
- ActiveRecord::ConnectionAdapters::Column.new("first_name", nil, "varchar(255)", true),
6
- ActiveRecord::ConnectionAdapters::Column.new("last_name", nil, "varchar(255)", true),
7
- ]
8
- end
9
- end
@@ -1,7 +0,0 @@
1
- require File.dirname(__FILE__) + "/disconnecting_test_helper"
2
-
3
- class DisconnectedTestCaseTest < Test::Unit::TestCase
4
- test "create_fixtures does nothing" do
5
- assert_nothing_raised { Fixtures.create_fixtures }
6
- end
7
- end
data/test/schema.rb DELETED
@@ -1,6 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
- create_table :people do |t|
3
- t.column :first_name, :string
4
- t.column :last_name, :string
5
- end
6
- end