datum 0.8.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/MIT-LICENSE +20 -0
- data/README.md +35 -0
- data/Rakefile +38 -0
- data/lib/datum/context.rb +55 -0
- data/lib/datum/db_tasks.rb +82 -0
- data/lib/datum/driver_helper.rb +75 -0
- data/lib/datum/enable_notification.rb +27 -0
- data/lib/datum/enable_task.rb +118 -0
- data/lib/datum/railtie.rb +14 -0
- data/lib/datum/version.rb +3 -0
- data/lib/datum.rb +101 -0
- data/lib/generators/datum/USAGE +0 -0
- data/lib/generators/datum/datum_generator.rb +104 -0
- data/lib/generators/datum/templates/datum_migration.rb +21 -0
- data/lib/generators/datum/templates/datum_model.rb +6 -0
- data/lib/tasks/datum.rake +38 -0
- data/test/datum_test.rb +17 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +61 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.example +42 -0
- data/test/dummy/config/database.sqlite +25 -0
- data/test/dummy/config/database.yml +55 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/log/development.log +17 -0
- data/test/dummy/log/test.log +25 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/test_helper.rb +13 -0
- data/test/dummy/test/unit/simple_model_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +153 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Tyemill. http://tyemill.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Datum is currently under development and pre-1.0
|
2
|
+
|
3
|
+
## Datum
|
4
|
+
|
5
|
+
Datum is a simple take on Data Driven Testing for Rails. Datum:
|
6
|
+
|
7
|
+
* Enables a table to drive a test case
|
8
|
+
* Quick conversion from data-driven via a database to via a file
|
9
|
+
* Dump tables to fixtures for scc storage
|
10
|
+
* Load tables from fixtures
|
11
|
+
* Generate datum specific migrations and models
|
12
|
+
|
13
|
+
## Rails 3
|
14
|
+
|
15
|
+
Datum is still in development. Currently, we're working with Rails 3.2.6 and Ruby 1.9.3.
|
16
|
+
|
17
|
+
### Getting Started
|
18
|
+
|
19
|
+
Add Datum to your Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'datum'
|
23
|
+
```
|
24
|
+
|
25
|
+
Run the bundle command to install it.
|
26
|
+
|
27
|
+
After you install Datum and add it to your Gemfile, you need to enable it:
|
28
|
+
|
29
|
+
```console
|
30
|
+
rake datum:enable
|
31
|
+
```
|
32
|
+
|
33
|
+
Enable will create several directories in your test directory. It will also prompt you to ask for permission to update your database.yml and application.rb. You MUST review both files even if you have Enable update them for you.
|
34
|
+
|
35
|
+
When you are finished, you are ready to add Datum migrations and models to your application as needed.
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'Datum'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
32
|
+
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
task :default => :test
|
@@ -0,0 +1,55 @@
|
|
1
|
+
|
2
|
+
module Datum
|
3
|
+
|
4
|
+
class Context
|
5
|
+
|
6
|
+
def self.initialized?
|
7
|
+
return @@initialized
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.continue?
|
11
|
+
@@table_data.nil? ? false : (@@table_data.count != 0 ? true : false)
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def self.next_row
|
17
|
+
result = nil if @@table_data.nil?
|
18
|
+
result = @@table_data.delete_at(0) unless @@table_data.nil?
|
19
|
+
@@initialized = false if !result.nil? && @@table_data.count == 0
|
20
|
+
|
21
|
+
log "next row table_data: #{@@table_data}"
|
22
|
+
log "next row result: #{result.attributes}" unless result.nil?
|
23
|
+
log "next row initialized: #{@@initialized}"
|
24
|
+
return result
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.datum_directory
|
28
|
+
return @@directory
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.table_data
|
32
|
+
return @@table_data
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.table_data= data
|
36
|
+
@@table_data = data
|
37
|
+
@@initialized = true if !@@table_data.nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.log msg
|
41
|
+
Datum::DriverHelper.log msg
|
42
|
+
end
|
43
|
+
|
44
|
+
@@directory = "#{Rails.env}/lib/datum"
|
45
|
+
@@test_directory = "#{Rails.env}/test/lib/datum"
|
46
|
+
@@table_data = nil
|
47
|
+
@@initialized = false
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
module Datum
|
3
|
+
class DbTasks
|
4
|
+
def initialize
|
5
|
+
Rails.env = @@datum_environment
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
Rake::Task['db:create'].invoke()
|
10
|
+
end
|
11
|
+
|
12
|
+
def migrate
|
13
|
+
ActiveRecord::Base.establish_connection(Rails.env)
|
14
|
+
ActiveRecord::Migrator.migrate "#{@@local_path}/migrate"
|
15
|
+
end
|
16
|
+
|
17
|
+
def drop
|
18
|
+
Rake::Task['db:drop'].invoke()
|
19
|
+
end
|
20
|
+
|
21
|
+
# get into the datum fixtures directory, walk the yml, load into db
|
22
|
+
def load
|
23
|
+
Dir.glob("#{@@local_path}/fixtures/*.yml").entries.each do |entry|
|
24
|
+
file_name = entry.to_s.split('/').last.to_s.split('.')[0]
|
25
|
+
target_model = file_name.classify.constantize
|
26
|
+
data_hash = YAML.load(File.read(entry))
|
27
|
+
data_hash.each_value {|value|
|
28
|
+
value.delete "id"
|
29
|
+
value.delete "created_at"
|
30
|
+
value.delete "updated_at"
|
31
|
+
target_model.create value
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# get into datum db, get relevant tables, produce ymls (for sharing)
|
37
|
+
# tonyamoyal.com/2009/12/09/
|
38
|
+
# converting-table-data-to-yaml-for-testing-in-ruby-on-rails/
|
39
|
+
def dump
|
40
|
+
sql = "SELECT * FROM %s"
|
41
|
+
skip_tables = ["schema_info", "schema_migrations"]
|
42
|
+
ActiveRecord::Base.establish_connection(Rails.env)
|
43
|
+
tables = (ActiveRecord::Base.connection.tables - skip_tables)
|
44
|
+
tables.each do |table_name|
|
45
|
+
i = "000"
|
46
|
+
File.open("#{@@local_path}/fixtures/#{table_name}.yml",
|
47
|
+
'w') do |file|
|
48
|
+
data = ActiveRecord::Base.connection.select_all(sql % table_name)
|
49
|
+
file.write data.inject({}) { |hash, record|
|
50
|
+
hash["#{table_name}_#{i.succ!}"] = record
|
51
|
+
hash}.to_yaml
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# take Models data, produce a file for use without db
|
57
|
+
def localize args
|
58
|
+
tasked_model = args[:table].classify.constantize
|
59
|
+
data = tasked_model.all
|
60
|
+
file_name = args[:table]
|
61
|
+
File.open("#{@@local_path}/locals/#{file_name}.rb", 'w') do |f1|
|
62
|
+
f1.puts "\n\n#\n# data dump for code access of table #{file_name}"
|
63
|
+
f1.puts "#\nmodule #{tasked_model.to_s.pluralize}"
|
64
|
+
f1.puts "def self.data\nd = ["
|
65
|
+
data.each_with_index {|e, i|
|
66
|
+
hash = e.attributes
|
67
|
+
hash.each_pair {|key, value|
|
68
|
+
new_value = value.to_s
|
69
|
+
hash[key] = new_value
|
70
|
+
}
|
71
|
+
f1.puts "#{hash.to_s},"
|
72
|
+
}
|
73
|
+
f1.puts "]\nend\nend"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
@@local_path = "#{Rails.root}/test/lib/datum"
|
79
|
+
@@datum_environment = "datum"
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
module Datum
|
3
|
+
|
4
|
+
class DriverHelper
|
5
|
+
|
6
|
+
def self.load_data table
|
7
|
+
context.table_data = load_file_data(table) || load_model_data(table)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.add_datum_exec_ext init_before_exec, result
|
11
|
+
return result if !init_before_exec && !context.initialized?
|
12
|
+
|
13
|
+
first = !init_before_exec && context.initialized?
|
14
|
+
last = init_before_exec && !context.initialized?
|
15
|
+
|
16
|
+
base = "," if result == "."
|
17
|
+
base = "," + result unless base == ","
|
18
|
+
base = "[" + base if first
|
19
|
+
base += "]" if last
|
20
|
+
return base
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.enable_logger
|
24
|
+
@@logger = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.disable_logger
|
28
|
+
@@logger = false
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
@@logger = false
|
33
|
+
|
34
|
+
def self.log msg
|
35
|
+
Rails.logger.debug "$$ " + msg unless !@@logger
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.load_model_data table
|
39
|
+
data = nil
|
40
|
+
begin
|
41
|
+
driver_method = table.to_s.singularize
|
42
|
+
data = driver_method.classify.constantize.all.reverse
|
43
|
+
rescue Exception => exc
|
44
|
+
log "load_model_data: could not get data from model #{driver_method}"
|
45
|
+
log exc
|
46
|
+
raise
|
47
|
+
"Accessing datum database with table / model #{driver_method} failed."
|
48
|
+
end
|
49
|
+
|
50
|
+
return data
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.load_file_data table
|
54
|
+
data = nil
|
55
|
+
begin
|
56
|
+
require "lib/datum/locals/#{table}"
|
57
|
+
cls = driver_method.classify.pluralize.constantize
|
58
|
+
data = cls::data.reverse
|
59
|
+
data = mock_data data
|
60
|
+
rescue Exception => exc
|
61
|
+
## database-driven
|
62
|
+
log "load_file_data: file load failed. moving to database load."
|
63
|
+
end
|
64
|
+
|
65
|
+
return data
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def self.context
|
71
|
+
return Datum::Context
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
module Datum
|
3
|
+
NOTIFICATION =
|
4
|
+
"
|
5
|
+
### !!!ADDITIONAL UPDATES REQUIRED!!!
|
6
|
+
|
7
|
+
Datum requires:
|
8
|
+
+ application.rb to reference testcase specific models
|
9
|
+
+ database.yml to contain a datum environment
|
10
|
+
|
11
|
+
- application.rb should contain:
|
12
|
+
config.autoload_paths += %W(\#{Rails.root}/test/lib/datum/models)
|
13
|
+
|
14
|
+
- database.yml should contain something like:
|
15
|
+
|
16
|
+
datum:
|
17
|
+
adapter: mysql2
|
18
|
+
encoding: utf8
|
19
|
+
reconnect: false
|
20
|
+
database: yourapp_datum
|
21
|
+
pool: 5
|
22
|
+
username: root
|
23
|
+
password:
|
24
|
+
socket: /tmp/mysql.sock
|
25
|
+
|
26
|
+
"
|
27
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
|
2
|
+
module Datum
|
3
|
+
class EnableTask
|
4
|
+
|
5
|
+
def rock
|
6
|
+
puts "\n Enabling Datum Data-Driven Testing Tools."
|
7
|
+
create_directories
|
8
|
+
notify_check
|
9
|
+
update_yml if @@update_yml
|
10
|
+
update_app if @@update_app
|
11
|
+
puts " Datum enabled.\n "
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
@@application_path = @@info = nil
|
16
|
+
@@update_app = @@update_yml = false
|
17
|
+
@@datum_drop_path = "test/lib/datum"
|
18
|
+
@@datum_model_path = 'config.autoload_paths += %W(#{Rails.root}/' +
|
19
|
+
"#{@@datum_drop_path}" + '/models)'
|
20
|
+
@@datum_app_scan = "config.autoload_paths.*#{@@datum_drop_path}/models"
|
21
|
+
#@@datum_app_scan = "config.autoload_paths.*test\/lib\/datum\/models"
|
22
|
+
#@@datum_drop_path.gsub(Regexp.new("\\/"), "\\/")
|
23
|
+
#"config.autoload_paths.*#{encoded_path}\/models"
|
24
|
+
|
25
|
+
def create_directories
|
26
|
+
["#{@@datum_drop_path}/fixtures", "#{@@datum_drop_path}/locals",
|
27
|
+
"#{@@datum_drop_path}/migrate", "#{@@datum_drop_path}/models"].each {
|
28
|
+
|path| FileUtils.mkdir_p(path) if !File::directory?(path)}
|
29
|
+
|
30
|
+
puts " Datum directories created."
|
31
|
+
end
|
32
|
+
|
33
|
+
def notify_check
|
34
|
+
@@update_yml = need_yml?
|
35
|
+
@@update_app = need_app?
|
36
|
+
|
37
|
+
notify unless !@@update_yml && !@@update_app
|
38
|
+
end
|
39
|
+
|
40
|
+
def notify
|
41
|
+
require "datum/enable_notification"
|
42
|
+
puts "#{Datum::NOTIFICATION}"
|
43
|
+
puts " Files that may need updates: "
|
44
|
+
puts " database.yml" if @@update_yml
|
45
|
+
puts " application.rb" if @@update_app
|
46
|
+
puts "\n>>>>>>>>>>>>>>>> Attempt updates for you? y/n"
|
47
|
+
continue = STDIN.gets.chomp
|
48
|
+
unless continue == 'y' || continue == 'yes'
|
49
|
+
puts "\n Files must be updated manually to fully enable Datum\n "
|
50
|
+
exit!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def update_yml
|
55
|
+
app_name = Rails.root.to_s.split("/").last
|
56
|
+
target_hash = @@info["test"] ? @@info["test"] : @@info["development"]
|
57
|
+
|
58
|
+
if target_hash.nil?
|
59
|
+
puts " Can't update database.yml without a pre-existing"
|
60
|
+
puts " test or development segment."
|
61
|
+
puts "###### !!!! Please update database.yml manually !!!! ######\n "
|
62
|
+
return
|
63
|
+
end
|
64
|
+
|
65
|
+
File.open(Rails.root.join("config/database.yml"), 'a') do |f1|
|
66
|
+
f1.puts "\n\n#\n# database entry for data-driven testing.\n#"
|
67
|
+
f1.puts "datum:"
|
68
|
+
target_hash.each_pair {|key, value|
|
69
|
+
f1.puts " #{key}: #{value}" unless key == "database"
|
70
|
+
f1.puts " database: #{app_name}_datum" if key == "database"
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
puts " database.yml updated with datum entry"
|
75
|
+
end
|
76
|
+
|
77
|
+
def update_app
|
78
|
+
FileUtils.mkdir_p("tmp")
|
79
|
+
tmp_path = "tmp/app.tmp"
|
80
|
+
tempfile = File.open(tmp_path, 'w')
|
81
|
+
readfile = open_app_file
|
82
|
+
|
83
|
+
readfile.each do |line|
|
84
|
+
tempfile << line
|
85
|
+
if line.strip == "class Application < Rails::Application"
|
86
|
+
tempfile << "\n # Added as part of datum install, enables access to datum specific models\n"
|
87
|
+
tempfile << " #{@@datum_model_path}\n\n"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
readfile.close
|
92
|
+
tempfile.close
|
93
|
+
FileUtils.mv(tmp_path, @@application_path)
|
94
|
+
|
95
|
+
puts " application.rb updated with datum model reference"
|
96
|
+
end
|
97
|
+
|
98
|
+
def need_yml?
|
99
|
+
@@info = YAML::load(IO.read(Rails.root.join("config/database.yml")))
|
100
|
+
return true unless @@info["datum"]
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
|
104
|
+
def need_app?
|
105
|
+
pattern = Regexp.new "#{@@datum_app_scan}"
|
106
|
+
readfile = open_app_file
|
107
|
+
readfile.each do |line|
|
108
|
+
return false if line.scan(pattern).length != 0
|
109
|
+
end
|
110
|
+
return true
|
111
|
+
end
|
112
|
+
|
113
|
+
def open_app_file
|
114
|
+
@@application_path = Rails.root.join("config/application.rb")
|
115
|
+
return File.new(@@application_path)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
data/lib/datum.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# datum helps data-driven testing.
|
2
|
+
#
|
3
|
+
# Author:: Gabriel Marius, Tyemill
|
4
|
+
# Copyright:: Copyright (c) 2012 Tyemill, llc.
|
5
|
+
# License:: MIT License (http://www.opensource.org/licenses/mit-license.php)
|
6
|
+
|
7
|
+
require 'datum/railtie'
|
8
|
+
require 'datum/driver_helper'
|
9
|
+
require 'datum/context'
|
10
|
+
#require 'test/unit'
|
11
|
+
|
12
|
+
module Datum
|
13
|
+
ActiveSupport::TestCase.class_eval do
|
14
|
+
alias_method :original_initialize, :initialize
|
15
|
+
|
16
|
+
|
17
|
+
def initialize(tst)
|
18
|
+
log NEW_TST
|
19
|
+
original_initialize tst
|
20
|
+
end
|
21
|
+
|
22
|
+
def drive_with table
|
23
|
+
datum_helper::load_data table if !datum_context::initialized?
|
24
|
+
@@driver_row = datum_context.next_row
|
25
|
+
log "drive_with table: #{table}"
|
26
|
+
log "drive_with row: #{@@driver_row.attributes}" unless @@driver_row.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def datum
|
30
|
+
return @@driver_row
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
@@driver_row = nil
|
35
|
+
NEW_TST = "@@@ N E W T S T C A S E @@@@@@@@@@@@@@@@@@@@@@@@@@@@"
|
36
|
+
def log msg
|
37
|
+
datum_helper.log msg
|
38
|
+
end
|
39
|
+
|
40
|
+
def datum_helper
|
41
|
+
return Datum::DriverHelper
|
42
|
+
end
|
43
|
+
|
44
|
+
def datum_context
|
45
|
+
return Datum::Context
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
MiniTest::Unit.class_eval do
|
51
|
+
alias_method :original__run_suite, :_run_suite
|
52
|
+
|
53
|
+
def _run_suite suite, type
|
54
|
+
header = "#{type}_suite_header"
|
55
|
+
puts send(header, suite) if respond_to? header
|
56
|
+
|
57
|
+
filter = options[:filter] || '/./'
|
58
|
+
filter = Regexp.new $1 if filter =~ /\/(.*)\//
|
59
|
+
|
60
|
+
testcases = suite.send("#{type}_methods").grep(filter)
|
61
|
+
assertions = []
|
62
|
+
p_test = nil
|
63
|
+
testcases.map { |test_case|
|
64
|
+
while datum_context::continue? || p_test != test_case do
|
65
|
+
__runner assertions, test_case, suite
|
66
|
+
p_test = test_case
|
67
|
+
end
|
68
|
+
}
|
69
|
+
return assertions.size, assertions.inject(0) { |sum, n| sum + n }
|
70
|
+
end
|
71
|
+
|
72
|
+
def __runner(assertions, test_case, suite)
|
73
|
+
testcase_result = inner_runner(test_case, suite)
|
74
|
+
assertions.push testcase_result
|
75
|
+
end
|
76
|
+
|
77
|
+
def inner_runner(method, suite)
|
78
|
+
inst = suite.new method
|
79
|
+
inst._assertions = 0
|
80
|
+
print "#{suite}##{method} = " if @verbose
|
81
|
+
@start_time = Time.now
|
82
|
+
datum_init = datum_context::initialized?
|
83
|
+
result = inst.run self
|
84
|
+
time = Time.now - @start_time
|
85
|
+
print "%.2f s = " % time if @verbose
|
86
|
+
result = Datum::DriverHelper::add_datum_exec_ext datum_init, result
|
87
|
+
print result
|
88
|
+
puts if @verbose
|
89
|
+
|
90
|
+
inst._assertions
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def datum_context
|
95
|
+
return Datum::Context
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
end
|
File without changes
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
require 'rails/generators/generated_attribute'
|
3
|
+
|
4
|
+
# Generator code was modified from https://github.com/ryanb/nifty-generators/
|
5
|
+
# Nifty Generators is Copyright (c) 2011 Ryan Bates and distributed via the
|
6
|
+
# MIT License
|
7
|
+
class DatumGenerator < Rails::Generators::Base
|
8
|
+
include Rails::Generators::Migration
|
9
|
+
no_tasks { attr_accessor :scaffold_name, :model_attributes}
|
10
|
+
source_root File.expand_path('../templates', __FILE__)
|
11
|
+
|
12
|
+
argument :scaffold_name, :type => :string, :required => true, :banner => 'ModelName'
|
13
|
+
argument :args_for_m, :type => :array, :default => [], :banner => 'model:attributes'
|
14
|
+
|
15
|
+
class_option :skip_migration,
|
16
|
+
:desc => 'Don\'t generate migration file for model.', :type => :boolean
|
17
|
+
|
18
|
+
class_option :skip_model,
|
19
|
+
:desc => 'Don\'t generate a model or migration file.', :type => :boolean
|
20
|
+
|
21
|
+
def initialize(*args, &block)
|
22
|
+
super
|
23
|
+
print_usage unless scaffold_name.underscore =~ /^[a-z][a-z0-9_\/]+$/
|
24
|
+
|
25
|
+
@datum_path = "test/lib/datum"
|
26
|
+
@model_attributes = []
|
27
|
+
@skip_model = options.skip_model?
|
28
|
+
|
29
|
+
args_for_m.each do |arg|
|
30
|
+
if arg.include?(':')
|
31
|
+
@model_attributes << Rails::Generators::GeneratedAttribute.new(*arg.split(':'))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
@model_attributes.uniq!
|
36
|
+
|
37
|
+
if @model_attributes.empty?
|
38
|
+
@skip_model = true # skip model if no attributes
|
39
|
+
if model_exists?
|
40
|
+
model_columns_for_attributes.each do |column|
|
41
|
+
@model_attributes << Rails::Generators::GeneratedAttribute.new(
|
42
|
+
column.name.to_s, column.type.to_s)
|
43
|
+
end
|
44
|
+
else
|
45
|
+
@model_attributes << Rails::Generators::GeneratedAttribute.new(
|
46
|
+
'name', 'string')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_model
|
52
|
+
unless @skip_model
|
53
|
+
template 'datum_model.rb', "#{@datum_path}/models/#{model_path}.rb"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def create_migration
|
57
|
+
unless @skip_model || options.skip_migration?
|
58
|
+
migration_template 'datum_migration.rb',
|
59
|
+
"#{@datum_path}/migrate/create_#{model_path.pluralize.gsub('/', '_')}.rb"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def plural_name
|
66
|
+
scaffold_name.underscore.pluralize
|
67
|
+
end
|
68
|
+
|
69
|
+
def plural_class_name
|
70
|
+
plural_name.camelize
|
71
|
+
end
|
72
|
+
|
73
|
+
def table_name
|
74
|
+
if scaffold_name.include?('::') && @namespace_model
|
75
|
+
plural_name.gsub('/', '_')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def class_name
|
80
|
+
scaffold_name.split('::').last.camelize
|
81
|
+
end
|
82
|
+
|
83
|
+
def model_path
|
84
|
+
class_name.underscore
|
85
|
+
end
|
86
|
+
|
87
|
+
def model_exists?
|
88
|
+
File.exist? destination_path("#{@datum_path}/models/#{singular_name}.rb")
|
89
|
+
end
|
90
|
+
|
91
|
+
def destination_path(path)
|
92
|
+
File.join(destination_root, path)
|
93
|
+
end
|
94
|
+
|
95
|
+
# FIXME: Should be proxied to ActiveRecord::Generators::Base
|
96
|
+
# Implement the required interface for Rails::Generators::Migration.
|
97
|
+
def self.next_migration_number(dirname) #:nodoc:
|
98
|
+
if ActiveRecord::Base.timestamped_migrations
|
99
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
100
|
+
else
|
101
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|