sprig 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: