sprig 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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +131 -0
  4. data/Rakefile +5 -0
  5. data/lib/sprig.rb +29 -0
  6. data/lib/sprig/configuration.rb +16 -0
  7. data/lib/sprig/data.rb +6 -0
  8. data/lib/sprig/dependency.rb +45 -0
  9. data/lib/sprig/dependency_collection.rb +23 -0
  10. data/lib/sprig/dependency_sorter.rb +83 -0
  11. data/lib/sprig/directive.rb +37 -0
  12. data/lib/sprig/directive_list.rb +30 -0
  13. data/lib/sprig/helpers.rb +25 -0
  14. data/lib/sprig/parser.rb +9 -0
  15. data/lib/sprig/parser/base.rb +15 -0
  16. data/lib/sprig/parser/csv.rb +22 -0
  17. data/lib/sprig/parser/google_spreadsheet_json.rb +35 -0
  18. data/lib/sprig/parser/json.rb +9 -0
  19. data/lib/sprig/parser/yml.rb +9 -0
  20. data/lib/sprig/planter.rb +39 -0
  21. data/lib/sprig/seed.rb +9 -0
  22. data/lib/sprig/seed/attribute.rb +54 -0
  23. data/lib/sprig/seed/attribute_collection.rb +33 -0
  24. data/lib/sprig/seed/entry.rb +80 -0
  25. data/lib/sprig/seed/factory.rb +56 -0
  26. data/lib/sprig/seed/record.rb +35 -0
  27. data/lib/sprig/source.rb +143 -0
  28. data/lib/sprig/sprig_logger.rb +68 -0
  29. data/lib/sprig/sprig_record_store.rb +31 -0
  30. data/lib/sprig/version.rb +3 -0
  31. data/spec/db/activerecord.db +0 -0
  32. data/spec/feature/configurations_spec.rb +30 -0
  33. data/spec/fixtures/cassettes/google_spreadsheet_json_posts.yml +60 -0
  34. data/spec/fixtures/models/comment.rb +5 -0
  35. data/spec/fixtures/models/post.rb +2 -0
  36. data/spec/fixtures/seeds/staging/posts.yml +6 -0
  37. data/spec/fixtures/seeds/test/comments.yml +6 -0
  38. data/spec/fixtures/seeds/test/legacy_posts.yml +6 -0
  39. data/spec/fixtures/seeds/test/posts.csv +2 -0
  40. data/spec/fixtures/seeds/test/posts.json +1 -0
  41. data/spec/fixtures/seeds/test/posts.yml +6 -0
  42. data/spec/fixtures/seeds/test/posts_find_existing_by_multiple.yml +9 -0
  43. data/spec/fixtures/seeds/test/posts_find_existing_by_single.yml +8 -0
  44. data/spec/fixtures/seeds/test/posts_missing_dependency.yml +7 -0
  45. data/spec/lib/sprig/configuration_spec.rb +21 -0
  46. data/spec/lib/sprig/directive_list_spec.rb +24 -0
  47. data/spec/lib/sprig/directive_spec.rb +60 -0
  48. data/spec/spec_helper.rb +75 -0
  49. data/spec/sprig_spec.rb +205 -0
  50. metadata +211 -0
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sprig::Directive do
4
+
5
+ describe "#klass" do
6
+ context "given a class" do
7
+ subject { described_class.new(Post) }
8
+
9
+ its(:klass) { should == Post }
10
+ end
11
+
12
+ context "given options with a class" do
13
+ subject { described_class.new(:class => Post) }
14
+
15
+ its(:klass) { should == Post }
16
+ end
17
+
18
+ context "given options without a class" do
19
+ subject { described_class.new(:source => 'source') }
20
+
21
+ it "raises and argument error" do
22
+ expect {
23
+ subject.klass
24
+ }.to raise_error(
25
+ ArgumentError,
26
+ 'Sprig::Directive must be instantiated with an '\
27
+ 'ActiveRecord subclass or a Hash with :class defined'
28
+ )
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#options" do
34
+ context "given no options" do
35
+ subject { described_class.new(Post) }
36
+
37
+ its(:options) { should == {} }
38
+ end
39
+
40
+ context "given options" do
41
+ subject { described_class.new(:class => Post, :source => 'source') }
42
+
43
+ its(:options) { should == { :source => 'source' } }
44
+ end
45
+ end
46
+
47
+ describe "#datasource" do
48
+ let(:datasource) { double('datasource') }
49
+
50
+ subject { described_class.new(:class => Post, :source => 'source') }
51
+
52
+ before do
53
+ Sprig::Source.stub(:new).with('posts', { :source => 'source' }).and_return(datasource)
54
+ end
55
+
56
+ it "returns a sprig data source" do
57
+ subject.datasource.should == datasource
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,75 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require "rails"
4
+ require "active_record"
5
+ require "database_cleaner"
6
+ require "webmock"
7
+ require "vcr"
8
+ require "pry"
9
+
10
+ require "sprig"
11
+ include Sprig::Helpers
12
+
13
+ Dir[File.dirname(__FILE__) + '/fixtures/models/*.rb'].each {|file| require file }
14
+
15
+ RSpec.configure do |c|
16
+ c.before(:suite) do
17
+ DatabaseCleaner.strategy = :transaction
18
+ DatabaseCleaner.clean_with(:truncation)
19
+ end
20
+
21
+ c.before(:each) do
22
+ DatabaseCleaner.start
23
+ end
24
+
25
+ c.after(:each) do
26
+ DatabaseCleaner.clean
27
+
28
+ Sprig.reset_configuration
29
+ end
30
+ end
31
+
32
+ VCR.configure do |c|
33
+ c.configure_rspec_metadata!
34
+ c.cassette_library_dir = 'spec/fixtures/cassettes'
35
+ c.hook_into :webmock
36
+ end
37
+
38
+ # Database
39
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "spec/db/activerecord.db")
40
+
41
+ #User.connection.execute "DROP TABLE IF EXISTS users;"
42
+ #User.connection.execute "CREATE TABLE users (id INTEGER PRIMARY KEY , first_name VARCHAR(255), last_name VARCHAR(255));"
43
+
44
+ Post.connection.execute "DROP TABLE IF EXISTS posts;"
45
+ Post.connection.execute "CREATE TABLE posts (id INTEGER PRIMARY KEY , title VARCHAR(255), content VARCHAR(255), published BOOLEAN);"
46
+
47
+ Comment.connection.execute "DROP TABLE IF EXISTS comments;"
48
+ Comment.connection.execute "CREATE TABLE comments (id INTEGER PRIMARY KEY , post_id INTEGER, body VARCHAR(255));"
49
+
50
+ # Helpers
51
+ #
52
+ # Setup fake `Rails.root`
53
+ def stub_rails_root(path='./spec/fixtures')
54
+ Rails.stub(:root).and_return(Pathname.new(path))
55
+ end
56
+
57
+ # Setup fake `Rails.env`
58
+ def stub_rails_env(env='development')
59
+ Rails.stub(:env).and_return(env)
60
+ end
61
+
62
+ # Copy and Remove Seed files around a spec
63
+ def load_seeds(*files)
64
+ env = Rails.env
65
+
66
+ files.each do |file|
67
+ `cp ./spec/fixtures/seeds/#{env}/#{file} ./spec/fixtures/db/seeds/#{env}`
68
+ end
69
+
70
+ yield
71
+
72
+ files.each do |file|
73
+ `rm ./spec/fixtures/db/seeds/#{env}/#{file}`
74
+ end
75
+ end
@@ -0,0 +1,205 @@
1
+ require 'spec_helper'
2
+ require 'open-uri'
3
+
4
+ describe "Seeding an application" do
5
+ before do
6
+ stub_rails_root
7
+ end
8
+
9
+ context "with a yaml file" do
10
+ around do |example|
11
+ load_seeds('posts.yml', &example)
12
+ end
13
+
14
+ it "seeds the db" do
15
+ sprig [Post]
16
+
17
+ Post.count.should == 1
18
+ Post.pluck(:title).should =~ ['Yaml title']
19
+ end
20
+ end
21
+
22
+ context "with a csv file" do
23
+ around do |example|
24
+ load_seeds('posts.csv', &example)
25
+ end
26
+
27
+ it "seeds the db" do
28
+ sprig [Post]
29
+
30
+ Post.count.should == 1
31
+ Post.pluck(:title).should =~ ['Csv title']
32
+ end
33
+ end
34
+
35
+ context "with a json file" do
36
+ around do |example|
37
+ load_seeds('posts.json', &example)
38
+ end
39
+
40
+ it "seeds the db" do
41
+ sprig [Post]
42
+
43
+ Post.count.should == 1
44
+ Post.pluck(:title).should =~ ['Json title']
45
+ end
46
+ end
47
+
48
+ context "with a google spreadsheet" do
49
+ it "seeds the db", :vcr => { :cassette_name => 'google_spreadsheet_json_posts' } do
50
+ sprig [
51
+ {
52
+ :class => Post,
53
+ :parser => Sprig::Parser::GoogleSpreadsheetJson,
54
+ :source => open('https://spreadsheets.google.com/feeds/list/0AjVLPMnHm86rdDVHQ2dCUS03RTN5ZUtVNzVOYVBwT0E/1/public/values?alt=json'),
55
+ }
56
+ ]
57
+
58
+ Post.count.should == 1
59
+ Post.pluck(:title).should =~ ['Google spreadsheet json title']
60
+ end
61
+ end
62
+
63
+ context "with a custom source" do
64
+ around do |example|
65
+ load_seeds('legacy_posts.yml', &example)
66
+ end
67
+
68
+ it "seeds" do
69
+ sprig [
70
+ {
71
+ :class => Post,
72
+ :source => open('spec/fixtures/seeds/test/legacy_posts.yml')
73
+ }
74
+ ]
75
+
76
+ Post.count.should == 1
77
+ Post.pluck(:title).should =~ ['Legacy yaml title']
78
+ end
79
+ end
80
+
81
+ context "with multiple file relationships" do
82
+ around do |example|
83
+ load_seeds('posts.yml', 'comments.yml', &example)
84
+ end
85
+
86
+ it "seeds the db" do
87
+ sprig [Post, Comment]
88
+
89
+ Post.count.should == 1
90
+ Comment.count.should == 1
91
+ Comment.first.post.should == Post.first
92
+ end
93
+ end
94
+
95
+ context "with a relationship to an undefined record" do
96
+ around do |example|
97
+ load_seeds('posts.yml', 'posts_missing_dependency.yml', &example)
98
+ end
99
+
100
+ it "raises a helpful error message" do
101
+ expect {
102
+ sprig [
103
+ {
104
+ :class => Post,
105
+ :source => open('spec/fixtures/seeds/test/posts_missing_dependency.yml')
106
+ }
107
+ ]
108
+ }.to raise_error(
109
+ Sprig::DependencySorter::MissingDependencyError,
110
+ "Undefined reference to 'sprig_record(Comment, 42)'"
111
+ )
112
+ end
113
+ end
114
+
115
+ context "with multiple files for a class" do
116
+ around do |example|
117
+ load_seeds('posts.yml', 'legacy_posts.yml', &example)
118
+ end
119
+
120
+ it "seeds the db" do
121
+ sprig [
122
+ Post,
123
+ {
124
+ :class => Post,
125
+ :source => open('spec/fixtures/seeds/test/legacy_posts.yml')
126
+ }
127
+ ]
128
+
129
+ Post.count.should == 2
130
+ Post.pluck(:title).should=~ ['Yaml title', 'Legacy yaml title']
131
+ end
132
+ end
133
+
134
+ context "from a specific environment" do
135
+ around do |example|
136
+ stub_rails_env 'staging'
137
+ load_seeds('posts.yml', &example)
138
+ end
139
+
140
+ it "seeds the db" do
141
+ sprig [Post]
142
+
143
+ Post.count.should == 1
144
+ Post.pluck(:title).should =~ ['Staging yaml title']
145
+ end
146
+ end
147
+
148
+ context "with custom seed options" do
149
+ context "using find_existing_by" do
150
+ context "with a single attribute" do
151
+ around do |example|
152
+ load_seeds('posts.yml', 'posts_find_existing_by_single.yml', &example)
153
+ end
154
+
155
+ context "with an existing record" do
156
+ let!(:existing) do
157
+ Post.create(
158
+ :title => "Existing title",
159
+ :content => "Existing content")
160
+ end
161
+
162
+ it "updates the existing record" do
163
+ sprig [
164
+ {
165
+ :class => Post,
166
+ :source => open("spec/fixtures/seeds/test/posts_find_existing_by_single.yml")
167
+ }
168
+ ]
169
+
170
+ Post.count.should == 1
171
+ existing.reload.content.should == "Updated content"
172
+ end
173
+ end
174
+ end
175
+
176
+ context "with multiple attributes" do
177
+ around do |example|
178
+ load_seeds('posts.yml', 'posts_find_existing_by_multiple.yml', &example)
179
+ end
180
+
181
+ context "with an existing record" do
182
+ let!(:existing) do
183
+ Post.create(
184
+ :title => "Existing title",
185
+ :content => "Existing content",
186
+ :published => false
187
+ )
188
+ end
189
+
190
+ it "updates the existing record" do
191
+ sprig [
192
+ {
193
+ :class => Post,
194
+ :source => open("spec/fixtures/seeds/test/posts_find_existing_by_multiple.yml")
195
+ }
196
+ ]
197
+
198
+ Post.count.should == 1
199
+ existing.reload.published.should == true
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
metadata ADDED
@@ -0,0 +1,211 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sprig
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lawson Kurtz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.8
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.8
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 2.14.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.14.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: database_cleaner
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 1.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.15.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.15.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: vcr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 2.8.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 2.8.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Sprig is a library for managing interconnected, environment-specific
112
+ seed data.
113
+ email:
114
+ - lawson.kurtz@viget.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - MIT-LICENSE
120
+ - README.md
121
+ - Rakefile
122
+ - lib/sprig.rb
123
+ - lib/sprig/configuration.rb
124
+ - lib/sprig/data.rb
125
+ - lib/sprig/dependency.rb
126
+ - lib/sprig/dependency_collection.rb
127
+ - lib/sprig/dependency_sorter.rb
128
+ - lib/sprig/directive.rb
129
+ - lib/sprig/directive_list.rb
130
+ - lib/sprig/helpers.rb
131
+ - lib/sprig/parser.rb
132
+ - lib/sprig/parser/base.rb
133
+ - lib/sprig/parser/csv.rb
134
+ - lib/sprig/parser/google_spreadsheet_json.rb
135
+ - lib/sprig/parser/json.rb
136
+ - lib/sprig/parser/yml.rb
137
+ - lib/sprig/planter.rb
138
+ - lib/sprig/seed.rb
139
+ - lib/sprig/seed/attribute.rb
140
+ - lib/sprig/seed/attribute_collection.rb
141
+ - lib/sprig/seed/entry.rb
142
+ - lib/sprig/seed/factory.rb
143
+ - lib/sprig/seed/record.rb
144
+ - lib/sprig/source.rb
145
+ - lib/sprig/sprig_logger.rb
146
+ - lib/sprig/sprig_record_store.rb
147
+ - lib/sprig/version.rb
148
+ - spec/db/activerecord.db
149
+ - spec/feature/configurations_spec.rb
150
+ - spec/fixtures/cassettes/google_spreadsheet_json_posts.yml
151
+ - spec/fixtures/models/comment.rb
152
+ - spec/fixtures/models/post.rb
153
+ - spec/fixtures/seeds/staging/posts.yml
154
+ - spec/fixtures/seeds/test/comments.yml
155
+ - spec/fixtures/seeds/test/legacy_posts.yml
156
+ - spec/fixtures/seeds/test/posts.csv
157
+ - spec/fixtures/seeds/test/posts.json
158
+ - spec/fixtures/seeds/test/posts.yml
159
+ - spec/fixtures/seeds/test/posts_find_existing_by_multiple.yml
160
+ - spec/fixtures/seeds/test/posts_find_existing_by_single.yml
161
+ - spec/fixtures/seeds/test/posts_missing_dependency.yml
162
+ - spec/lib/sprig/configuration_spec.rb
163
+ - spec/lib/sprig/directive_list_spec.rb
164
+ - spec/lib/sprig/directive_spec.rb
165
+ - spec/spec_helper.rb
166
+ - spec/sprig_spec.rb
167
+ homepage: http://www.github.com/vigetlabs/sprig
168
+ licenses:
169
+ - MIT
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.2.1
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Relational, environment-specific seeding for Rails apps.
191
+ test_files:
192
+ - spec/db/activerecord.db
193
+ - spec/feature/configurations_spec.rb
194
+ - spec/fixtures/cassettes/google_spreadsheet_json_posts.yml
195
+ - spec/fixtures/models/comment.rb
196
+ - spec/fixtures/models/post.rb
197
+ - spec/fixtures/seeds/staging/posts.yml
198
+ - spec/fixtures/seeds/test/comments.yml
199
+ - spec/fixtures/seeds/test/legacy_posts.yml
200
+ - spec/fixtures/seeds/test/posts.csv
201
+ - spec/fixtures/seeds/test/posts.json
202
+ - spec/fixtures/seeds/test/posts.yml
203
+ - spec/fixtures/seeds/test/posts_find_existing_by_multiple.yml
204
+ - spec/fixtures/seeds/test/posts_find_existing_by_single.yml
205
+ - spec/fixtures/seeds/test/posts_missing_dependency.yml
206
+ - spec/lib/sprig/configuration_spec.rb
207
+ - spec/lib/sprig/directive_list_spec.rb
208
+ - spec/lib/sprig/directive_spec.rb
209
+ - spec/spec_helper.rb
210
+ - spec/sprig_spec.rb
211
+ has_rdoc: