data_miner 3.0.0.alpha → 3.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/CHANGELOG +12 -0
- data/data_miner.gemspec +3 -1
- data/lib/data_miner.rb +1 -0
- data/lib/data_miner/active_record_class_methods.rb +1 -0
- data/lib/data_miner/script.rb +35 -0
- data/lib/data_miner/step.rb +16 -0
- data/lib/data_miner/step/import.rb +30 -0
- data/lib/data_miner/step/test.rb +77 -0
- data/lib/data_miner/version.rb +1 -1
- data/spec/spec_helper.rb +25 -0
- data/spec/test_step_spec.rb +134 -0
- data/test/helper.rb +1 -49
- data/test/support/database.rb +50 -0
- data/test/support/pet.rb +7 -0
- metadata +42 -2
data/.rspec
ADDED
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
3.0.0.beta / 2013-07-26
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
|
5
|
+
* test steps with after: and every: options, referring to row counts in the previous step
|
6
|
+
* :limit option for import steps - oh yeah
|
7
|
+
* :random_skip option - goes nicely with :limit if you're debugging
|
8
|
+
|
9
|
+
* Bug fixes
|
10
|
+
|
11
|
+
* Make sure to stringify data_miner(:append) option
|
12
|
+
|
1
13
|
3.0.0.alpha / 2013-07-24
|
2
14
|
|
3
15
|
* breaking changes
|
data/data_miner.gemspec
CHANGED
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.add_runtime_dependency 'posix-spawn'
|
26
26
|
s.add_runtime_dependency 'unix_utils'
|
27
27
|
s.add_runtime_dependency 'roo', '>=1.10.3'
|
28
|
-
|
28
|
+
s.add_runtime_dependency 'rspec-expectations'
|
29
|
+
|
30
|
+
s.add_development_dependency 'rspec'
|
29
31
|
s.add_development_dependency 'pry'
|
30
32
|
s.add_development_dependency 'active_record_inline_schema'
|
31
33
|
s.add_development_dependency 'fuzzy_match'
|
data/lib/data_miner.rb
CHANGED
data/lib/data_miner/script.rb
CHANGED
@@ -92,6 +92,36 @@ class DataMiner
|
|
92
92
|
append(:process, method_id_or_description, &blk)
|
93
93
|
end
|
94
94
|
|
95
|
+
# A step that runs tests and stops the data miner on failures.
|
96
|
+
#
|
97
|
+
# rspec-expectations are automatically included.
|
98
|
+
#
|
99
|
+
# @see DataMiner::ActiveRecordClassMethods#data_miner Overview of how to define data miner scripts inside of ActiveRecord models.
|
100
|
+
# @see DataMiner::Step::Test The actual Test class.
|
101
|
+
#
|
102
|
+
# @param [String] description A description of what the block does.
|
103
|
+
# @param [Hash] settings Settings
|
104
|
+
# @option settings [String] :after After how many rows of the previous step to run the tests.
|
105
|
+
# @yield [] Tests to be run
|
106
|
+
#
|
107
|
+
# @example Tests
|
108
|
+
# data_miner do
|
109
|
+
# [...]
|
110
|
+
# test "make sure something works" do
|
111
|
+
# expect(Pet.count).to be > 10
|
112
|
+
# end
|
113
|
+
# [...]
|
114
|
+
# test "make sure something works", after: 20 do
|
115
|
+
# [...]
|
116
|
+
# end
|
117
|
+
# [...]
|
118
|
+
# end
|
119
|
+
#
|
120
|
+
# @return [nil]
|
121
|
+
def test(description, settings = {}, &blk)
|
122
|
+
append(:test, description, settings, &blk)
|
123
|
+
end
|
124
|
+
|
95
125
|
# Import rows into your model.
|
96
126
|
#
|
97
127
|
# As long as...
|
@@ -217,6 +247,11 @@ class DataMiner
|
|
217
247
|
Script.current_stack.clear
|
218
248
|
end
|
219
249
|
Script.current_stack << model_name
|
250
|
+
steps.each do |step|
|
251
|
+
steps.each do |other|
|
252
|
+
other.register step
|
253
|
+
end
|
254
|
+
end
|
220
255
|
steps.each do |step|
|
221
256
|
step.start
|
222
257
|
model.reset_column_information
|
data/lib/data_miner/step.rb
CHANGED
@@ -12,5 +12,21 @@ class DataMiner
|
|
12
12
|
def model
|
13
13
|
script.model
|
14
14
|
end
|
15
|
+
|
16
|
+
def pos
|
17
|
+
script.steps.index self
|
18
|
+
end
|
19
|
+
|
20
|
+
def register(step)
|
21
|
+
# noop
|
22
|
+
end
|
23
|
+
|
24
|
+
def notify(*args)
|
25
|
+
# noop
|
26
|
+
end
|
27
|
+
|
28
|
+
def target?(*args)
|
29
|
+
false
|
30
|
+
end
|
15
31
|
end
|
16
32
|
end
|
@@ -20,6 +20,17 @@ class DataMiner
|
|
20
20
|
# @return [String]
|
21
21
|
attr_reader :description
|
22
22
|
|
23
|
+
# Max number of rows to import.
|
24
|
+
# @return [Numeric]
|
25
|
+
attr_reader :limit
|
26
|
+
|
27
|
+
# Number from zero to one representing what percentage of rows to skip. Defaults to 0, of course :)
|
28
|
+
# @return [Numeric]
|
29
|
+
attr_reader :random_skip
|
30
|
+
|
31
|
+
# @private
|
32
|
+
attr_reader :listeners
|
33
|
+
|
23
34
|
# @private
|
24
35
|
def initialize(script, description, settings, &blk)
|
25
36
|
settings = settings.stringify_keys
|
@@ -41,6 +52,9 @@ class DataMiner
|
|
41
52
|
@table_settings = settings.dup
|
42
53
|
@table_settings['streaming'] = true
|
43
54
|
@table_mutex = ::Mutex.new
|
55
|
+
@limit = settings.fetch 'limit', (1.0/0)
|
56
|
+
@random_skip = settings['random_skip']
|
57
|
+
@listeners = []
|
44
58
|
instance_eval(&blk)
|
45
59
|
end
|
46
60
|
|
@@ -94,6 +108,12 @@ class DataMiner
|
|
94
108
|
@validate_query == true
|
95
109
|
end
|
96
110
|
|
111
|
+
def register(step)
|
112
|
+
if step.target?(self)
|
113
|
+
listeners << step
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
97
117
|
private
|
98
118
|
|
99
119
|
def upsert_enabled?
|
@@ -110,7 +130,9 @@ class DataMiner
|
|
110
130
|
count = 0
|
111
131
|
Upsert.stream(c, model.table_name) do |upsert|
|
112
132
|
table.each do |row|
|
133
|
+
next if random_skip and random_skip > Kernel.rand
|
113
134
|
$stderr.puts "#{count}..." if count_every > 0 and count % count_every == 0
|
135
|
+
break if count > limit
|
114
136
|
count += 1
|
115
137
|
selector = @key ? { @key => attributes[@key].read(row) } : { model.primary_key => nil }
|
116
138
|
document = attrs_except_key.inject({}) do |memo, attr|
|
@@ -125,6 +147,9 @@ class DataMiner
|
|
125
147
|
memo
|
126
148
|
end
|
127
149
|
upsert.row selector, document
|
150
|
+
listeners.select! do |listener|
|
151
|
+
listener.notify self, count
|
152
|
+
end
|
128
153
|
end
|
129
154
|
end
|
130
155
|
model.connection_pool.checkin c
|
@@ -133,11 +158,16 @@ class DataMiner
|
|
133
158
|
def save_with_find_or_initialize
|
134
159
|
count = 0
|
135
160
|
table.each do |row|
|
161
|
+
next if random_skip and random_skip > Kernel.rand
|
136
162
|
$stderr.puts "#{count}..." if count_every > 0 and count % count_every == 0
|
163
|
+
break if count > limit
|
137
164
|
count += 1
|
138
165
|
record = @key ? model.send("find_or_initialize_by_#{@key}", attributes[@key].read(row)) : model.new
|
139
166
|
attributes.each { |_, attr| attr.set_from_row record, row }
|
140
167
|
record.save!
|
168
|
+
listeners.select! do |listener|
|
169
|
+
listener.notify self, count
|
170
|
+
end
|
141
171
|
end
|
142
172
|
end
|
143
173
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'rspec-expectations'
|
2
|
+
|
3
|
+
class DataMiner
|
4
|
+
class Step
|
5
|
+
# A step that runs tests and stops the data miner on failures.
|
6
|
+
#
|
7
|
+
# Create these by calling +test+ inside a +data_miner+ block.
|
8
|
+
#
|
9
|
+
# @see DataMiner::ActiveRecordClassMethods#data_miner Overview of how to define data miner scripts inside of ActiveRecord models.
|
10
|
+
# @see DataMiner::Script#test Creating a test step by calling DataMiner::Script#test from inside a data miner script
|
11
|
+
class Test < Step
|
12
|
+
include ::RSpec::Expectations
|
13
|
+
include ::RSpec::Matchers
|
14
|
+
|
15
|
+
# A description of what the block does. Doesn't exist when a single class method is specified using a Symbol.
|
16
|
+
# @return [String]
|
17
|
+
attr_reader :description
|
18
|
+
|
19
|
+
# The block of arbitrary code to be run.
|
20
|
+
# @return [Proc]
|
21
|
+
attr_reader :blk
|
22
|
+
|
23
|
+
# After how many rows of the previous step to run the tests.
|
24
|
+
# @return [Numeric]
|
25
|
+
attr_reader :after
|
26
|
+
|
27
|
+
# Every how many rows to run tests
|
28
|
+
# @return [Numeric]
|
29
|
+
attr_reader :every
|
30
|
+
|
31
|
+
alias :block_description :description
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def initialize(script, description, settings, &blk)
|
35
|
+
@script = script
|
36
|
+
@description = description
|
37
|
+
@blk = blk
|
38
|
+
@after = settings[:after]
|
39
|
+
@every = settings[:every]
|
40
|
+
raise "can't do both after and every" if after and every
|
41
|
+
end
|
42
|
+
|
43
|
+
# @private
|
44
|
+
def start
|
45
|
+
if inline?
|
46
|
+
eval_catching_errors
|
47
|
+
end
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def target?(step)
|
52
|
+
!inline? and (step.pos == pos - 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
def notify(step, count)
|
56
|
+
if count % (after || every) == 0
|
57
|
+
eval_catching_errors
|
58
|
+
!after # if it's an after, return false, so that we stop getting informed
|
59
|
+
else
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def inline?
|
67
|
+
not (after or every)
|
68
|
+
end
|
69
|
+
|
70
|
+
def eval_catching_errors
|
71
|
+
DataMiner::Script.uniq { instance_eval(&blk) }
|
72
|
+
rescue ::RSpec::Expectations::ExpectationNotMetError
|
73
|
+
raise RuntimeError, "FAILED: #{description} (#{$!.inspect})"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/data_miner/version.rb
CHANGED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
4
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
5
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
6
|
+
# loaded once.
|
7
|
+
#
|
8
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
11
|
+
config.run_all_when_everything_filtered = true
|
12
|
+
config.filter_run :focus
|
13
|
+
|
14
|
+
# Run specs in random order to surface order dependencies. If you find an
|
15
|
+
# order dependency and want to debug it, you can fix the order by providing
|
16
|
+
# the seed, which is printed after each run.
|
17
|
+
# --seed 1234
|
18
|
+
config.order = 'random'
|
19
|
+
end
|
20
|
+
|
21
|
+
require_relative '../test/support/database'
|
22
|
+
init_database
|
23
|
+
init_models
|
24
|
+
|
25
|
+
require 'data_miner'
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class PetTest1 < ActiveRecord::Base
|
4
|
+
self.primary_key = "name"
|
5
|
+
col :name
|
6
|
+
col :favorite_food
|
7
|
+
data_miner do
|
8
|
+
process :auto_upgrade!
|
9
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
10
|
+
key :name
|
11
|
+
store :favorite_food
|
12
|
+
end
|
13
|
+
test "Jerry likes cheese" do
|
14
|
+
expect(PetTest1.find('Jerry').favorite_food).to eq 'cheese'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class PetTest2 < ActiveRecord::Base
|
20
|
+
self.primary_key = "name"
|
21
|
+
col :name
|
22
|
+
col :favorite_food
|
23
|
+
data_miner do
|
24
|
+
process :auto_upgrade!
|
25
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
26
|
+
key :name
|
27
|
+
store :favorite_food
|
28
|
+
end
|
29
|
+
test "Jerry likes veggies" do
|
30
|
+
expect(PetTest2.find('Jerry').favorite_food).to eq 'veggies'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class PetTest3 < ActiveRecord::Base
|
36
|
+
self.primary_key = "name"
|
37
|
+
col :name
|
38
|
+
col :favorite_food
|
39
|
+
data_miner do
|
40
|
+
process :auto_upgrade!
|
41
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
42
|
+
key :name
|
43
|
+
store :favorite_food
|
44
|
+
end
|
45
|
+
test "First few have somebody named Pierre", after: 2 do
|
46
|
+
expect(PetTest3.count).to eq 2
|
47
|
+
expect(PetTest3.where(name: 'Pierre').count).to be > 0
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class PetTest4 < ActiveRecord::Base
|
53
|
+
self.primary_key = "name"
|
54
|
+
col :name
|
55
|
+
col :favorite_food
|
56
|
+
data_miner do
|
57
|
+
process :auto_upgrade!
|
58
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
59
|
+
key :name
|
60
|
+
store :favorite_food
|
61
|
+
end
|
62
|
+
test "First few have somebody named Johnny", after: 2 do
|
63
|
+
expect(PetTest4.count).to eq 2 # that's where we are
|
64
|
+
expect(PetTest4.where(name: 'Johnny').count).to be > 0
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
$pet_test_5_i = 0
|
70
|
+
class PetTest5 < ActiveRecord::Base
|
71
|
+
self.primary_key = "name"
|
72
|
+
col :name
|
73
|
+
col :favorite_food
|
74
|
+
data_miner do
|
75
|
+
process :auto_upgrade!
|
76
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
77
|
+
key :name
|
78
|
+
store :favorite_food
|
79
|
+
end
|
80
|
+
test "Everybody has a name", every: 2 do
|
81
|
+
$pet_test_5_i += 1
|
82
|
+
expect(PetTest5.count).to eq $pet_test_5_i*2
|
83
|
+
expect(PetTest5.where(name: nil).count).to be 0
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
$pet_test_6_i = 0
|
89
|
+
class PetTest6 < ActiveRecord::Base
|
90
|
+
self.primary_key = "name"
|
91
|
+
col :name
|
92
|
+
col :favorite_food
|
93
|
+
data_miner do
|
94
|
+
process :auto_upgrade!
|
95
|
+
import("A list of pets", :url => "file://#{Pet::PETS}") do
|
96
|
+
key :name
|
97
|
+
store :favorite_food
|
98
|
+
end
|
99
|
+
test "Everybody has a favorite food", every: 2 do
|
100
|
+
$pet_test_6_i += 1
|
101
|
+
expect(PetTest6.count).to eq $pet_test_6_i*2
|
102
|
+
expect(PetTest6.where(favorite_food: nil).count).to be 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe DataMiner::Step::Test do
|
108
|
+
it "keeps going if it passes" do
|
109
|
+
PetTest1.run_data_miner!
|
110
|
+
expect(PetTest1.count).to be > 0
|
111
|
+
end
|
112
|
+
it "stops on failure" do
|
113
|
+
expect { PetTest2.run_data_miner! }.to raise_error(/Jerry.*veggies/)
|
114
|
+
expect(PetTest2.count).to be > 0 # still populated tho
|
115
|
+
end
|
116
|
+
it "can be run in the middle of the previous step" do
|
117
|
+
PetTest3.run_data_miner!
|
118
|
+
expect(PetTest3.count).to be > 0
|
119
|
+
end
|
120
|
+
it "can be run in the middle of the previous step - failing" do
|
121
|
+
expect { PetTest4.run_data_miner! }.to raise_error(/First few.*Johnny/)
|
122
|
+
expect(PetTest4.count).to be 2 # stopped after 2
|
123
|
+
end
|
124
|
+
it "can be run every 2" do
|
125
|
+
PetTest5.run_data_miner!
|
126
|
+
expect($pet_test_5_i).to eq 2
|
127
|
+
expect(PetTest5.count).to be 5
|
128
|
+
end
|
129
|
+
it "can be run every 2 - failing" do
|
130
|
+
expect { PetTest6.run_data_miner! }.to raise_error(/Everybody has a favorite food/)
|
131
|
+
expect($pet_test_6_i).to eq 2
|
132
|
+
expect(PetTest6.count).to be $pet_test_6_i*2
|
133
|
+
end
|
134
|
+
end
|
data/test/helper.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'bundler/setup'
|
3
2
|
|
4
3
|
if Bundler.definition.specs['debugger'].first
|
@@ -12,53 +11,6 @@ require 'minitest/autorun'
|
|
12
11
|
require 'minitest/reporters'
|
13
12
|
MiniTest::Reporters.use!
|
14
13
|
|
15
|
-
|
16
|
-
require 'logger'
|
17
|
-
ActiveRecord::Base.logger = Logger.new $stderr
|
18
|
-
ActiveRecord::Base.logger.level = (ENV['VERBOSE'] == 'true') ? Logger::DEBUG : Logger::INFO
|
19
|
-
|
20
|
-
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
21
|
-
|
22
|
-
require 'active_record_inline_schema'
|
14
|
+
require_relative 'support/database'
|
23
15
|
|
24
16
|
require 'data_miner'
|
25
|
-
|
26
|
-
def init_database
|
27
|
-
case ENV['DATABASE']
|
28
|
-
when /postgr/i
|
29
|
-
system %{dropdb test_data_miner}
|
30
|
-
system %{createdb test_data_miner}
|
31
|
-
ActiveRecord::Base.establish_connection(
|
32
|
-
'adapter' => 'postgresql',
|
33
|
-
'encoding' => 'utf8',
|
34
|
-
'database' => 'test_data_miner',
|
35
|
-
'username' => `whoami`.chomp
|
36
|
-
)
|
37
|
-
when /sqlite/i
|
38
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
39
|
-
else
|
40
|
-
system %{mysql -u root -ppassword -e "DROP DATABASE test_data_miner"}
|
41
|
-
system %{mysql -u root -ppassword -e "CREATE DATABASE test_data_miner CHARSET utf8"}
|
42
|
-
ActiveRecord::Base.establish_connection(
|
43
|
-
'adapter' => (RUBY_PLATFORM == 'java' ? 'mysql' : 'mysql2'),
|
44
|
-
'encoding' => 'utf8',
|
45
|
-
'database' => 'test_data_miner',
|
46
|
-
'username' => 'root',
|
47
|
-
'password' => 'password'
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def init_models
|
53
|
-
require 'support/breed'
|
54
|
-
require 'support/pet'
|
55
|
-
require 'support/pet2'
|
56
|
-
require 'support/pet3'
|
57
|
-
Pet.auto_upgrade!
|
58
|
-
Pet2.auto_upgrade!
|
59
|
-
Pet3.auto_upgrade!
|
60
|
-
|
61
|
-
ActiveRecord::Base.descendants.each do |model|
|
62
|
-
model.attr_accessible nil
|
63
|
-
end
|
64
|
-
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'logger'
|
3
|
+
ActiveRecord::Base.logger = Logger.new $stderr
|
4
|
+
ActiveRecord::Base.logger.level = (ENV['VERBOSE'] == 'true') ? Logger::DEBUG : Logger::INFO
|
5
|
+
|
6
|
+
ActiveRecord::Base.mass_assignment_sanitizer = :strict
|
7
|
+
|
8
|
+
require 'active_record_inline_schema'
|
9
|
+
|
10
|
+
require 'data_miner'
|
11
|
+
|
12
|
+
def init_database
|
13
|
+
case ENV['DATABASE']
|
14
|
+
when /postgr/i
|
15
|
+
system %{dropdb test_data_miner}
|
16
|
+
system %{createdb test_data_miner}
|
17
|
+
ActiveRecord::Base.establish_connection(
|
18
|
+
'adapter' => 'postgresql',
|
19
|
+
'encoding' => 'utf8',
|
20
|
+
'database' => 'test_data_miner',
|
21
|
+
'username' => `whoami`.chomp
|
22
|
+
)
|
23
|
+
when /sqlite/i
|
24
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
25
|
+
else
|
26
|
+
system %{mysql -u root -ppassword -e "DROP DATABASE test_data_miner"}
|
27
|
+
system %{mysql -u root -ppassword -e "CREATE DATABASE test_data_miner CHARSET utf8"}
|
28
|
+
ActiveRecord::Base.establish_connection(
|
29
|
+
'adapter' => (RUBY_PLATFORM == 'java' ? 'mysql' : 'mysql2'),
|
30
|
+
'encoding' => 'utf8',
|
31
|
+
'database' => 'test_data_miner',
|
32
|
+
'username' => 'root',
|
33
|
+
'password' => 'password'
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_models
|
39
|
+
require_relative 'breed'
|
40
|
+
require_relative 'pet'
|
41
|
+
require_relative 'pet2'
|
42
|
+
require_relative 'pet3'
|
43
|
+
Pet.auto_upgrade!
|
44
|
+
Pet2.auto_upgrade!
|
45
|
+
Pet3.auto_upgrade!
|
46
|
+
|
47
|
+
ActiveRecord::Base.descendants.each do |model|
|
48
|
+
model.attr_accessible nil
|
49
|
+
end
|
50
|
+
end
|
data/test/support/pet.rb
CHANGED
@@ -15,9 +15,15 @@ class Pet < ActiveRecord::Base
|
|
15
15
|
col :command_phrase
|
16
16
|
col :emphatic_command_phrase
|
17
17
|
belongs_to :breed
|
18
|
+
|
19
|
+
|
20
|
+
|
18
21
|
data_miner do
|
22
|
+
|
19
23
|
process :auto_upgrade!
|
24
|
+
|
20
25
|
process :run_data_miner_on_parent_associations!
|
26
|
+
|
21
27
|
import("A list of pets", :url => "file://#{PETS}") do
|
22
28
|
key :name
|
23
29
|
store :age
|
@@ -31,5 +37,6 @@ class Pet < ActiveRecord::Base
|
|
31
37
|
(row['command_phrase'] + "!!!!!") if row['command_phrase']
|
32
38
|
end
|
33
39
|
end
|
40
|
+
|
34
41
|
end
|
35
42
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_miner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.
|
4
|
+
version: 3.0.0.beta
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2013-07-
|
16
|
+
date: 2013-07-26 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: activerecord
|
@@ -143,6 +143,38 @@ dependencies:
|
|
143
143
|
- - ! '>='
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: 1.10.3
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: rspec-expectations
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :runtime
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
- !ruby/object:Gem::Dependency
|
163
|
+
name: rspec
|
164
|
+
requirement: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ! '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
type: :development
|
171
|
+
prerelease: false
|
172
|
+
version_requirements: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
146
178
|
- !ruby/object:Gem::Dependency
|
147
179
|
name: pry
|
148
180
|
requirement: !ruby/object:Gem::Requirement
|
@@ -333,6 +365,7 @@ extensions: []
|
|
333
365
|
extra_rdoc_files: []
|
334
366
|
files:
|
335
367
|
- .gitignore
|
368
|
+
- .rspec
|
336
369
|
- .yardopts
|
337
370
|
- CHANGELOG
|
338
371
|
- Gemfile
|
@@ -348,7 +381,10 @@ files:
|
|
348
381
|
- lib/data_miner/step/import.rb
|
349
382
|
- lib/data_miner/step/process.rb
|
350
383
|
- lib/data_miner/step/sql.rb
|
384
|
+
- lib/data_miner/step/test.rb
|
351
385
|
- lib/data_miner/version.rb
|
386
|
+
- spec/spec_helper.rb
|
387
|
+
- spec/test_step_spec.rb
|
352
388
|
- test/data_miner/step/test_sql.rb
|
353
389
|
- test/data_miner/test_attribute.rb
|
354
390
|
- test/helper.rb
|
@@ -356,6 +392,7 @@ files:
|
|
356
392
|
- test/support/breed_by_license_number.csv
|
357
393
|
- test/support/breeds.xls
|
358
394
|
- test/support/data_miner_with_alchemist.rb
|
395
|
+
- test/support/database.rb
|
359
396
|
- test/support/pet.rb
|
360
397
|
- test/support/pet2.rb
|
361
398
|
- test/support/pet3.rb
|
@@ -390,6 +427,8 @@ specification_version: 3
|
|
390
427
|
summary: Download, pull out of a ZIP/TAR/GZ/BZ2 archive, parse, correct, and import
|
391
428
|
XLS, ODS, XML, CSV, HTML, etc. into your ActiveRecord models.
|
392
429
|
test_files:
|
430
|
+
- spec/spec_helper.rb
|
431
|
+
- spec/test_step_spec.rb
|
393
432
|
- test/data_miner/step/test_sql.rb
|
394
433
|
- test/data_miner/test_attribute.rb
|
395
434
|
- test/helper.rb
|
@@ -397,6 +436,7 @@ test_files:
|
|
397
436
|
- test/support/breed_by_license_number.csv
|
398
437
|
- test/support/breeds.xls
|
399
438
|
- test/support/data_miner_with_alchemist.rb
|
439
|
+
- test/support/database.rb
|
400
440
|
- test/support/pet.rb
|
401
441
|
- test/support/pet2.rb
|
402
442
|
- test/support/pet3.rb
|