dibber 0.2.2 → 0.3.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.
@@ -19,11 +19,11 @@ Add this to your Gemfile:
19
19
 
20
20
  gem 'dibber'
21
21
 
22
- === Examples
22
+ === Rails Examples
23
23
 
24
24
  You have a rails app with a Thing model, and you want to seed it with some
25
25
  things. Thing instances have the attributes 'name', 'colour', 'size'.
26
- You have a YAML file '/db/seeds/things.yml' that looks like this:
26
+ You have a YAML file 'db/seeds/things.yml' that looks like this:
27
27
 
28
28
  foo:
29
29
  colour: red
@@ -36,8 +36,7 @@ You have a YAML file '/db/seeds/things.yml' that looks like this:
36
36
  Add this to your 'db/seeds.rb'
37
37
 
38
38
  Seeder = Dibber::Seeder
39
- Seeder.seeds_path = "#{Rails.root}/db/seeds"
40
- Seeder.new(Thing, 'things.yml').build
39
+ Seeder.seed :thing
41
40
  puts Seeder.report
42
41
 
43
42
  Then run 'rake db:seed'
@@ -48,23 +47,56 @@ You'll then be able to do this:
48
47
 
49
48
  thing = Thing.find_by_name(:foo)
50
49
  thing.colour ---> 'red'
50
+
51
+ === Outside Rails
52
+
53
+ Dibber can be used outside of Rails, but in this case you will need to
54
+ specify the location of the seed files.
55
+
56
+ Seeder.seeds_path = "some/path/to/seeds"
57
+
58
+ You can also use this technique in Rails if you want to put your seed files
59
+ in an alternative folder to 'db/seeds'
51
60
 
52
61
  == Report
53
62
 
54
- Each time seeds.rb is run, Seeder will output a report detailing start and
55
- end time, and a log of how the number of things has changed.
63
+ Seeder.report outputs a report detailing start and end time, and a log of how
64
+ the number of things has changed
56
65
 
57
66
  == Overwriting existing entries
58
67
 
59
- As of version 0.2.0, Seeder#build will not overwrite existing data unless
60
- directed to do so.
68
+ Seeder#build will not overwrite existing data unless directed to do so.
61
69
 
62
70
  thing.update_attribute(:colour, 'black')
63
- Seeder.new(Thing, 'things.yml').build
71
+ Seeder.seed :thing
64
72
  thing.reload.colour ----> 'black'
65
73
 
66
- Seeder.new(Thing, 'things.yml', :overwrite => true).build
74
+ Seeder.seed(:thing, :overwrite => true).build
67
75
  thing.reload.colour ----> 'red'
68
76
 
69
- Have a look at the lib/examples folder, for a more detailed guide to how
70
- Dibber is used.
77
+
78
+ == Using alternative class and field name mappings
79
+
80
+ Seeder.seed calls Seeder#build to build the objects defined in the seed files.
81
+ You can call the build method directly if your seed file names do not match
82
+ the class name:
83
+
84
+ Seeder.new(Thing, 'other_things.yml').build
85
+
86
+ == More examples
87
+
88
+ Take a look at test/examples/seeds.rb for some more usage examples.
89
+
90
+ If you clone this app, you can run this example at the project root:
91
+
92
+ ruby test/examples/seeds.rb
93
+
94
+ There is also an example of process log usage:
95
+
96
+ ruby test/examples/process_logs.rb
97
+
98
+
99
+
100
+
101
+
102
+
data/Rakefile CHANGED
@@ -15,5 +15,5 @@ Rake::RDocTask.new do |rdoc|
15
15
  end
16
16
 
17
17
  Rake::TestTask.new do |t|
18
- t.test_files = FileList['test/**/*.rb']
18
+ t.test_files = FileList['test/**/*_test.rb']
19
19
  end
@@ -29,5 +29,9 @@ module Dibber
29
29
  return @report
30
30
  end
31
31
 
32
+ def exists?(name)
33
+ @log.keys.include?(name)
34
+ end
35
+
32
36
  end
33
37
  end
@@ -5,6 +5,13 @@ module Dibber
5
5
  class Seeder
6
6
  attr_accessor :klass, :file, :attribute_method, :name_method, :overwrite
7
7
 
8
+ def self.seed(name, args = {})
9
+ class_name = name.to_s.strip.classify
10
+ new_klass = (/\A\w+(::\w+)+\Z/ =~ class_name) ? eval(class_name) : Kernel.const_get(class_name)
11
+ new_file = "#{name.to_s.pluralize}.yml"
12
+ new(new_klass, new_file, args).build
13
+ end
14
+
8
15
  def self.process_log
9
16
  @process_log || start_process_log
10
17
  end
@@ -20,7 +27,10 @@ module Dibber
20
27
  end
21
28
 
22
29
  def self.monitor(klass)
23
- process_log.start(klass.to_s.tableize.to_sym, "#{klass}.count")
30
+ log_name = klass.to_s.tableize.to_sym
31
+ unless process_log.exists?(log_name)
32
+ process_log.start(log_name, "#{klass}.count")
33
+ end
24
34
  end
25
35
 
26
36
  def self.objects_from(file)
@@ -28,15 +38,13 @@ module Dibber
28
38
  end
29
39
 
30
40
  def self.seeds_path
31
- @seeds_path || raise_no_seeds_path_error
41
+ @seeds_path || try_to_guess_seeds_path || raise_no_seeds_path_error
32
42
  end
33
43
 
34
44
  def self.seeds_path=(path)
35
- path = path + '/' unless path =~ /\/$/
36
- @seeds_path = path
45
+ @seeds_path = add_trailing_slash_to(path)
37
46
  end
38
47
 
39
-
40
48
  def initialize(klass, file, args = {})
41
49
  @klass = klass
42
50
  @file = file
@@ -47,8 +55,8 @@ module Dibber
47
55
  end
48
56
 
49
57
  def build
50
- start_log
51
58
  check_objects_exist
59
+ start_log
52
60
  objects.each do |name, attributes|
53
61
  object = klass.send(retrieval_method, name)
54
62
  if overwrite or object.new_record?
@@ -79,5 +87,16 @@ module Dibber
79
87
  "find_or_initialize_by_#{name_method}"
80
88
  end
81
89
 
90
+ def self.try_to_guess_seeds_path
91
+ path = File.expand_path('db/seeds', Rails.root) if defined? Rails
92
+ add_trailing_slash_to(path)
93
+ end
94
+
95
+
96
+ def self.add_trailing_slash_to(path = nil)
97
+ path = path + '/' if path and path !~ /\/$/
98
+ path
99
+ end
100
+
82
101
  end
83
102
  end
@@ -1,9 +1,13 @@
1
1
  module Dibber
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
4
4
 
5
5
  # History
6
6
  # =======
7
+ # 0.3.0 Adds seed method
8
+ # Allows seeding to be carried out via Dibber::Seeder.seed(:thing).
9
+ # Also tidies up examples
10
+ #
7
11
  # 0.2.2 Minor bug fix. There was an error in the example. Also a small bit
8
12
  # of house keeping (adding license to gemspec, and removing Gemfile.lock
9
13
  # from repository.
@@ -44,5 +44,11 @@ module Dibber
44
44
  expected = ['No finish was 1, now 1.']
45
45
  assert_equal(expected, @process_log.report)
46
46
  end
47
+
48
+ def test_exists_method
49
+ assert !@process_log.exists?(:one), "There should not be a log for :one yet"
50
+ test_one
51
+ assert @process_log.exists?(:one), "There should be log for :one"
52
+ end
47
53
  end
48
54
  end
@@ -9,7 +9,7 @@ module Dibber
9
9
  class SeederTest < Test::Unit::TestCase
10
10
 
11
11
  def setup
12
- Seeder.seeds_path = File.join(File.dirname(__FILE__),'seeds')
12
+ Seeder.seeds_path = File.join(File.dirname(__FILE__), 'seeds')
13
13
  end
14
14
 
15
15
  def teardown
@@ -121,6 +121,65 @@ module Dibber
121
121
  assert_equal([foo, bar], Thing.saved)
122
122
  assert_equal({'title' => 'one'}, foo.attributes)
123
123
  end
124
+
125
+ def test_seed
126
+ assert_equal(0, Thing.count)
127
+ Seeder.seed(:things)
128
+ assert_equal(2, Thing.count)
129
+ foo = Thing.find_or_initialize_by_name(:foo)
130
+ bar = Thing.find_or_initialize_by_name(:bar)
131
+ assert_equal([foo, bar], Thing.saved)
132
+ assert_equal({'title' => 'one'}, foo.attributes)
133
+ end
134
+
135
+ def test_seed_with_alternative_name_method
136
+ Seeder.seed(:things, :name_method => 'other_method')
137
+ assert_equal(2, Thing.count)
138
+ foo = Thing.find_or_initialize_by_other_method(:foo)
139
+ bar = Thing.find_or_initialize_by_other_method(:bar)
140
+ assert_equal([foo, bar], Thing.saved)
141
+ assert_equal({'title' => 'one'}, foo.attributes)
142
+ end
143
+
144
+ def test_seed_with_non_existent_class
145
+ assert_raise NameError do
146
+ Seeder.seed(:non_existent_class)
147
+ end
148
+ end
149
+
150
+ def test_seed_with_non_existent_seed_file
151
+ no_file_found_error = Errno::ENOENT
152
+ assert_raise no_file_found_error do
153
+ Seeder.seed(:array)
154
+ end
155
+ end
156
+
157
+ def test_seeds_path_with_none_set
158
+ Seeder.seeds_path = nil
159
+ assert_raise RuntimeError do
160
+ Seeder.seeds_path
161
+ end
162
+ end
163
+
164
+ def test_process_log_not_reset_by_second_seed_process_on_same_class
165
+ Seeder.seed(:things)
166
+ original_start = Seeder.process_log.raw[:things][:start]
167
+ Seeder.seed(:things)
168
+ assert_equal original_start, Seeder.process_log.raw[:things][:start]
169
+ end
170
+
171
+ module DummyRails
172
+ def self.root
173
+ '/some/path'
174
+ end
175
+ end
176
+
177
+ def test_seeds_path_if_Rails_exists
178
+ Dibber.const_set :Rails, DummyRails
179
+ Seeder.seeds_path = nil
180
+ assert_equal '/some/path/db/seeds/', Seeder.seeds_path
181
+ Dibber.send(:remove_const, :Rails)
182
+ end
124
183
 
125
184
 
126
185
  private
@@ -1,55 +1,5 @@
1
- class Thing
2
- attr_reader :name
3
- attr_accessor :attributes, :other_method
4
-
5
- def initialize(name = nil)
6
- @name = name.to_s if name
7
- self.class.members << self
8
- end
9
-
10
- def save
11
- self.class.saved << self if new_record?
12
- true
13
- end
14
-
15
- def new_record?
16
- !self.class.saved.include? self
17
- end
18
-
19
- def self.find_or_initialize_by_name(name)
20
- existing = members.select{|m| m.name == name.to_s}
21
- if existing.empty?
22
- new(name)
23
- else
24
- existing.first
25
- end
26
- end
27
-
28
- def self.find_or_initialize_by_other_method(data)
29
- existing = members.select{|m| m.other_method == data.to_s}
30
- if existing.empty?
31
- thing = new
32
- thing.other_method = data.to_s
33
- thing
34
- else
35
- existing.first
36
- end
37
- end
38
-
39
- def self.members
40
- @members ||= []
41
- end
42
-
43
- def self.count
44
- members.length
45
- end
46
-
47
- def self.saved
48
- @saved ||= []
49
- end
50
-
51
- def self.clear_all
52
- @members = []
53
- @saved = []
54
- end
1
+ require_relative '../not_quite_active_record'
2
+
3
+ class Thing < NotQuiteActiveRecord
4
+ attr_accessor :other_method
55
5
  end
@@ -0,0 +1,5 @@
1
+ require_relative '../../not_quite_active_record'
2
+
3
+ class AdminUser < NotQuiteActiveRecord
4
+ attr_accessor :title, :header, :footer
5
+ end
@@ -0,0 +1,5 @@
1
+ require_relative '../../not_quite_active_record'
2
+
3
+ class Borough < NotQuiteActiveRecord
4
+
5
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../../not_quite_active_record'
2
+ class Category < NotQuiteActiveRecord
3
+
4
+ attr_accessor :description, :title
5
+
6
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../../not_quite_active_record'
2
+ module Disclaimer
3
+ class Document < NotQuiteActiveRecord
4
+ attr_accessor :title, :header, :footer
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ require_relative '../../not_quite_active_record'
2
+
3
+ class Fee < NotQuiteActiveRecord
4
+ attr_accessor :description, :value, :title
5
+ end
@@ -1,4 +1,4 @@
1
- require_relative '../dibber/process_log'
1
+ require_relative '../../lib/dibber/process_log'
2
2
 
3
3
  process_log = Dibber::ProcessLog.new
4
4
  process_log.start :time_one, 'Time.now'
@@ -1,7 +1,13 @@
1
+ require_relative '../../lib/dibber'
2
+
3
+ models = %w{borough admin_user fee disclaimer category}
4
+ models.each {|model| require_relative "models/#{model}"}
5
+
6
+
1
7
  Seeder = Dibber::Seeder
2
8
 
3
9
  # Set up the path to seed YAML files
4
- Seeder.seeds_path = "#{Rails.root}/db/seeds"
10
+ Seeder.seeds_path = File.expand_path('seeds', File.dirname(__FILE__))
5
11
 
6
12
  # Example 1. Seeder is used to monitor the process
7
13
  # and grab the attributes from the YAML file
@@ -30,22 +36,31 @@ Seeder.new(Fee, 'fees.yml').build
30
36
  # Example 4. Seeder using an alternative name field
31
37
  Seeder.new(Fee, 'fees.yml', :name_method => :title).build
32
38
 
33
- # Example 5. Seeder working with a name spaced object
39
+ # Example 5. If the seed file's name is the lower case plural of the class name
40
+ # you can use the seed method:
41
+ Seeder.seed(:fee)
42
+
43
+ # Example 6. Seeder working with a name-spaced object
34
44
  Seeder.new(Disclaimer::Document, 'disclaimer/documents.yml').build
35
45
 
36
- # Example 6. Seeder using values in the yaml file to set a single field
37
- Seeder.new(Category, 'categories.yml', 'description').build
46
+ # Example 7. You can also use the seed method with name-spaced objects.
47
+ # In this case the seed files need to be in a name-spaced path (see previous
48
+ # example)
49
+ Seeder.seed('disclaimer/document')
50
+
51
+ # Example 8. Seeder using values in the yaml file to set a single field
52
+ Seeder.seed(:category, 'description')
38
53
 
39
- # Example 7. Seeder using alternative name and attributes fields
40
- Seeder.new(
41
- Category,
42
- 'categories.yml',
54
+ # Example 9. Seeder using alternative name and attributes fields
55
+ Seeder.seed(
56
+ :category,
43
57
  :name_method => :title,
44
58
  :attributes_method => :description
45
- ).build
59
+ )
46
60
 
47
- # You can also access Seeders attached process log, and set up a custom log
48
- Seeder.process_log.start('First questionnaire questions', 'Questionnaire.count > 0 ? Questionnaire.first.questions.length : 0')
61
+ # Example 10. You can also access Seeders attached process log, and set up a
62
+ # custom log
63
+ Seeder.process_log.start('Time to end of report', 'Time.now')
49
64
 
50
65
  # Output a report showing how the numbers of each type of object
51
66
  # have changed through the process. Also has a log of start and end time.
File without changes
@@ -0,0 +1,79 @@
1
+ # Mock ActiveRecord::Base
2
+ class NotQuiteActiveRecord
3
+ attr_reader :name
4
+ attr_accessor :attributes
5
+
6
+ def initialize(name = nil)
7
+ @name = name.to_s if name
8
+ self.class.members << self
9
+ end
10
+
11
+ def save
12
+ self.class.saved << self if new_record?
13
+ true
14
+ end
15
+
16
+ def new_record?
17
+ !self.class.saved.include? self
18
+ end
19
+
20
+ def self.find_or_initialize_by_name(name)
21
+ existing = members.select{|m| m.name == name.to_s}
22
+ if existing.empty?
23
+ new(name)
24
+ else
25
+ existing.first
26
+ end
27
+ end
28
+
29
+ def self.find_or_initialize_by_title(title)
30
+ existing = members.select{|m| m.title == title.to_s}
31
+ if existing.empty?
32
+ fee = new
33
+ fee.title = title
34
+ fee
35
+ else
36
+ existing.first
37
+ end
38
+ end
39
+
40
+ def self.find_or_create_by_name(name)
41
+ find_or_initialize_by_name(name).save
42
+ end
43
+
44
+ def self.find_or_initialize_by_other_method(data)
45
+ existing = members.select{|m| m.other_method == data.to_s}
46
+ if existing.empty?
47
+ thing = new
48
+ thing.other_method = data.to_s
49
+ thing
50
+ else
51
+ existing.first
52
+ end
53
+ end
54
+
55
+ def self.exists?(hash)
56
+ !members.select{|m| m.send(hash.first[0]) == hash.first[1].to_s}.empty?
57
+ end
58
+
59
+ def self.create!(hash)
60
+ new(hash).save
61
+ end
62
+
63
+ def self.members
64
+ @members ||= []
65
+ end
66
+
67
+ def self.count
68
+ members.length
69
+ end
70
+
71
+ def self.saved
72
+ @saved ||= []
73
+ end
74
+
75
+ def self.clear_all
76
+ @members = []
77
+ @saved = []
78
+ end
79
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dibber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-01 00:00:00.000000000 Z
12
+ date: 2013-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: active_support
@@ -35,12 +35,6 @@ executables: []
35
35
  extensions: []
36
36
  extra_rdoc_files: []
37
37
  files:
38
- - lib/examples/process_logs.rb
39
- - lib/examples/seeds/boroughs.yml
40
- - lib/examples/seeds/disclaimer/documents.yml
41
- - lib/examples/seeds/fees.yml
42
- - lib/examples/seeds/categories.yml
43
- - lib/examples/seeds.rb
44
38
  - lib/dibber.rb
45
39
  - lib/dibber/version.rb
46
40
  - lib/dibber/process_log.rb
@@ -48,6 +42,18 @@ files:
48
42
  - MIT-LICENSE
49
43
  - Rakefile
50
44
  - README.rdoc
45
+ - test/examples/process_logs.rb
46
+ - test/examples/models/admin_user.rb
47
+ - test/examples/models/disclaimer.rb
48
+ - test/examples/models/category.rb
49
+ - test/examples/models/borough.rb
50
+ - test/examples/models/fee.rb
51
+ - test/examples/seeds/boroughs.yml
52
+ - test/examples/seeds/disclaimer/documents.yml
53
+ - test/examples/seeds/fees.yml
54
+ - test/examples/seeds/categories.yml
55
+ - test/examples/seeds.rb
56
+ - test/not_quite_active_record.rb
51
57
  - test/dibber/seeder_test.rb
52
58
  - test/dibber/thing.rb
53
59
  - test/dibber/process_log_test.rb
@@ -80,6 +86,18 @@ signing_key:
80
86
  specification_version: 3
81
87
  summary: Tool for seeding database from YAML.
82
88
  test_files:
89
+ - test/examples/process_logs.rb
90
+ - test/examples/models/admin_user.rb
91
+ - test/examples/models/disclaimer.rb
92
+ - test/examples/models/category.rb
93
+ - test/examples/models/borough.rb
94
+ - test/examples/models/fee.rb
95
+ - test/examples/seeds/boroughs.yml
96
+ - test/examples/seeds/disclaimer/documents.yml
97
+ - test/examples/seeds/fees.yml
98
+ - test/examples/seeds/categories.yml
99
+ - test/examples/seeds.rb
100
+ - test/not_quite_active_record.rb
83
101
  - test/dibber/seeder_test.rb
84
102
  - test/dibber/thing.rb
85
103
  - test/dibber/process_log_test.rb