activewarehouse-etl 0.9.5.rc1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/.standalone_migrations +2 -0
  2. data/.travis.yml +15 -0
  3. data/CHANGELOG +10 -1
  4. data/HOW_TO_RELEASE +4 -0
  5. data/LICENSE +1 -1
  6. data/README.textile +111 -0
  7. data/Rakefile +37 -78
  8. data/activewarehouse-etl.gemspec +7 -4
  9. data/db/migrate/20120229203554_create_tables.rb +37 -0
  10. data/db/schema.rb +45 -0
  11. data/examples/database.example.yml +3 -3
  12. data/lib/etl.rb +16 -0
  13. data/lib/etl/commands/etl.rb +1 -0
  14. data/lib/etl/control/control.rb +1 -1
  15. data/lib/etl/control/destination.rb +5 -16
  16. data/lib/etl/control/destination/csv_destination.rb +122 -0
  17. data/lib/etl/control/destination/excel_destination.rb +1 -1
  18. data/lib/etl/control/destination/insert_update_database_destination.rb +6 -3
  19. data/lib/etl/control/destination/yaml_destination.rb +74 -0
  20. data/lib/etl/control/source.rb +39 -4
  21. data/lib/etl/control/source/database_source.rb +6 -1
  22. data/lib/etl/control/source/file_source.rb +4 -0
  23. data/lib/etl/control/source/mysql_streamer.rb +31 -0
  24. data/lib/etl/engine.rb +40 -20
  25. data/lib/etl/parser/{delimited_parser.rb → csv_parser.rb} +3 -3
  26. data/lib/etl/parser/excel_parser.rb +1 -1
  27. data/lib/etl/parser/nokogiri_xml_parser.rb +83 -0
  28. data/lib/etl/processor/bulk_import_processor.rb +11 -0
  29. data/lib/etl/processor/check_exist_processor.rb +6 -6
  30. data/lib/etl/processor/check_unique_processor.rb +4 -0
  31. data/lib/etl/processor/database_join_processor.rb +25 -4
  32. data/lib/etl/processor/encode_processor.rb +0 -2
  33. data/lib/etl/processor/ensure_fields_presence_processor.rb +24 -0
  34. data/lib/etl/processor/imapattachment_downloader_processor.rb +2 -2
  35. data/lib/etl/processor/pop3attachment_downloader_processor.rb +2 -2
  36. data/lib/etl/processor/row_processor.rb +10 -0
  37. data/lib/etl/processor/sftp_downloader_processor.rb +1 -1
  38. data/lib/etl/processor/sftp_uploader_processor.rb +1 -1
  39. data/lib/etl/processor/truncate_processor.rb +4 -1
  40. data/lib/etl/processor/zip_file_processor.rb +1 -1
  41. data/lib/etl/transform/foreign_key_lookup_transform.rb +57 -15
  42. data/lib/etl/transform/md5_transform.rb +13 -0
  43. data/lib/etl/transform/{string_to_datetime_transform.rb → string_to_date_time_transform.rb} +0 -0
  44. data/lib/etl/version.rb +1 -1
  45. data/test/.gitignore +0 -1
  46. data/test/check_exist_processor_test.rb +89 -0
  47. data/test/check_unique_processor_test.rb +40 -0
  48. data/test/config/.gitignore +1 -0
  49. data/test/config/database.yml +28 -0
  50. data/test/config/{Gemfile.rails-3.0.x → gemfiles/Gemfile.rails-3.0.x} +1 -1
  51. data/test/config/{Gemfile.rails-2.3.x → gemfiles/Gemfile.rails-3.1.x} +1 -1
  52. data/test/config/gemfiles/Gemfile.rails-3.2.x +3 -0
  53. data/test/config/gemfiles/common.rb +29 -0
  54. data/test/control_test.rb +2 -2
  55. data/test/data/nokogiri.xml +38 -0
  56. data/test/database_join_processor_test.rb +43 -0
  57. data/test/delimited.ctl +1 -1
  58. data/test/delimited_absolute.ctl +1 -3
  59. data/test/delimited_destination_db.ctl +1 -3
  60. data/test/delimited_excel.ctl +1 -1
  61. data/test/delimited_insert_update.ctl +1 -1
  62. data/test/delimited_update.ctl +1 -1
  63. data/test/delimited_with_bulk_load.ctl +2 -2
  64. data/test/destination_test.rb +0 -4
  65. data/test/encode_processor_test.rb +2 -0
  66. data/test/engine_test.rb +65 -19
  67. data/test/ensure_fields_presence_processor_test.rb +33 -0
  68. data/test/foreign_key_lookup_transform_test.rb +50 -0
  69. data/test/multiple_delimited.ctl +1 -1
  70. data/test/multiple_source_delimited.ctl +2 -2
  71. data/test/nokogiri_all.ctl +35 -0
  72. data/test/nokogiri_select.ctl +35 -0
  73. data/test/nokogiri_test.rb +35 -0
  74. data/test/parser_test.rb +2 -2
  75. data/test/performance/delimited.ctl +1 -1
  76. data/test/processor_test.rb +0 -3
  77. data/test/scd_test.rb +2 -8
  78. data/test/scd_test_type_1.ctl +1 -1
  79. data/test/scd_test_type_2.ctl +1 -1
  80. data/test/screen_test.rb +2 -3
  81. data/test/source_test.rb +19 -6
  82. data/test/test_helper.rb +6 -8
  83. data/test/truncate_processor_test.rb +37 -0
  84. metadata +121 -144
  85. data/README +0 -101
  86. data/active_support_logger.patch +0 -78
  87. data/test-matrix.yml +0 -10
  88. data/test/config/Gemfile.rails-2.3.x.lock +0 -38
  89. data/test/config/Gemfile.rails-3.0.x.lock +0 -49
  90. data/test/config/common.rb +0 -21
  91. data/test/connection/mysql/connection.rb +0 -9
  92. data/test/connection/mysql/schema.sql +0 -36
  93. data/test/connection/postgresql/connection.rb +0 -13
  94. data/test/connection/postgresql/schema.sql +0 -39
  95. data/test/vendor/adapter_extensions-0.5.0/CHANGELOG +0 -26
  96. data/test/vendor/adapter_extensions-0.5.0/LICENSE +0 -16
  97. data/test/vendor/adapter_extensions-0.5.0/README +0 -7
  98. data/test/vendor/adapter_extensions-0.5.0/Rakefile +0 -158
  99. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions.rb +0 -12
  100. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions/connection_adapters/abstract_adapter.rb +0 -44
  101. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions/connection_adapters/mysql_adapter.rb +0 -63
  102. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions/connection_adapters/postgresql_adapter.rb +0 -52
  103. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions/connection_adapters/sqlserver_adapter.rb +0 -44
  104. data/test/vendor/adapter_extensions-0.5.0/lib/adapter_extensions/version.rb +0 -10
@@ -0,0 +1,13 @@
1
+ require 'digest/md5'
2
+
3
+ module ETL #:nodoc:
4
+ module Transform #:nodoc:
5
+ # Transform which hashes the original value with a MD5 hash algorithm
6
+ class Md5Transform < ETL::Transform::Transform
7
+ # Transform the value with a MD5 digest algorithm.
8
+ def transform(name, value, row)
9
+ Digest::MD5.hexdigest(value)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module ETL#:nodoc:
2
- VERSION = "0.9.5.rc1"
2
+ VERSION = "1.0.0.rc1"
3
3
  end
@@ -1 +0,0 @@
1
- database*.yml
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class CheckExistProcessorTest < Test::Unit::TestCase
4
+
5
+ context 'CheckExistProcessor' do
6
+
7
+ setup do
8
+ @config = {
9
+ :target => :data_warehouse,
10
+ :table => 'people',
11
+ :columns => [:first_name, :last_name]
12
+ }
13
+ end
14
+
15
+ should_eventually "compare based on all columns if no columns are provided" do
16
+ # TBI
17
+ end
18
+
19
+ should_eventually "compare based on all columns except skipped ones if columns to skip are provided" do
20
+ # TBI
21
+ end
22
+
23
+ should "raise an error if no table is provided" do
24
+ error = assert_raises(ETL::ControlError) do
25
+ ETL::Processor::CheckExistProcessor.new(nil, @config.except(:table))
26
+ end
27
+ # bug #2413 on assert_raises won't let me check error message above
28
+ assert_equal 'table must be specified', error.message
29
+ end
30
+
31
+ should "raise an error if no target is provided" do
32
+ error = assert_raises(ETL::ControlError) do
33
+ ETL::Processor::CheckExistProcessor.new(nil, @config.except(:target))
34
+ end
35
+
36
+ assert_equal 'target must be specified', error.message
37
+ end
38
+
39
+ should "bypass checking if the table has no rows" do
40
+ Person.delete_all
41
+
42
+ processor = ETL::Processor::CheckExistProcessor.new(nil, @config)
43
+ assert_equal false, processor.should_check?
44
+ end
45
+
46
+ should "raise an error if one of the keys used for checking existence is not available in a row" do
47
+ Person.delete_all
48
+ # we need at least one record to avoid automatic skipping
49
+ # this should be mocked instead, probably
50
+ Person.create!(:first_name => 'John', :last_name => 'Barry', :ssn => '1234')
51
+
52
+ error = assert_raise(ETL::ControlError) do
53
+ row = ETL::Row[:first_name => 'John']
54
+ processor = ETL::Processor::CheckExistProcessor.new(nil, @config)
55
+
56
+ # guard against bypassing
57
+ assert_equal true, processor.should_check?
58
+
59
+ processor.process(row)
60
+ end
61
+
62
+ assert_equal "Row missing required field :last_name for existence check", error.message
63
+ end
64
+
65
+ should "return nil if the same row is found in database" do
66
+ Person.delete_all
67
+ Person.create!(:first_name => 'John', :last_name => 'Barry', :ssn => '1234')
68
+
69
+ row = ETL::Row[:first_name => 'John', :last_name => 'Barry']
70
+ processor = ETL::Processor::CheckExistProcessor.new(nil, @config)
71
+ assert_equal true, processor.should_check? # guard against bypassing
72
+
73
+ assert_equal nil, processor.process(row)
74
+ end
75
+
76
+ should "return the row if no same row is found in database" do
77
+ Person.delete_all
78
+ Person.create!(:first_name => 'John', :last_name => 'Barry', :ssn => '1234')
79
+
80
+ row = ETL::Row[:first_name => 'John', :last_name => 'OtherName']
81
+ processor = ETL::Processor::CheckExistProcessor.new(nil, @config)
82
+ assert_equal true, processor.should_check? # guard against bypassing
83
+
84
+ assert_equal row, processor.process(row)
85
+ end
86
+
87
+ end
88
+
89
+ end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class CheckUniqueProcessorTest < Test::Unit::TestCase
4
+
5
+ context 'CheckUniqueProcessor' do
6
+ attr_reader :processor
7
+
8
+ setup do
9
+ @processor = ETL::Processor::CheckUniqueProcessor.new(nil,
10
+ :keys => [:first, :second])
11
+ end
12
+
13
+ should "keep a row whose keys didn't already appear in the pipeline" do
14
+ row = ETL::Row[:first => 'A', :second => 'B']
15
+
16
+ assert_equal row, processor.process(row)
17
+
18
+ assert_equal({ 'A|B' => 1 }, processor.compound_key_constraints)
19
+ end
20
+
21
+ should "remove a row whose keys already appeared in the pipeline" do
22
+ row = ETL::Row[:first => 'A', :second => 'B']
23
+
24
+ assert_equal row, processor.process(row)
25
+ assert_equal nil, processor.process(row)
26
+ end
27
+
28
+ should "raise an error if a row lacks one of the keys specified" do
29
+ row = ETL::Row[:first => 'A']
30
+
31
+ error = assert_raises(ETL::ControlError) do
32
+ processor.process(row)
33
+ end
34
+
35
+ assert_equal "Row missing required field :second for unicity check", error.message
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1 @@
1
+ *.lock
@@ -0,0 +1,28 @@
1
+ <% raise "ENV['DB'] not specified!" unless ENV['DB'] %>
2
+
3
+ # a bit hackish - tests would require a refactoring instead
4
+
5
+ mysql2: &mysql2
6
+ adapter: mysql2
7
+ database: activewarehouse_etl_test
8
+ username: root
9
+ encoding: utf8
10
+ local_infile: true
11
+ # the tests would require a rework: disabling casting for now
12
+ cast: false
13
+
14
+ postgresql: &postgresql
15
+ adapter: postgresql
16
+ database: activewarehouse_etl_test
17
+ username: postgres
18
+
19
+ # TODO - refactor test to avoid using 2 databases maybe?
20
+ operational_database:
21
+ <<: *<%= ENV['DB'] %>
22
+
23
+ data_warehouse:
24
+ <<: *<%= ENV['DB'] %>
25
+
26
+ etl_execution:
27
+ adapter: mysql2
28
+ database: etl_execution
@@ -1,3 +1,3 @@
1
1
  require File.dirname(__FILE__) + '/common'
2
2
 
3
- common_gemfile('3.0.7')
3
+ declare_gems '3.0.11'
@@ -1,3 +1,3 @@
1
1
  require File.dirname(__FILE__) + '/common'
2
2
 
3
- common_gemfile('2.3.11')
3
+ declare_gems '3.1.3'
@@ -0,0 +1,3 @@
1
+ require File.dirname(__FILE__) + '/common'
2
+
3
+ declare_gems '3.2.1'
@@ -0,0 +1,29 @@
1
+ def declare_gems(activerecord_version)
2
+ source :rubygems
3
+
4
+ gem 'activerecord', activerecord_version
5
+ gem 'adapter_extensions', :git => 'https://github.com/activewarehouse/adapter_extensions.git', :branch => 'rails-3'
6
+
7
+ if activerecord_version < '3.1'
8
+ gem 'mysql2', '< 0.3'
9
+ else
10
+ # use our own fork for bulk load support until issue fixed:
11
+ # https://github.com/brianmario/mysql2/pull/242
12
+ gem 'mysql2', :git => 'https://github.com/activewarehouse/mysql2.git'
13
+ end
14
+
15
+ gem 'pg'
16
+ gem 'activerecord-sqlserver-adapter'
17
+
18
+ gem 'awesome_print'
19
+ gem 'rake'
20
+ gem 'flexmock'
21
+ gem 'shoulda', '3.0.1'
22
+ gem 'sqlite3'
23
+
24
+ gem 'spreadsheet'
25
+ gem 'nokogiri'
26
+ gem 'fastercsv'
27
+
28
+ gem 'standalone_migrations'
29
+ end
@@ -4,8 +4,8 @@ class ControlTest < Test::Unit::TestCase
4
4
  # Test the ability to parse control files.
5
5
  def test_parse
6
6
  assert_nothing_raised do
7
- Dir.glob('*.ctl') do |f|
8
- ETL::Control::Control.parse(File.join(File.dirname(__FILE__), f))
7
+ Dir.glob(File.join(File.dirname(__FILE__), '*.ctl')) do |f|
8
+ ETL::Control::Control.parse(f)
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,38 @@
1
+ <?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
2
+ <!DOCTYPE people >
3
+ <people>
4
+ <person ssn="123456789" type="employee">
5
+ <first_name>Bob</first_name>
6
+ <last_name>Smith</last_name>
7
+ <email>bsmith@foo.com</email>
8
+ <colours>
9
+ <eyes>brown</eyes>
10
+ <hair>black</hair>
11
+ <skin>fair</skin>
12
+ </colours>
13
+ <age>24</age>
14
+ </person>
15
+ <person ssn="111223333" type="client">
16
+ <first_name>Jane</first_name>
17
+ <last_name>Doe</last_name>
18
+ <email>jdoe@bar.com</email>
19
+ <colours>
20
+ <eyes>blue</eyes>
21
+ <hair>blond</hair>
22
+ <skin>medium</skin>
23
+ </colours>
24
+ <age>45</age>
25
+ </person>
26
+ <person ssn="133244566" type="client">
27
+ <first_name>Jake</first_name>
28
+ <last_name>Smithsonian</last_name>
29
+ <email>jake@example.com</email>
30
+ <colours>
31
+ <eyes>brown</eyes>
32
+ <hair>black</hair>
33
+ <skin>dark</skin>
34
+ </colours>
35
+ <age>37</age>
36
+ </person>
37
+ </people>
38
+
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class DatabaseJoinProcessorTest < Test::Unit::TestCase
4
+
5
+ def new_processor(options)
6
+ ETL::Processor::DatabaseJoinProcessor.new(nil, options)
7
+ end
8
+
9
+ should 'raise an error unless :fields is specified' do
10
+ error = assert_raises(ETL::ControlError) { new_processor({}) }
11
+ assert_equal ":target must be specified", error.message
12
+ end
13
+
14
+ should 'return the row and the database result' do
15
+ row = ETL::Row[:id => 1, :first_name => 'Bob', :last_name => 'Smith', :ssn => '111234444']
16
+ control = ETL::Control::Control.parse(File.dirname(__FILE__) +
17
+ '/delimited.ctl')
18
+
19
+ Person.delete_all
20
+ assert_equal 0, Person.count
21
+
22
+ # First define a basic configuration to check defaults
23
+ configuration = {
24
+ :target => :data_warehouse,
25
+ :database => 'etl_unittest',
26
+ :table => 'people',
27
+ :buffer_size => 0
28
+ }
29
+ mapping = { :order => [:id, :first_name, :last_name, :ssn] }
30
+ dest = ETL::Control::DatabaseDestination.new(control, configuration, mapping)
31
+ dest.write(row)
32
+ dest.close
33
+
34
+ assert_equal 1, Person.find(:all).length
35
+
36
+ row = ETL::Row[:last_name => "Smith"]
37
+ processor = new_processor(:target => :data_warehouse,
38
+ :query => "SELECT first_name FROM people WHERE last_name = \#{connection.quote(row[:last_name])}",
39
+ :fields => ["first_name"]).process(row)
40
+ assert_equal row[:first_name], "Bob"
41
+ end
42
+
43
+ end
@@ -1,7 +1,7 @@
1
1
  source :in, {
2
2
  :file => 'data/delimited.txt',
3
3
  :parser => {
4
- :name => :delimited
4
+ :name => :csv
5
5
  }
6
6
  },
7
7
  [
@@ -1,9 +1,7 @@
1
- # puts "executing delimited.ctl"
2
-
3
1
  source :in, {
4
2
  :file => '/tmp/delimited_abs.txt',
5
3
  :parser => {
6
- :name => :delimited
4
+ :name => :csv
7
5
  }
8
6
  },
9
7
  [
@@ -1,8 +1,6 @@
1
- # puts "executing delimited.ctl"
2
-
3
1
  source :in, {
4
2
  :file => 'data/delimited.txt',
5
- :parser => :delimited
3
+ :parser => :csv
6
4
  },
7
5
  [
8
6
  :id,
@@ -1,7 +1,7 @@
1
1
  source :in, {
2
2
  :file => 'data/delimited.txt',
3
3
  :parser => {
4
- :name => :delimited
4
+ :name => :csv
5
5
  }
6
6
  },
7
7
  [
@@ -1,7 +1,7 @@
1
1
  source :in, {
2
2
  :file => 'data/delimited.txt',
3
3
  :parser => {
4
- :name => :delimited
4
+ :name => :csv
5
5
  }
6
6
  },
7
7
  [
@@ -1,7 +1,7 @@
1
1
  source :in, {
2
2
  :file => 'data/delimited.txt',
3
3
  :parser => {
4
- :name => :delimited
4
+ :name => :csv
5
5
  }
6
6
  },
7
7
  [
@@ -4,7 +4,7 @@ outfile = 'output/people.txt'
4
4
  source :in, {
5
5
  :file => infile,
6
6
  :parser => {
7
- :name => :delimited
7
+ :name => :csv
8
8
  }
9
9
  },
10
10
  [
@@ -13,7 +13,7 @@ source :in, {
13
13
  ]
14
14
 
15
15
  before_write :surrogate_key, :target => :data_warehouse, :table => 'person_dimension', :column => 'id'
16
- before_write :check_exists, {
16
+ before_write :check_exist, {
17
17
  :target => :data_warehouse,
18
18
  :table => 'person_dimension',
19
19
  :columns => [:first_name, :last_name]
@@ -1,10 +1,6 @@
1
- require 'rubygems'
2
1
  require 'spreadsheet'
3
2
  require File.dirname(__FILE__) + '/test_helper'
4
3
 
5
- class Person < ActiveRecord::Base
6
- end
7
-
8
4
  class BadDestination < ETL::Control::Destination
9
5
  def initialize(control, configuration, mapping)
10
6
  super
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
  require File.dirname(__FILE__) + '/test_helper'
3
3
 
4
+ require 'iconv'
5
+
4
6
  class EncodeProcessorTest < Test::Unit::TestCase
5
7
 
6
8
  SOURCE = 'data/encode_source_latin1.txt'
@@ -1,32 +1,78 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class EngineTest < Test::Unit::TestCase
4
+
5
+ context 'process' do
4
6
 
5
- def test_connections
6
- assert_equal 3, ActiveRecord::Base.configurations.length
7
- conn = ETL::Engine.connection(:data_warehouse)
8
- assert_not_nil conn
9
- end
10
-
11
- def test_non_existent_connection
12
- assert_raise ETL::ETLError do
13
- conn = ETL::Engine.connection(:does_not_exist)
7
+ should 'raise an error when a file which does not exist is given' do
8
+ error = assert_raise(Errno::ENOENT) do
9
+ ETL::Engine.process('foo-bar.ctl')
10
+ end
11
+
12
+ assert_equal "No such file or directory - foo-bar.ctl", error.message
13
+ end
14
+
15
+ should 'raise an error when an unknown file type is given' do
16
+ error = assert_raise(RuntimeError) do
17
+ ETL::Engine.process(__FILE__)
18
+ end
19
+
20
+ assert_match /Unsupported file type/, error.message
14
21
  end
22
+
23
+ should_eventually 'stop as soon as the error threshold is reached' do
24
+ engine = ETL::Engine.new
25
+
26
+ assert_equal 0, engine.errors.size
27
+
28
+ engine.process ETL::Control::Control.parse_text <<CTL
29
+ set_error_threshold 1
30
+ source :in, { :type => :enumerable, :enumerable => (1..100) }
31
+ after_read { |row| raise "Failure" }
32
+ CTL
33
+
34
+ assert_equal 1, engine.errors.size
35
+ end
36
+
15
37
  end
16
38
 
17
- def test_engine_table_method_should_return_same_name_when_not_using_temp_tables
18
- assert_equal 'foo', ETL::Engine.table('foo', connection)
19
- end
39
+ context 'connection' do
20
40
 
21
- def test_engine_table_method_should_return_temp_name_when_using_temp_tables
22
- ETL::Engine.use_temp_tables = true
23
- assert_equal 'tmp_people', ETL::Engine.table('people', connection)
24
- ETL::Engine.use_temp_tables = false
41
+ should 'return an ActiveRecord configuration by name' do
42
+ assert_not_nil ETL::Engine.connection(:data_warehouse)
43
+ end
44
+
45
+ should 'raise an error on non existent connection' do
46
+ error = assert_raise(ETL::ETLError) do
47
+ ETL::Engine.connection(:does_not_exist)
48
+ end
49
+ assert_equal "Cannot find connection named :does_not_exist", error.message
50
+ end
51
+
52
+ should 'raise an error when requesting a connection with no name' do
53
+ error = assert_raise(ETL::ETLError) do
54
+ ETL::Engine.connection(" ")
55
+ end
56
+ assert_equal "Connection with no name requested. Is there a missing :target parameter somewhere?", error.message
57
+ end
25
58
  end
26
59
 
27
- protected
28
- def connection
29
- ETL::Engine.connection(:data_warehouse)
60
+ context 'temp tables' do
61
+ attr_reader :connection
62
+
63
+ setup do
64
+ @connection = ETL::Engine.connection(:data_warehouse)
65
+ end
66
+
67
+ should 'return unmodified table name when temp tables are disabled' do
68
+ assert_equal 'foo', ETL::Engine.table('foo', ETL::Engine.connection(:data_warehouse))
69
+ end
70
+
71
+ should 'return temp table name instead of table name when temp tables are enabled' do
72
+ ETL::Engine.use_temp_tables = true
73
+ assert_equal 'tmp_people', ETL::Engine.table('people', connection)
74
+ ETL::Engine.use_temp_tables = false
75
+ end
30
76
  end
31
77
 
32
78
  end