sprig 0.2.0 → 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.
- checksums.yaml +4 -4
- data/README.md +33 -11
- data/lib/generators/sprig/install_generator.rb +5 -1
- data/lib/sprig.rb +5 -1
- data/lib/sprig/configuration.rb +19 -2
- data/lib/sprig/helpers.rb +15 -3
- data/lib/sprig/version.rb +8 -1
- data/spec/feature/configurations_spec.rb +5 -5
- data/spec/fixtures/seeds/shared/comments.yml +4 -0
- data/spec/fixtures/seeds/shared/files/cat.png +0 -0
- data/spec/fixtures/seeds/shared/invalid_users.yml +4 -0
- data/spec/fixtures/seeds/shared/legacy_posts.yml +4 -0
- data/spec/fixtures/seeds/shared/posts.csv +2 -0
- data/spec/fixtures/seeds/shared/posts.json +1 -0
- data/spec/fixtures/seeds/shared/posts.md +5 -0
- data/spec/fixtures/seeds/shared/posts.yml +4 -0
- data/spec/fixtures/seeds/shared/posts_delete_existing_by.yml +7 -0
- data/spec/fixtures/seeds/shared/posts_find_existing_by_missing.yml +7 -0
- data/spec/fixtures/seeds/shared/posts_find_existing_by_multiple.yml +8 -0
- data/spec/fixtures/seeds/shared/posts_find_existing_by_single.yml +7 -0
- data/spec/fixtures/seeds/shared/posts_missing_dependency.yml +5 -0
- data/spec/fixtures/seeds/shared/posts_missing_record.yml +5 -0
- data/spec/fixtures/seeds/shared/posts_partially_dynamic_value.yml +4 -0
- data/spec/fixtures/seeds/shared/posts_with_cyclic_dependencies.yml +4 -0
- data/spec/fixtures/seeds/shared/posts_with_files.yml +5 -0
- data/spec/fixtures/seeds/shared/posts_with_habtm.yml +7 -0
- data/spec/fixtures/seeds/shared/tags.yml +5 -0
- data/spec/lib/generators/sprig/install_generator_spec.rb +6 -2
- data/spec/lib/sprig/configuration_spec.rb +6 -6
- data/spec/lib/sprig/directive_list_spec.rb +4 -4
- data/spec/lib/sprig/directive_spec.rb +19 -9
- data/spec/lib/sprig/null_record_spec.rb +2 -2
- data/spec/lib/sprig/parser/base_spec.rb +1 -1
- data/spec/lib/sprig/process_notifier_spec.rb +1 -1
- data/spec/lib/sprig/seed/entry_spec.rb +3 -3
- data/spec/lib/sprig/seed/record_spec.rb +3 -3
- data/spec/lib/sprig/source_spec.rb +2 -2
- data/spec/lib/sprig_spec.rb +8 -8
- data/spec/spec_helper.rb +24 -8
- data/spec/sprig_shared_spec.rb +467 -0
- data/spec/sprig_spec.rb +37 -37
- data/spec/support/helpers/logger_mock.rb +2 -1
- metadata +89 -58
- data/lib/sprig/data.rb +0 -6
- data/spec/db/activerecord.db +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::DirectiveList do
|
3
|
+
RSpec.describe Sprig::DirectiveList do
|
4
4
|
|
5
5
|
describe "#add_seeds_to_hopper" do
|
6
6
|
let(:hopper) { Array.new }
|
@@ -10,13 +10,13 @@ describe Sprig::DirectiveList do
|
|
10
10
|
subject { described_class.new(Post) }
|
11
11
|
|
12
12
|
before do
|
13
|
-
Sprig::Directive.
|
13
|
+
allow(Sprig::Directive).to receive(:new).with(Post).and_return(directive)
|
14
14
|
|
15
|
-
Sprig::Seed::Factory.
|
15
|
+
allow(Sprig::Seed::Factory).to receive(:new_from_directive).with(directive).and_return(seed_factory)
|
16
16
|
end
|
17
17
|
|
18
18
|
it "builds seeds from directives and adds to the given array" do
|
19
|
-
seed_factory.
|
19
|
+
expect(seed_factory).to receive(:add_seeds_to_hopper).with(hopper)
|
20
20
|
|
21
21
|
subject.add_seeds_to_hopper(hopper)
|
22
22
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::Directive do
|
3
|
+
RSpec.describe Sprig::Directive do
|
4
4
|
|
5
5
|
module Users
|
6
6
|
class Admin < User
|
@@ -11,19 +11,25 @@ describe Sprig::Directive do
|
|
11
11
|
context "given a class" do
|
12
12
|
subject { described_class.new(Post) }
|
13
13
|
|
14
|
-
|
14
|
+
it "returns the class" do
|
15
|
+
expect(subject.klass).to eq(Post)
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
17
19
|
context "given a class within a module" do
|
18
20
|
subject { described_class.new(Users::Admin) }
|
19
21
|
|
20
|
-
|
22
|
+
it "returns the full class" do
|
23
|
+
expect(subject.klass).to eq(Users::Admin)
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
27
|
context "given options with a class" do
|
24
28
|
subject { described_class.new(:class => Post) }
|
25
29
|
|
26
|
-
|
30
|
+
it "returns the class" do
|
31
|
+
expect(subject.klass).to eq(Post)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
context "given options without a class" do
|
@@ -45,13 +51,17 @@ describe Sprig::Directive do
|
|
45
51
|
context "given no options" do
|
46
52
|
subject { described_class.new(Post) }
|
47
53
|
|
48
|
-
|
54
|
+
it "returns an empty hash" do
|
55
|
+
expect(subject.options).to eq({})
|
56
|
+
end
|
49
57
|
end
|
50
58
|
|
51
59
|
context "given options" do
|
52
60
|
subject { described_class.new(:class => Post, :source => 'source') }
|
53
61
|
|
54
|
-
|
62
|
+
it "returns a the options" do
|
63
|
+
expect(subject.options).to eq(:source => 'source')
|
64
|
+
end
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
@@ -62,11 +72,11 @@ describe Sprig::Directive do
|
|
62
72
|
subject { described_class.new(:class => Post, :source => 'source') }
|
63
73
|
|
64
74
|
before do
|
65
|
-
Sprig::Source.
|
75
|
+
allow(Sprig::Source).to receive(:new).with('posts', { :source => 'source' }).and_return(datasource)
|
66
76
|
end
|
67
77
|
|
68
78
|
it "returns a sprig data source" do
|
69
|
-
subject.datasource.
|
79
|
+
expect(subject.datasource).to eq(datasource)
|
70
80
|
end
|
71
81
|
end
|
72
82
|
|
@@ -74,7 +84,7 @@ describe Sprig::Directive do
|
|
74
84
|
subject { described_class.new(Users::Admin) }
|
75
85
|
|
76
86
|
it "passes the correct path to Source" do
|
77
|
-
Sprig::Source.
|
87
|
+
expect(Sprig::Source).to receive(:new).with("users_admins", {})
|
78
88
|
|
79
89
|
subject.datasource
|
80
90
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::NullRecord do
|
3
|
+
RSpec.describe Sprig::NullRecord do
|
4
4
|
let(:error_msg) { 'Something bad happened.' }
|
5
5
|
subject { described_class.new(error_msg) }
|
6
6
|
|
@@ -14,7 +14,7 @@ describe Sprig::NullRecord do
|
|
14
14
|
|
15
15
|
describe "#method_missing" do
|
16
16
|
it "returns nil for undefined method calls" do
|
17
|
-
subject.enhance_your_calm.
|
17
|
+
expect(subject.enhance_your_calm).to eq(nil)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::Seed::Entry do
|
3
|
+
RSpec.describe Sprig::Seed::Entry do
|
4
4
|
describe ".success_log_text" do
|
5
5
|
context "on a new record" do
|
6
6
|
it "indicates the record was 'saved'" do
|
7
7
|
subject = described_class.new(Post, { title: "Hello World!", content: "Stuff", sprig_id: 1 }, {})
|
8
8
|
subject.save_record
|
9
9
|
|
10
|
-
subject.success_log_text.
|
10
|
+
expect(subject.success_log_text).to eq("Saved")
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -24,7 +24,7 @@ describe Sprig::Seed::Entry do
|
|
24
24
|
subject = described_class.new(Post, { title: "Existing title", content: "Existing content", sprig_id: 1 }, { find_existing_by: [:title] })
|
25
25
|
subject.save_record
|
26
26
|
|
27
|
-
subject.success_log_text.
|
27
|
+
expect(subject.success_log_text).to eq("Updated")
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::Seed::Record do
|
3
|
+
RSpec.describe Sprig::Seed::Record do
|
4
4
|
describe ".existing?" do
|
5
5
|
let!(:existing) do
|
6
6
|
Post.create(
|
@@ -13,13 +13,13 @@ describe Sprig::Seed::Record do
|
|
13
13
|
it "returns true if the record has already been saved to the database" do
|
14
14
|
subject = described_class.new_or_existing(Post, { title: "Existing title" }, { title: "Existing title" })
|
15
15
|
|
16
|
-
subject.existing
|
16
|
+
expect(subject.existing?).to eq(true)
|
17
17
|
end
|
18
18
|
|
19
19
|
it "returns false if the record is new" do
|
20
20
|
subject = described_class.new_or_existing(Post, { title: "New title" }, { title: "New title" })
|
21
21
|
|
22
|
-
subject.existing
|
22
|
+
expect(subject.existing?).to eq(false)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig::NullRecord do
|
3
|
+
RSpec.describe Sprig::NullRecord do
|
4
4
|
let(:error_msg) { 'Something bad happened.' }
|
5
5
|
subject { described_class.new(error_msg) }
|
6
6
|
|
@@ -14,7 +14,7 @@ describe Sprig::NullRecord do
|
|
14
14
|
|
15
15
|
describe "#method_missing" do
|
16
16
|
it "returns nil for undefined method calls" do
|
17
|
-
subject.enhance_your_calm.
|
17
|
+
expect(subject.enhance_your_calm).to eq(nil)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
data/spec/lib/sprig_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Sprig do
|
3
|
+
RSpec.describe Sprig do
|
4
4
|
let(:configuration) { double('Configuration') }
|
5
5
|
|
6
6
|
before do
|
7
|
-
Sprig::Configuration.
|
7
|
+
allow(Sprig::Configuration).to receive(:new).and_return(configuration)
|
8
8
|
end
|
9
9
|
|
10
10
|
describe '.adapter' do
|
@@ -61,7 +61,7 @@ describe Sprig do
|
|
61
61
|
describe ".configuration" do
|
62
62
|
context "when there is not yet a Configuration instance" do
|
63
63
|
it "returns a new Configuration instance" do
|
64
|
-
described_class.configuration.
|
64
|
+
expect(described_class.configuration).to eq(configuration)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -72,9 +72,9 @@ describe Sprig do
|
|
72
72
|
|
73
73
|
it "returns the existing Configuration instance" do
|
74
74
|
new_configuration = double('Configuration')
|
75
|
-
Sprig::Configuration.
|
75
|
+
allow(Sprig::Configuration).to receive(:new).and_return(new_configuration)
|
76
76
|
|
77
|
-
described_class.configuration.
|
77
|
+
expect(described_class.configuration).to eq(configuration)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -87,16 +87,16 @@ describe Sprig do
|
|
87
87
|
it "clears the existing configuration" do
|
88
88
|
described_class.reset_configuration
|
89
89
|
new_configuration = double('Configuration')
|
90
|
-
Sprig::Configuration.
|
90
|
+
allow(Sprig::Configuration).to receive(:new).and_return(new_configuration)
|
91
91
|
|
92
|
-
described_class.configuration.
|
92
|
+
expect(described_class.configuration).to eq(new_configuration)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
describe ".configure" do
|
97
97
|
it "yields the configuration" do
|
98
98
|
described_class.configure do |config|
|
99
|
-
config.
|
99
|
+
expect(config).to eq(configuration)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -21,6 +21,14 @@ RSpec.configure do |c|
|
|
21
21
|
c.include ColoredText
|
22
22
|
c.include LoggerMock
|
23
23
|
|
24
|
+
c.disable_monkey_patching!
|
25
|
+
|
26
|
+
c.order = :random
|
27
|
+
|
28
|
+
c.mock_with :rspec do |mocks|
|
29
|
+
mocks.verify_partial_doubles = true
|
30
|
+
end
|
31
|
+
|
24
32
|
c.after(:each) do
|
25
33
|
Sprig.reset_configuration
|
26
34
|
end
|
@@ -56,29 +64,37 @@ require "adapters/#{Sprig.adapter}.rb"
|
|
56
64
|
#
|
57
65
|
# Setup fake `Rails.root`
|
58
66
|
def stub_rails_root(path='./spec/fixtures')
|
59
|
-
Rails.
|
67
|
+
allow(Rails).to receive(:root).and_return(Pathname.new(path))
|
60
68
|
end
|
61
69
|
|
62
70
|
# Setup fake `Rails.env`
|
63
71
|
def stub_rails_env(env='development')
|
64
|
-
Rails.
|
72
|
+
allow(Rails).to receive(:env).and_return(env)
|
65
73
|
end
|
66
74
|
|
67
75
|
# Copy and Remove Seed files around a spec
|
68
|
-
def load_seeds(*files)
|
76
|
+
def load_seeds(*files, &block)
|
69
77
|
env = Rails.env
|
78
|
+
prepare_seeds(env, *files, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Copy and Remove shared seed files around a spec
|
82
|
+
def load_shared_seeds(*files, &block)
|
83
|
+
prepare_seeds('shared', *files, &block)
|
84
|
+
end
|
70
85
|
|
71
|
-
|
86
|
+
def prepare_seeds(directory, *files, &block)
|
87
|
+
`cp -R ./spec/fixtures/seeds/#{directory}/files ./spec/fixtures/db/seeds/#{directory}`
|
72
88
|
|
73
89
|
files.each do |file|
|
74
|
-
`cp ./spec/fixtures/seeds/#{
|
90
|
+
`cp ./spec/fixtures/seeds/#{directory}/#{file} ./spec/fixtures/db/seeds/#{directory}`
|
75
91
|
end
|
76
92
|
|
77
|
-
|
93
|
+
block.call
|
78
94
|
|
79
|
-
`rm -R ./spec/fixtures/db/seeds/#{
|
95
|
+
`rm -R ./spec/fixtures/db/seeds/#{directory}/files`
|
80
96
|
|
81
97
|
files.each do |file|
|
82
|
-
`rm ./spec/fixtures/db/seeds/#{
|
98
|
+
`rm ./spec/fixtures/db/seeds/#{directory}/#{file}`
|
83
99
|
end
|
84
100
|
end
|
@@ -0,0 +1,467 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
RSpec.describe "Seeding an application with shared seeds" do
|
5
|
+
let(:missing_record_error) do
|
6
|
+
if defined?(ActiveRecord) && Post < ActiveRecord::Base
|
7
|
+
ActiveRecord::RecordNotFound
|
8
|
+
elsif defined?(Mongoid) && Post < Mongoid::Document
|
9
|
+
Mongoid::Errors::DocumentNotFound
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
stub_rails_root
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with a yaml file" do
|
18
|
+
around do |example|
|
19
|
+
load_shared_seeds('posts.yml', &example)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "seeds the db" do
|
23
|
+
sprig_shared [Post]
|
24
|
+
|
25
|
+
expect(Post.count).to eq(1)
|
26
|
+
expect(Post.pluck(:title)).to eq(['Yaml title'])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with a csv file" do
|
31
|
+
around do |example|
|
32
|
+
load_shared_seeds('posts.csv', &example)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "seeds the db" do
|
36
|
+
sprig_shared [Post]
|
37
|
+
|
38
|
+
expect(Post.count).to eq(1)
|
39
|
+
expect(Post.pluck(:title)).to eq(['Csv title'])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with a json file" do
|
44
|
+
around do |example|
|
45
|
+
load_shared_seeds('posts.json', &example)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "seeds the db" do
|
49
|
+
sprig_shared [Post]
|
50
|
+
|
51
|
+
expect(Post.count).to eq(1)
|
52
|
+
expect(Post.pluck(:title)).to eq(['Json title'])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with a partially-dynamic value" do
|
57
|
+
around do |example|
|
58
|
+
load_shared_seeds('posts_partially_dynamic_value.yml', &example)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "seeds the db with the full value" do
|
62
|
+
sprig_shared [
|
63
|
+
{
|
64
|
+
:class => Post,
|
65
|
+
:source => open('spec/fixtures/seeds/shared/posts_partially_dynamic_value.yml')
|
66
|
+
}
|
67
|
+
]
|
68
|
+
|
69
|
+
expect(Post.count).to eq(1)
|
70
|
+
expect(Post.pluck(:title)).to eq(['Partially Dynamic Title'])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "with a symlinked file" do
|
75
|
+
around do |example|
|
76
|
+
`ln -s ./spec/fixtures/seeds/shared/posts.yml ./spec/fixtures/db/seeds/shared/`
|
77
|
+
example.call
|
78
|
+
`rm ./spec/fixtures/db/seeds/shared/posts.yml`
|
79
|
+
end
|
80
|
+
|
81
|
+
it "seeds the db" do
|
82
|
+
sprig_shared [Post]
|
83
|
+
|
84
|
+
expect(Post.count).to eq(1)
|
85
|
+
expect(Post.pluck(:title)).to eq(['Yaml title'])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with a google spreadsheet" do
|
90
|
+
it "seeds the db", :vcr => { :cassette_name => 'google_spreadsheet_json_posts' } do
|
91
|
+
sprig_shared [
|
92
|
+
{
|
93
|
+
:class => Post,
|
94
|
+
:parser => Sprig::Parser::GoogleSpreadsheetJson,
|
95
|
+
:source => open('https://spreadsheets.google.com/feeds/list/0AjVLPMnHm86rdDVHQ2dCUS03RTN5ZUtVNzVOYVBwT0E/1/public/values?alt=json'),
|
96
|
+
}
|
97
|
+
]
|
98
|
+
|
99
|
+
expect(Post.count).to eq(1)
|
100
|
+
expect(Post.pluck(:title)).to eq(['Google spreadsheet json title'])
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with an invalid custom parser" do
|
105
|
+
around do |example|
|
106
|
+
load_shared_seeds('posts.yml', &example)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "fails with an argument error" do
|
110
|
+
expect {
|
111
|
+
sprig_shared [
|
112
|
+
{
|
113
|
+
:class => Post,
|
114
|
+
:source => open('spec/fixtures/seeds/shared/posts.yml'),
|
115
|
+
:parser => Object # Not a valid parser
|
116
|
+
}
|
117
|
+
]
|
118
|
+
}.to raise_error(ArgumentError, 'Parsers must define #parse.')
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "with a custom source" do
|
123
|
+
around do |example|
|
124
|
+
load_shared_seeds('legacy_posts.yml', &example)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "seeds" do
|
128
|
+
sprig_shared [
|
129
|
+
{
|
130
|
+
:class => Post,
|
131
|
+
:source => open('spec/fixtures/seeds/shared/legacy_posts.yml')
|
132
|
+
}
|
133
|
+
]
|
134
|
+
|
135
|
+
expect(Post.count).to eq(1)
|
136
|
+
expect(Post.pluck(:title)).to eq(['Legacy yaml title'])
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with a custom source that cannot be parsed by native parsers" do
|
141
|
+
around do |example|
|
142
|
+
load_shared_seeds('posts.md', &example)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "fails with an unparsable file error" do
|
146
|
+
expect {
|
147
|
+
sprig_shared [
|
148
|
+
{
|
149
|
+
:class => Post,
|
150
|
+
:source => open('spec/fixtures/seeds/shared/posts.md')
|
151
|
+
}
|
152
|
+
]
|
153
|
+
}.to raise_error(Sprig::Source::ParserDeterminer::UnparsableFileError)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "with an invalid custom source" do
|
158
|
+
it "fails with an argument error" do
|
159
|
+
expect {
|
160
|
+
sprig_shared [ { :class => Post, :source => 42 } ]
|
161
|
+
}.to raise_error(ArgumentError, 'Data sources must act like an IO.')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "with multiple file relationships" do
|
166
|
+
around do |example|
|
167
|
+
load_shared_seeds('posts.yml', 'comments.yml', &example)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "seeds the db" do
|
171
|
+
sprig_shared [Post, Comment]
|
172
|
+
|
173
|
+
expect(Post.count).to eq(1)
|
174
|
+
expect(Comment.count).to eq(1)
|
175
|
+
expect(Comment.first.post).to eq(Post.first)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "with missing seed files" do
|
180
|
+
it "raises a missing file error" do
|
181
|
+
expect {
|
182
|
+
sprig_shared [Post]
|
183
|
+
}.to raise_error(Sprig::Source::SourceDeterminer::FileNotFoundError)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with a relationship to an undefined record" do
|
188
|
+
around do |example|
|
189
|
+
load_shared_seeds('posts.yml', 'posts_missing_dependency.yml', &example)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "raises a helpful error message" do
|
193
|
+
expect {
|
194
|
+
sprig_shared [
|
195
|
+
{
|
196
|
+
:class => Post,
|
197
|
+
:source => open('spec/fixtures/seeds/shared/posts_missing_dependency.yml')
|
198
|
+
}
|
199
|
+
]
|
200
|
+
}.to raise_error(
|
201
|
+
Sprig::DependencySorter::MissingDependencyError,
|
202
|
+
"Undefined reference to 'sprig_record(Comment, 42)'"
|
203
|
+
)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "with a relationship to a record that didn't save" do
|
208
|
+
around do |example|
|
209
|
+
load_shared_seeds('invalid_users.yml', 'posts_missing_record.yml', &example)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "does not error, but carries on with the seeding" do
|
213
|
+
expect {
|
214
|
+
sprig_shared [
|
215
|
+
{
|
216
|
+
:class => Post,
|
217
|
+
:source => open('spec/fixtures/seeds/shared/posts_missing_record.yml')
|
218
|
+
},
|
219
|
+
{
|
220
|
+
:class => User,
|
221
|
+
:source => open('spec/fixtures/seeds/shared/invalid_users.yml')
|
222
|
+
}
|
223
|
+
]
|
224
|
+
}.to_not raise_error
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "with multiple files for a class" do
|
229
|
+
around do |example|
|
230
|
+
load_shared_seeds('posts.yml', 'legacy_posts.yml', &example)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "seeds the db" do
|
234
|
+
sprig_shared [
|
235
|
+
Post,
|
236
|
+
{
|
237
|
+
:class => Post,
|
238
|
+
:source => open('spec/fixtures/seeds/shared/legacy_posts.yml')
|
239
|
+
}
|
240
|
+
]
|
241
|
+
|
242
|
+
expect(Post.count).to eq(2)
|
243
|
+
expect(Post.pluck(:title)).to eq(['Yaml title', 'Legacy yaml title'])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context "with files defined as attributes" do
|
248
|
+
around do |example|
|
249
|
+
load_shared_seeds('posts_with_files.yml', &example)
|
250
|
+
end
|
251
|
+
|
252
|
+
it "seeds the db" do
|
253
|
+
sprig_shared [
|
254
|
+
{
|
255
|
+
:class => Post,
|
256
|
+
:source => open('spec/fixtures/seeds/shared/posts_with_files.yml')
|
257
|
+
}
|
258
|
+
]
|
259
|
+
|
260
|
+
expect(Post.count).to eq(1)
|
261
|
+
expect(Post.pluck(:photo)).to eq(['cat.png'])
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context "with has_and_belongs_to_many relationships" do
|
266
|
+
around do |example|
|
267
|
+
load_shared_seeds('posts_with_habtm.yml', 'tags.yml', &example)
|
268
|
+
end
|
269
|
+
|
270
|
+
it "saves the habtm relationships" do
|
271
|
+
sprig_shared [
|
272
|
+
Tag,
|
273
|
+
{
|
274
|
+
:class => Post,
|
275
|
+
:source => open('spec/fixtures/seeds/shared/posts_with_habtm.yml')
|
276
|
+
}
|
277
|
+
]
|
278
|
+
|
279
|
+
expect(Post.first.tags.map(&:name)).to eq(['Botany', 'Biology'])
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context "with cyclic dependencies" do
|
284
|
+
around do |example|
|
285
|
+
load_shared_seeds('comments.yml', 'posts_with_cyclic_dependencies.yml', &example)
|
286
|
+
end
|
287
|
+
|
288
|
+
it "raises an cyclic dependency error" do
|
289
|
+
expect {
|
290
|
+
sprig_shared [
|
291
|
+
{
|
292
|
+
:class => Post,
|
293
|
+
:source => open('spec/fixtures/seeds/shared/posts_with_cyclic_dependencies.yml')
|
294
|
+
},
|
295
|
+
Comment
|
296
|
+
]
|
297
|
+
}.to raise_error(Sprig::DependencySorter::CircularDependencyError)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
context "with a malformed directive" do
|
302
|
+
let(:expected_error_message) { "Sprig::Directive must be instantiated with a(n) #{Sprig.adapter_model_class} class or a Hash with :class defined" }
|
303
|
+
|
304
|
+
context "including a class that is not a subclass of AR" do
|
305
|
+
it "raises an argument error" do
|
306
|
+
expect {
|
307
|
+
sprig_shared [
|
308
|
+
Object
|
309
|
+
]
|
310
|
+
}.to raise_error(ArgumentError, expected_error_message)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "including a non-class, non-hash" do
|
315
|
+
it "raises an argument error" do
|
316
|
+
expect {
|
317
|
+
sprig_shared [
|
318
|
+
42
|
319
|
+
]
|
320
|
+
}.to raise_error(ArgumentError, expected_error_message)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
context "with custom seed options" do
|
327
|
+
context "using delete_existing_by" do
|
328
|
+
around do |example|
|
329
|
+
load_shared_seeds('posts_delete_existing_by.yml', &example)
|
330
|
+
end
|
331
|
+
|
332
|
+
context "with an existing record" do
|
333
|
+
let!(:existing_match) do
|
334
|
+
Post.create(
|
335
|
+
:title => "Such Title",
|
336
|
+
:content => "Old Content")
|
337
|
+
end
|
338
|
+
|
339
|
+
let!(:existing_nonmatch) do
|
340
|
+
Post.create(
|
341
|
+
:title => "Wow Title",
|
342
|
+
:content => "Much Content")
|
343
|
+
end
|
344
|
+
|
345
|
+
it "replaces only the matching existing record" do
|
346
|
+
sprig_shared [
|
347
|
+
{
|
348
|
+
:class => Post,
|
349
|
+
:source => open("spec/fixtures/seeds/shared/posts_delete_existing_by.yml")
|
350
|
+
}
|
351
|
+
]
|
352
|
+
|
353
|
+
expect(Post.count).to eq(2)
|
354
|
+
|
355
|
+
expect {
|
356
|
+
existing_match.reload
|
357
|
+
}.to raise_error(missing_record_error)
|
358
|
+
|
359
|
+
expect {
|
360
|
+
existing_nonmatch.reload
|
361
|
+
}.to_not raise_error
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
context "using find_existing_by" do
|
367
|
+
context "with a missing attribute" do
|
368
|
+
around do |example|
|
369
|
+
load_shared_seeds('posts_find_existing_by_missing.yml', &example)
|
370
|
+
end
|
371
|
+
|
372
|
+
it "raises a missing attribute error" do
|
373
|
+
expect {
|
374
|
+
sprig_shared [
|
375
|
+
{
|
376
|
+
:class => Post,
|
377
|
+
:source => open("spec/fixtures/seeds/shared/posts_find_existing_by_missing.yml")
|
378
|
+
}
|
379
|
+
]
|
380
|
+
}.to raise_error(Sprig::Seed::AttributeCollection::AttributeNotFoundError, "Attribute 'unicorn' is not present.")
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
context "with a single attribute" do
|
385
|
+
around do |example|
|
386
|
+
load_shared_seeds('posts.yml', 'posts_find_existing_by_single.yml', &example)
|
387
|
+
end
|
388
|
+
|
389
|
+
context "with an existing record" do
|
390
|
+
let!(:existing) do
|
391
|
+
Post.create(
|
392
|
+
:title => "Existing title",
|
393
|
+
:content => "Existing content")
|
394
|
+
end
|
395
|
+
|
396
|
+
it "updates the existing record" do
|
397
|
+
sprig_shared [
|
398
|
+
{
|
399
|
+
:class => Post,
|
400
|
+
:source => open("spec/fixtures/seeds/shared/posts_find_existing_by_single.yml")
|
401
|
+
}
|
402
|
+
]
|
403
|
+
|
404
|
+
expect(Post.count).to eq(1)
|
405
|
+
expect(existing.reload.content).to eq("Updated content")
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
context "with multiple attributes" do
|
411
|
+
around do |example|
|
412
|
+
load_shared_seeds('posts.yml', 'posts_find_existing_by_multiple.yml', &example)
|
413
|
+
end
|
414
|
+
|
415
|
+
context "with an existing record" do
|
416
|
+
let!(:existing) do
|
417
|
+
Post.create(
|
418
|
+
:title => "Existing title",
|
419
|
+
:content => "Existing content",
|
420
|
+
:published => false
|
421
|
+
)
|
422
|
+
end
|
423
|
+
|
424
|
+
it "updates the existing record" do
|
425
|
+
sprig_shared [
|
426
|
+
{
|
427
|
+
:class => Post,
|
428
|
+
:source => open("spec/fixtures/seeds/shared/posts_find_existing_by_multiple.yml")
|
429
|
+
}
|
430
|
+
]
|
431
|
+
|
432
|
+
expect(Post.count).to eq(1)
|
433
|
+
expect(existing.reload.published).to eq(true)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
context "defined within the directive" do
|
440
|
+
let!(:existing) do
|
441
|
+
Post.create(
|
442
|
+
:title => "Yaml title",
|
443
|
+
:content => "Existing content")
|
444
|
+
end
|
445
|
+
|
446
|
+
around do |example|
|
447
|
+
load_shared_seeds('posts.yml', &example)
|
448
|
+
end
|
449
|
+
|
450
|
+
it "respects the directive option" do
|
451
|
+
sprig_shared [
|
452
|
+
{
|
453
|
+
:class => Post,
|
454
|
+
:source => open("spec/fixtures/seeds/shared/posts.yml"),
|
455
|
+
:delete_existing_by => :title
|
456
|
+
}
|
457
|
+
]
|
458
|
+
|
459
|
+
expect(Post.count).to eq(1)
|
460
|
+
|
461
|
+
expect {
|
462
|
+
existing.reload
|
463
|
+
}.to raise_error(missing_record_error)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|