dummy 0.6 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,55 +1,5 @@
1
- ## 0.1 (July 13, 2010)
1
+ ## 0.9 (August 10, 2010)
2
2
 
3
3
  Features:
4
- - added generation of dummy data based on a Rails 3 application
5
-
6
-
7
- ## 0.2 (July 17, 2010)
8
-
9
- Features:
10
- - moved data generation into a generator
11
- - added growth-ratio and base-amount options
12
-
13
-
14
- ## 0.3 (July 21, 2010)
15
-
16
- Features:
17
- - added rake task to import the generated dummy data in the target application
18
-
19
-
20
- ## 0.4 (July 24, 2010)
21
-
22
- Features:
23
- - improved data generation (which tries to be smart, RIP lorem ipsum)
24
-
25
-
26
- ## 0.5 (July 24, 2010)
27
-
28
- Features:
29
- - added tests for the data generators and rails generator
30
- - small improvements
31
- - added documentation
32
-
33
- Fixes:
34
- - various minor bugs
35
-
36
- ## 0.5.1 (July 29, 2010)
37
-
38
- Fixes:
39
- - fixed a bug where magic integers were being returned as strings
40
-
41
- ## 0.5.2 (July 30, 2010)
42
-
43
- Features:
44
- - added option to manually configure the amount of records to generate for each model
45
-
46
- ## 0.6 (July 31, 2010)
47
-
48
- Features:
49
- - added option to define the output folder where the YAML files are placed
50
-
51
- Fixes:
52
- - Removed unused core extensions (for now)
53
- - fixed some outdated tests
54
-
4
+ - cleverly generating dummy data (functionality split up from old project)
55
5
 
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Dummy
2
2
 
3
- Dummy generates dummy data for your Rails 3 application and allows you to import it.
3
+ Dummy generates dummy data in a clever way.
4
4
 
5
5
  ## Description
6
6
 
7
- Dummy generates data for your application by inspecting your models and their associations. It tries to generate the correct type of data for each column by guessing what it is from its name. Finally, it allows you to import the generated data into the database.
7
+ Dummy can generate a lot of dummy data from company names to postal codes. While it allows you to specifically request a type of information, it can also try to determine what you're looking for given a couple of parameters.
8
8
 
9
9
  ## Installation
10
10
 
@@ -12,28 +12,7 @@ $ gem install dummy
12
12
 
13
13
  ## Usage
14
14
 
15
- Add the following to the Gemfile of your Rails 3 application:
16
- gem "dummy"
17
-
18
- Now you have access to the generator:
19
- rails generate dummy:data
20
-
21
- You can change the base amount of records and the growth ratio (what these mean exactly is explained latter on):
22
- rails generate dummy:data --base-amount 5 --growth-ratio 1.5
23
-
24
- Also, you can manually define the amount of records to generate for each model (or just accept the defaults):
25
- rails generate dummy:data --manual-amounts
26
-
27
- And you can manually set the output folder for the YAML files (which defaults to test/dummy/data):
28
- rails generate dummy:data --output-folder test/awesome_fixtures
29
-
30
-
31
- The fixtures are stored in _test/dummy/_ while a rake file is placed in _lib/tasks/dummy.rake_. It allows you to import the generated data into the database:
32
- RAILS_ENV="dummy" rake dummy:data:import
33
-
34
- Don't forget to change RAILS_ENV to whatever is appropriate for you (and is configured under databases.yml). Your database doesn't need to be empty.
35
-
36
- Another less conventional way of using dummy is to directly use its magic data generation:
15
+ To ask for cleverly generated dummy data:
37
16
  Dummy.magic_data(field, type)
38
17
 
39
18
  Example:
@@ -44,43 +23,20 @@ Example:
44
23
  Dummy.magic_data("state", :string) => "Louisiana"
45
24
  Dummy.magic_data("lat", :float) => -86.718683637
46
25
  Dummy.magic_data("phone", :integer) => 9462876293
47
-
48
-
49
- ## More information
50
-
51
- ### Smart data
52
-
53
- Dummy tries to understand your database columns and generates data accordingly, instead of dumping "Lorem ipsum" all over the place.
54
-
55
- For instance, if you have a field called _company\_name_, it will generate a company name. If you have a field called _awesome\_postal\_code_, it will generate a valid ZIP Code. If you have a field called _longitude_, it will generate a valid longitude. And so on. You get the picture.
56
-
57
- Dummy cares about associations. It will create random associations between the automatically generated records.
58
-
59
- ### Smart amounts of data
60
-
61
- Dummy is aware that the amount of records that each model has in real world applications is different. For this reason, it will analyze your model associations to try to make a somewhat accurate estimation of the expected amount of records.
62
-
63
- To illustrate this, consider an application with models for _Child_, _Parent_ and _GrandParent_. If the base amount is 10, the growth ratio is 2.0, and the models look like the following:
64
-
65
- class GrandParent < ActiveRecord::Base
66
- has_many :parents
67
- end
68
26
 
69
- class Parent < ActiveRecord::Base
70
- belongs_to :grand_parent
71
- has_many :children
72
- end
27
+ You can also use its submodules for specific data:
28
+ Dummy::Name.first_name => "Muhammad"
29
+ Dummy::Internet.url => "https://david.grady.biz"
30
+ Dummy::Address.street_address => "10273 Delaney Extensions"
73
31
 
74
- class Child < ActiveRecord::Base
75
- belongs_to :parent
76
- end`
32
+ Have a look in the rdoc for all available generators.
77
33
 
78
- The generator will create dummy data for 10 _GrandParents_, 20 _Parents_ and 40 _Children_.
34
+ ## More information
79
35
 
80
36
  ### Caveats
81
37
 
82
38
  Dummy has a few caveats which are on the TODO list. Those are:
83
- * It is an English speaking gem. It will not be smart at all if your column is named _telefone_ (Portuguese for _phone_) or if you want a zip code from outside the US.
84
- * It will generate valid emails, latitudes, street addresses, etc, but it doesn't care about your model validations.
39
+
40
+ * It is an English speaking gem. It will not be smart at all if your column is named _telefone_ (Portuguese for _phone_) or if you want a zip code from outside the US.
85
41
 
86
42
  Copyright (c) 2010 Gonçalo Silva
data/lib/dummy/lorem.rb CHANGED
@@ -17,7 +17,7 @@ module Dummy
17
17
  end
18
18
 
19
19
  def paragraphs
20
- (1..3).map { paragraph }.join("\n")
20
+ (1..3).map { paragraph }.join(" ") # removing \n because of ruby's syck bug
21
21
  end
22
22
 
23
23
  private
data/lib/dummy.rb CHANGED
@@ -7,11 +7,10 @@ require "dummy/lorem"
7
7
  require "dummy/name"
8
8
  require "dummy/phone_number"
9
9
  require "dummy/geolocation"
10
- require "generators/dummy_generator"
11
10
 
12
11
  module Dummy
13
12
  class << self
14
-
13
+
15
14
  def magic_data(field, type)
16
15
  case type
17
16
  when :string, :text then magic_string(field, type)
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 6
8
- version: "0.6"
7
+ - 9
8
+ version: "0.9"
9
9
  platform: ruby
10
10
  authors:
11
11
  - "Gon\xC3\xA7alo Silva"
@@ -13,26 +13,11 @@ autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
15
 
16
- date: 2010-07-31 00:00:00 +01:00
16
+ date: 2010-08-11 00:00:00 +01:00
17
17
  default_executable:
18
- dependencies:
19
- - !ruby/object:Gem::Dependency
20
- name: rails
21
- prerelease: false
22
- requirement: &id001 !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 3
29
- - 0
30
- - 0
31
- - rc
32
- version: 3.0.0.rc
33
- type: :runtime
34
- version_requirements: *id001
35
- description: Generates consistent fake data and allows you to insert it to the database
18
+ dependencies: []
19
+
20
+ description: A Ruby library to generate clever dummy data
36
21
  email:
37
22
  - goncalossilva@gmail.com
38
23
  executables: []
@@ -52,9 +37,7 @@ files:
52
37
  - lib/dummy/internet.rb
53
38
  - lib/dummy/geolocation.rb
54
39
  - lib/dummy/phone_number.rb
55
- - lib/generators/dummy_generator.rb
56
40
  - lib/dummy.rb
57
- - lib/generators/templates/dummy.rake
58
41
  - LICENSE
59
42
  - README.md
60
43
  - CHANGELOG.md
@@ -91,6 +74,6 @@ rubyforge_project: dummy
91
74
  rubygems_version: 1.3.7
92
75
  signing_key:
93
76
  specification_version: 3
94
- summary: Generates and imports dummy data for Rails 3 applications
77
+ summary: Generates dummy data
95
78
  test_files: []
96
79
 
@@ -1,194 +0,0 @@
1
- require "yaml"
2
- require "active_support"
3
- require "active_record"
4
- require "rails/generators"
5
-
6
- module Dummy
7
- class DataGenerator < Rails::Generators::Base
8
- def self.source_root
9
- @source_root ||= File.expand_path("../templates", __FILE__)
10
- end
11
-
12
- class_option :base_amount, :type => :numeric, :default => 10,
13
- :desc => "The base amount of records to generate for each model."
14
- class_option :growth_ratio, :type => :numeric, :default => 2.0,
15
- :desc => "The growth ratio of each model, according to its associations."
16
- class_option :manual_amounts, :type => :boolean, :default => false,
17
- :desc => "Manually set the amount of records for each model."
18
- class_option :output_folder, :type => :string, :default => "test/dummy/data",
19
- :desc => "Folder to use when outputting the resulting YAML files."
20
-
21
- def install_dummy
22
- initialize_application
23
- generate_dummy_data
24
- copy_rake_file
25
- end
26
-
27
- private
28
-
29
- def initialize_application
30
- require File.expand_path("#{Rails.root}/config/environment.rb")
31
- say_status :successful, "initialize Rails application"
32
- end
33
-
34
- def generate_dummy_data
35
- get_table_names
36
- gather_associations
37
- predict_record_amounts
38
- generate_and_write_data
39
- end
40
-
41
- def get_table_names
42
- @models = Hash.new
43
- Dir["app/models/*.rb"].each do |full_path|
44
- model = File.basename(full_path).chomp(File.extname(full_path)).camelcase.constantize
45
- @models.merge!({model => {
46
- :record_amount => 0, :associations => []
47
- }}) if model.respond_to?(:columns)
48
- end
49
- end
50
-
51
- def gather_associations
52
- @models.each_key do |model|
53
- model_symbol = model.to_s.underscore.pluralize.to_sym
54
- associations = model.reflect_on_all_associations(:belongs_to)
55
-
56
- associations.each do |assoc|
57
- assoc_name = assoc.name.to_s.camelcase
58
- assoc_options = assoc.options
59
-
60
- if assoc_options.empty?
61
- @models[model][:associations].push({
62
- :model => assoc_name.constantize,
63
- :foreign_key => "#{assoc_name.underscore}_id"
64
- })
65
- elsif assoc_options.has_key?(:class_name) and assoc_options.has_key?(:foreign_key)
66
- @models[model][:associations].push({
67
- :model => assoc_options[:class_name].constantize, # TODO: handle class_name
68
- :foreign_key => assoc_options[:foreign_key]
69
- })
70
- else
71
- next
72
- end
73
-
74
- assoc_model = @models[model][:associations].last[:model]
75
- assoc_reflections = assoc_model.reflect_on_all_associations(:has_one)
76
- @models[model][:associations].pop if assoc_reflections.map(&:name).include?(model_symbol)
77
- end
78
- end
79
- end
80
-
81
- def predict_record_amounts
82
- models = @models.dup
83
- models.each do |model, info|
84
- predict_record_amount(model, info, models, [])
85
- end
86
- end
87
-
88
- def predict_record_amount(model, info, models, stacked_models)
89
- info[:associations].each do |assoc|
90
- next if stacked_models.include?(assoc[:model])
91
-
92
- if model != assoc[:model]
93
- stacked_models << assoc[:model]
94
- predict_record_amount(assoc[:model], @models[assoc[:model]], models, stacked_models)
95
- end
96
- end
97
-
98
- amount = options.base_amount
99
- if not info[:associations].empty?
100
- amount = info[:associations].map do |assoc|
101
- @models[assoc[:model]][:record_amount]
102
- end.max*options.growth_ratio # **info[:associations].size
103
- end
104
-
105
- if options.manual_amounts
106
- user_defined = ask("Number of records for #{model} (default: #{amount}): ")
107
- amount = user_defined unless user_defined.empty?
108
- end
109
-
110
- @models[model][:record_amount] = amount.to_i
111
- stacked_models.delete(model)
112
- models.delete(model)
113
- end
114
-
115
- def generate_and_write_data
116
- empty_directory options.output_folder
117
- data = Hash.new
118
-
119
- @models.each do |model, info|
120
- name = model.to_s.underscore
121
-
122
- (0..info[:record_amount]-1).each do |num|
123
- key_value = Hash.new
124
- fixture_data = Hash.new
125
-
126
- model.columns.each do |column|
127
- key_value = generate_record_data(name, info, column)
128
- fixture_data.merge!(key_value) unless key_value.nil?
129
- end
130
-
131
- data[model.table_name] = Hash.new if data[model.table_name].nil?
132
- data[model.table_name].merge!({ "#{name}_#{num}" => fixture_data })
133
- end
134
-
135
- say_status :successful, "generate #{info[:record_amount]} records for '#{name}'"
136
- end
137
-
138
- data.each do |name, fixtures|
139
- content = "# '#{name}' data generated automatically by dummy at #{Time.now.strftime("%H:%M %m/%d/%Y")} (#{fixtures.size} records).\n"
140
-
141
- content << YAML.dump(fixtures)
142
-
143
- create_file "#{options.output_folder}/#{name}.yml", content
144
- end
145
- say_status :successful, "store fixtures"
146
- end
147
-
148
- def generate_record_data(name, info, column)
149
- column_name = column.name
150
- if(column_name =~ /_at$/ and column.type == :datetime) or column_name == "id"
151
- return
152
- end
153
-
154
- associated_model = associated_class_name(info, column_name)
155
-
156
- if associated_model
157
- val = generate_association_data(associated_model)
158
- column_name.gsub!(/_id$/, "")
159
- else
160
- val = generate_regular_data(column)
161
- end
162
-
163
- {column_name => val}
164
- end
165
-
166
- def associated_class_name(info, name)
167
- info[:associations].each do |assoc|
168
- return assoc[:model] if assoc[:foreign_key] == name
169
- end
170
- false
171
- end
172
-
173
- def generate_association_data(associated_model)
174
- random_record_num = rand(@models[associated_model][:record_amount])
175
- "#{associated_model.to_s.underscore}_#{random_record_num}"
176
- end
177
-
178
- def generate_regular_data(column)
179
- val = Dummy.magic_data(column.name, column.type)
180
-
181
- if val
182
- val
183
- else
184
- say_status :failed, "data generation for '#{column.name}' with type '#{column.type.to_s.downcase}'", :red
185
- ""
186
- end
187
- end
188
-
189
- def copy_rake_file
190
- template "dummy.rake", "lib/tasks/dummy.rake"
191
- end
192
- end
193
- end
194
-
@@ -1,13 +0,0 @@
1
- require 'active_record/fixtures'
2
-
3
- namespace :dummy do
4
- namespace :data do
5
- desc "Load the generated dummy data into the current environment's database."
6
- task :import => :environment do
7
- Fixtures.reset_cache
8
- fixtures_folder = File.join(Rails.root, "<%= options.output_folder %>")
9
- fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }
10
- Fixtures.create_fixtures(fixtures_folder, fixtures)
11
- end
12
- end
13
- end