unit_record 0.1.0 → 0.2.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.
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