dibber 0.0.3 → 0.1.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/README.rdoc CHANGED
@@ -5,10 +5,53 @@ A set of tools to tidy up rails seeds.rb files.
5
5
  Dibber has two compoments:
6
6
 
7
7
  === Seeder
8
+
8
9
  Seeder is designed to simplify the process of pulling attributes from
9
10
  YAML files, and populating ActiveRecord objects with those attributes.
10
11
 
11
12
  === ProcessLog
13
+
12
14
  ProcessLog provides Seeder with a simple before and after reporting tool.
13
15
 
14
- Have a look at the lib/examples folder, for a guide to how Dibber is used.
16
+ === Installation
17
+
18
+ Add this to your Gemfile:
19
+
20
+ gem 'dibber'
21
+
22
+ === Examples
23
+
24
+ You have a rails app with a Thing model, and you want to seed it with some
25
+ things. Thing instances have the attributes 'name', 'colour', 'size'.
26
+ You have a YAML file '/db/seeds/things.yml' that looks like this:
27
+
28
+ foo:
29
+ colour: red
30
+ size: large
31
+
32
+ bar:
33
+ colour: blue
34
+ size: small
35
+
36
+ Add this to your 'db/seeds.rb'
37
+
38
+ Seeder = Dibber::Seeder
39
+ Seeder.seeds_path = "#{Rails.root}/db/seeds"
40
+ Seeder.new(Thing, 'things.yml').build
41
+
42
+ Then run 'rake db:seed'
43
+
44
+ Seeder will create two new things (unless things with the names 'foo' or
45
+ 'bar' already exist, in which case it will update those things with the
46
+ values in the YAML file).
47
+
48
+ You'll then be able to do this:
49
+
50
+ thing = Thing.find_by_name(:foo)
51
+ thing.colour ---> 'red'
52
+
53
+ Each time seeds.rb is run, Seeder will output a report detailing start and
54
+ end time, and a log of how the number of things has changed.
55
+
56
+ Have a look at the lib/examples folder, for a more detailed guide to how
57
+ Dibber is used.
data/lib/dibber/seeder.rb CHANGED
@@ -1,6 +1,9 @@
1
+ require 'active_support/inflector'
2
+ require 'yaml'
3
+
1
4
  module Dibber
2
5
  class Seeder
3
- attr_accessor :klass, :file, :method
6
+ attr_accessor :klass, :file, :attribute_method, :name_method
4
7
 
5
8
  def self.process_log
6
9
  @process_log || start_process_log
@@ -13,7 +16,7 @@ module Dibber
13
16
  end
14
17
 
15
18
  def self.report
16
- @process_log.report
19
+ process_log.report
17
20
  end
18
21
 
19
22
  def self.monitor(klass)
@@ -34,17 +37,20 @@ module Dibber
34
37
  end
35
38
 
36
39
 
37
- def initialize(klass, file, method = 'attributes')
40
+ def initialize(klass, file, args = {})
38
41
  @klass = klass
39
42
  @file = file
40
- @method = method
43
+ args = {:attributes_method => args} unless args.kind_of?(Hash)
44
+ @attribute_method = args[:attributes_method] || 'attributes'
45
+ @name_method = args[:name_method] || 'name'
41
46
  end
42
47
 
43
48
  def build
44
49
  start_log
50
+ check_objects_exist
45
51
  objects.each do |name, attributes|
46
- object = klass.find_or_initialize_by_name(name)
47
- object.send("#{method}=", attributes)
52
+ object = klass.send(retrieval_method, name)
53
+ object.send("#{attribute_method}=", attributes)
48
54
  object.save
49
55
  end
50
56
  end
@@ -54,13 +60,21 @@ module Dibber
54
60
  end
55
61
 
56
62
  def objects
57
- self.class.objects_from(file)
63
+ @objects ||= self.class.objects_from(file)
58
64
  end
59
65
 
60
66
  private
61
67
  def self.raise_no_seeds_path_error
62
68
  raise "You must set the path to your seed files via Seeder.seeds_path = 'path/to/seed/files'"
63
69
  end
70
+
71
+ def check_objects_exist
72
+ raise "No objects returned from file: #{self.class.seeds_path}#{file}" unless objects
73
+ end
74
+
75
+ def retrieval_method
76
+ "find_or_initialize_by_#{name_method}"
77
+ end
64
78
 
65
79
  end
66
80
  end
@@ -0,0 +1,51 @@
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 unless self.class.saved.include? self
12
+ true
13
+ end
14
+
15
+ def self.find_or_initialize_by_name(name)
16
+ existing = members.select{|m| m.name == name.to_s}
17
+ if existing.empty?
18
+ new(name)
19
+ else
20
+ existing.first
21
+ end
22
+ end
23
+
24
+ def self.find_or_initialize_by_other_method(data)
25
+ existing = members.select{|m| m.other_method == data.to_s}
26
+ if existing.empty?
27
+ thing = new
28
+ thing.other_method = data.to_s
29
+ thing
30
+ else
31
+ existing.first
32
+ end
33
+ end
34
+
35
+ def self.members
36
+ @members ||= []
37
+ end
38
+
39
+ def self.count
40
+ members.length
41
+ end
42
+
43
+ def self.saved
44
+ @saved ||= []
45
+ end
46
+
47
+ def self.clear_all
48
+ @members = []
49
+ @saved = []
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module Dibber
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -23,18 +23,30 @@ AdminUser.create!(
23
23
  # Example 3. Seeder grabs the attributes from the YAML and builds a
24
24
  # set of Fee objects with those attributes (or updates them if
25
25
  # they already exist).
26
- # Note that the build process requires the model to have a name field.
26
+ # Note that the build process defaults to using a 'name' field to store
27
+ # the root key.
27
28
  Seeder.new(Fee, 'fees.yml').build
28
29
 
29
- # Example 4. Seeder working with a name spaced object
30
+ # Example 4. Seeder using an alternative name field
31
+ Seeder.new(Fee, 'fees.yml', :name_field => :title).build
32
+
33
+ # Example 5. Seeder working with a name spaced object
30
34
  Seeder.new(Disclaimer::Document, 'disclaimer/documents.yml').build
31
35
 
32
- # Example 5. Seeder using values in the yaml file to set a single field
36
+ # Example 6. Seeder using values in the yaml file to set a single field
33
37
  Seeder.new(Category, 'categories.yml', 'description').build
34
38
 
39
+ # Example 7. Seeder using alternative name and attributes fields
40
+ Seeder.new(
41
+ Category,
42
+ 'categories.yml',
43
+ :name_field => :title,
44
+ :attributes_field => :description
45
+ ).build
46
+
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')
49
+
35
50
  # Output a report showing how the numbers of each type of object
36
51
  # have changed through the process. Also has a log of start and end time.
37
52
  puts Seeder.report
38
-
39
- # You can also access Seeders attached process log, and set up a custom log
40
- Seeder.process_log.start('First questionnaire questions', 'Questionnaire.count > 0 ? Questionnaire.first.questions.length : 0')
@@ -0,0 +1,112 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'../..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'dibber'
5
+ require 'dibber/thing'
6
+
7
+ module Dibber
8
+
9
+ class SeederTest < Test::Unit::TestCase
10
+
11
+ def setup
12
+ Seeder.seeds_path = File.join(File.dirname(__FILE__),'seeds')
13
+ end
14
+
15
+ def teardown
16
+ Thing.clear_all
17
+ end
18
+
19
+ def test_process_log
20
+ assert_kind_of(ProcessLog, Seeder.process_log)
21
+ end
22
+
23
+ def test_process_log_start
24
+ @log = Seeder.process_log
25
+ assert(@log.raw.keys.include?(:time), 'time should be logged')
26
+ end
27
+
28
+ def test_report
29
+ test_process_log_start
30
+ assert_equal(@log.report, Seeder.report)
31
+ end
32
+
33
+ def test_monitor
34
+ Seeder.monitor(Thing)
35
+ assert_equal({:command => 'Thing.count', :start => Thing.count}, Seeder.process_log.raw[:things])
36
+ end
37
+
38
+ def test_seeds_path
39
+ assert_match(/test\/dibber\/seeds\/$/, Seeder.seeds_path)
40
+ end
41
+
42
+ def test_objects_from
43
+ content = YAML.load_file(thing_file_path)
44
+ assert_equal(content, Seeder.objects_from('things.yml'))
45
+ end
46
+
47
+ def test_start_log
48
+ thing_seeder.start_log
49
+ assert(Seeder.process_log.raw.keys.include?(:things), 'Things should be logged')
50
+ end
51
+
52
+ def test_objects
53
+ content = YAML.load_file(thing_file_path)
54
+ assert_equal(content, thing_seeder.objects)
55
+ end
56
+
57
+ def test_build_with_no_objects
58
+ thing_seeder = Seeder.new(Thing, 'empty.yml')
59
+ assert_raise RuntimeError do
60
+ thing_seeder.build
61
+ end
62
+ end
63
+
64
+ def test_build
65
+ assert_equal(0, Thing.count)
66
+ thing_seeder.build
67
+ assert_equal(2, Thing.count)
68
+ foo = Thing.find_or_initialize_by_name(:foo)
69
+ bar = Thing.find_or_initialize_by_name(:bar)
70
+ assert_equal([foo, bar], Thing.saved)
71
+ assert_equal({'title' => 'one'}, foo.attributes)
72
+ end
73
+
74
+ def test_other_method_replacing_attributes
75
+ thing_seeder('other_method').build
76
+ foo = Thing.find_or_initialize_by_name(:foo)
77
+ bar = Thing.find_or_initialize_by_name(:bar)
78
+ assert_equal([foo, bar], Thing.saved)
79
+ assert_nil(foo.attributes)
80
+ assert_equal({'title' => 'one'}, foo.other_method)
81
+ end
82
+
83
+ def test_other_method_replacing_attributes_via_args
84
+ thing_seeder(:attributes_method => 'other_method').build
85
+ foo = Thing.find_or_initialize_by_name(:foo)
86
+ bar = Thing.find_or_initialize_by_name(:bar)
87
+ assert_equal([foo, bar], Thing.saved)
88
+ assert_nil(foo.attributes)
89
+ assert_equal({'title' => 'one'}, foo.other_method)
90
+ end
91
+
92
+ def test_alternative_name_method
93
+ thing_seeder(:name_method => 'other_method').build
94
+ assert_equal(2, Thing.count)
95
+ foo = Thing.find_or_initialize_by_other_method(:foo)
96
+ bar = Thing.find_or_initialize_by_other_method(:bar)
97
+ assert_equal([foo, bar], Thing.saved)
98
+ assert_equal({'title' => 'one'}, foo.attributes)
99
+ end
100
+
101
+
102
+ private
103
+ def thing_seeder(method = 'attributes')
104
+ @thing_seeder = Seeder.new(Thing, 'things.yml', method)
105
+ end
106
+
107
+ def thing_file_path
108
+ File.join(File.dirname(__FILE__),'seeds', 'things.yml')
109
+ end
110
+ end
111
+
112
+ end
@@ -0,0 +1,2 @@
1
+ ## YAML Template.
2
+ ---
@@ -0,0 +1,5 @@
1
+ foo:
2
+ title: one
3
+
4
+ bar:
5
+ title: two
@@ -0,0 +1,81 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),'../..','lib')
2
+
3
+ require 'test/unit'
4
+ require 'dibber/thing'
5
+
6
+ module Dibber
7
+
8
+ class ThingTest < Test::Unit::TestCase
9
+
10
+ def teardown
11
+ Thing.clear_all
12
+ end
13
+
14
+ def test_find_or_initialize_by_name
15
+ @name = 'foo'
16
+ @thing = Thing.find_or_initialize_by_name(@name)
17
+ assert_equal(@name, @thing.name)
18
+ end
19
+
20
+ def test_find_or_initialize_by_name_with_symbol
21
+ test_find_or_initialize_by_name
22
+ assert_equal(1, Thing.count)
23
+ thing = Thing.find_or_initialize_by_name(:foo)
24
+ assert_equal(1, Thing.count)
25
+ assert_equal('foo', thing.name)
26
+ end
27
+
28
+ def test_find_or_initialize_by_name_when_thing_exists
29
+ test_find_or_initialize_by_name
30
+ test_find_or_initialize_by_name
31
+ assert_equal(1, Thing.count)
32
+ end
33
+
34
+ def test_count
35
+ assert_equal(0, Thing.count)
36
+ Thing.find_or_initialize_by_name(:thing_for_count_test)
37
+ assert_equal(1, Thing.count)
38
+ end
39
+
40
+ def test_attributes
41
+ stuff = %w{this that}
42
+ test_find_or_initialize_by_name
43
+ @thing.attributes = stuff
44
+ assert_equal(stuff, @thing.attributes)
45
+ end
46
+
47
+ def test_other_method
48
+ stuff = %w{come home mother}
49
+ test_find_or_initialize_by_name
50
+ @thing.other_method = stuff
51
+ assert_equal(stuff, @thing.other_method)
52
+ end
53
+
54
+ def test_save_and_saved
55
+ thing = Thing.find_or_initialize_by_name(:thing_for_save_test)
56
+ assert !Thing.saved.include?(thing), 'saved things should not include thing'
57
+ assert thing.save, 'should return true on save'
58
+ assert Thing.saved.include?(thing), 'saved things should include thing'
59
+ thing.save
60
+ assert_equal(1, Thing.saved.select{|t| t == thing}.length)
61
+ end
62
+
63
+ def test_clear
64
+ test_find_or_initialize_by_name
65
+ @thing.save
66
+ assert_not_equal(0, Thing.count)
67
+ assert_not_equal([], Thing.saved)
68
+ Thing.clear_all
69
+ assert_equal(0, Thing.count)
70
+ assert_equal([], Thing.saved)
71
+ end
72
+
73
+ def test_find_or_initialize_by_other_method
74
+ thing = Thing.find_or_initialize_by_other_method(:something)
75
+ assert_nil(thing.name)
76
+ assert_equal('something', thing.other_method)
77
+ end
78
+
79
+ end
80
+
81
+ 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.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-19 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: active_support
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
14
30
  description: Packages up code needed to pull data from YAML files when seeding, and
15
31
  adds a process log.
16
32
  email:
@@ -27,12 +43,17 @@ files:
27
43
  - lib/examples/seeds.rb
28
44
  - lib/dibber.rb
29
45
  - lib/dibber/version.rb
46
+ - lib/dibber/thing.rb
30
47
  - lib/dibber/process_log.rb
31
48
  - lib/dibber/seeder.rb
32
49
  - MIT-LICENSE
33
50
  - Rakefile
34
51
  - README.rdoc
52
+ - test/dibber/seeder_test.rb
35
53
  - test/dibber/process_log_test.rb
54
+ - test/dibber/seeds/empty.yml
55
+ - test/dibber/seeds/things.yml
56
+ - test/dibber/thing_test.rb
36
57
  homepage: https://github.com/reggieb/Dibber
37
58
  licenses: []
38
59
  post_install_message:
@@ -58,4 +79,8 @@ signing_key:
58
79
  specification_version: 3
59
80
  summary: Tool for seeding database from YAML.
60
81
  test_files:
82
+ - test/dibber/seeder_test.rb
61
83
  - test/dibber/process_log_test.rb
84
+ - test/dibber/seeds/empty.yml
85
+ - test/dibber/seeds/things.yml
86
+ - test/dibber/thing_test.rb