fedora-migrate 0.3.0 → 0.4.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +128 -0
  3. data/.rubocop_todo.yml +9 -0
  4. data/.travis.yml +3 -2
  5. data/Gemfile +2 -0
  6. data/fedora-migrate.gemspec +1 -0
  7. data/lib/fedora-migrate.rb +3 -5
  8. data/lib/fedora_migrate/content_mover.rb +7 -11
  9. data/lib/fedora_migrate/datastream_mover.rb +21 -24
  10. data/lib/fedora_migrate/datastream_verification.rb +15 -17
  11. data/lib/fedora_migrate/dates_mover.rb +0 -2
  12. data/lib/fedora_migrate/file_configurator.rb +3 -5
  13. data/lib/fedora_migrate/hooks.rb +0 -2
  14. data/lib/fedora_migrate/logger.rb +8 -11
  15. data/lib/fedora_migrate/migration_options.rb +6 -7
  16. data/lib/fedora_migrate/migration_report.rb +18 -22
  17. data/lib/fedora_migrate/mover.rb +4 -6
  18. data/lib/fedora_migrate/object_mover.rb +28 -34
  19. data/lib/fedora_migrate/permissions.rb +8 -10
  20. data/lib/fedora_migrate/permissions_mover.rb +7 -11
  21. data/lib/fedora_migrate/rdf_datastream_mover.rb +1 -2
  22. data/lib/fedora_migrate/rels_ext_datastream_mover.rb +29 -31
  23. data/lib/fedora_migrate/repository_migrator.rb +40 -43
  24. data/lib/fedora_migrate/rights_metadata.rb +109 -114
  25. data/lib/fedora_migrate/rubydora_connection.rb +4 -5
  26. data/lib/fedora_migrate/target_constructor.rb +19 -22
  27. data/lib/fedora_migrate/version.rb +1 -1
  28. data/spec/integration/content_versions_spec.rb +12 -14
  29. data/spec/integration/custom_target_spec.rb +44 -0
  30. data/spec/integration/fedora3_interface_spec.rb +7 -11
  31. data/spec/integration/missing_relationships_spec.rb +8 -10
  32. data/spec/integration/object_migration_spec.rb +20 -31
  33. data/spec/integration/permission_migration_spec.rb +4 -6
  34. data/spec/integration/rdf_migration_spec.rb +3 -6
  35. data/spec/integration/relationship_migration_spec.rb +6 -7
  36. data/spec/integration/repository_migration_spec.rb +14 -19
  37. data/spec/integration/versions_spec.rb +6 -8
  38. data/spec/spec_helper.rb +3 -3
  39. data/spec/support/example_model.rb +23 -25
  40. data/spec/unit/content_mover_spec.rb +21 -23
  41. data/spec/unit/datastream_mover_spec.rb +10 -14
  42. data/spec/unit/datastream_verification_spec.rb +7 -9
  43. data/spec/unit/dates_mover_spec.rb +3 -4
  44. data/spec/unit/fedora_migrate_spec.rb +2 -6
  45. data/spec/unit/file_configurator_spec.rb +4 -8
  46. data/spec/unit/migration_options_spec.rb +1 -3
  47. data/spec/unit/migration_report_spec.rb +5 -6
  48. data/spec/unit/mover_spec.rb +10 -12
  49. data/spec/unit/object_mover_spec.rb +9 -16
  50. data/spec/unit/permissions_mover_spec.rb +8 -11
  51. data/spec/unit/rels_ext_datastream_mover_spec.rb +4 -6
  52. data/spec/unit/repository_migrator_spec.rb +12 -14
  53. data/spec/unit/rubydora_connection_spec.rb +3 -5
  54. data/spec/unit/target_constructor_spec.rb +10 -16
  55. data/tasks/dev.rake +9 -1
  56. metadata +21 -3
@@ -1,14 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::Mover do
4
-
5
4
  it { is_expected.to respond_to :source }
6
5
  it { is_expected.to respond_to :target }
7
6
  it { is_expected.to respond_to :options }
8
7
 
9
8
  describe "#new" do
10
9
  context "with two arguments" do
11
- subject { FedoraMigrate::Mover.new("foo", "bar") }
10
+ subject { described_class.new("foo", "bar") }
12
11
  specify "has a source" do
13
12
  expect(subject.source).to eql("foo")
14
13
  end
@@ -18,14 +17,14 @@ describe FedoraMigrate::Mover do
18
17
  end
19
18
 
20
19
  context "with options" do
21
- subject { FedoraMigrate::Mover.new("foo", "bar", {option: "optional"}) }
20
+ subject { described_class.new("foo", "bar", option: "optional") }
22
21
  specify "it has an option" do
23
- expect(subject.options).to eql({option: "optional"})
22
+ expect(subject.options).to eql(option: "optional")
24
23
  end
25
24
  end
26
25
 
27
26
  context "with optional arguments" do
28
- subject { FedoraMigrate::Mover.new("foo") }
27
+ subject { described_class.new("foo") }
29
28
  specify "has a source" do
30
29
  expect(subject.source).to eql("foo")
31
30
  end
@@ -39,35 +38,34 @@ describe FedoraMigrate::Mover do
39
38
  context "with a Rubydora object" do
40
39
  let(:id) { "rb68xc11m" }
41
40
  let(:object) { FedoraMigrate.source.connection.find("sufia:#{id}") }
42
- subject { FedoraMigrate::Mover.id_component(object) }
41
+ subject { described_class.id_component(object) }
43
42
  it { is_expected.to eql(id) }
44
43
  end
45
44
  context "with a URI" do
46
45
  let(:object) { RDF::URI.new("foo:bar") }
47
- subject { FedoraMigrate::Mover.id_component(object) }
46
+ subject { described_class.id_component(object) }
48
47
  it { is_expected.to eql("bar") }
49
48
  end
50
49
  context "with a string" do
51
50
  let(:object) { "foo:bar" }
52
- subject { FedoraMigrate::Mover.id_component(object) }
51
+ subject { described_class.id_component(object) }
53
52
  it { is_expected.to eql("bar") }
54
53
  end
55
54
  end
56
55
 
57
56
  describe "#id_component" do
58
57
  context "with a source" do
59
- subject { FedoraMigrate::Mover.new("source:pid").id_component }
58
+ subject { described_class.new("source:pid").id_component }
60
59
  it { is_expected.to eql("pid") }
61
60
  end
62
61
  context "object, but no source" do
63
- subject { FedoraMigrate::Mover.new.id_component("source:pid") }
62
+ subject { described_class.new.id_component("source:pid") }
64
63
  it { is_expected.to eql("pid") }
65
64
  end
66
65
  context "neither object, nor source" do
67
66
  specify "raises an error" do
68
- expect { FedoraMigrate::Mover.new.id_component }.to raise_error(FedoraMigrate::Errors::MigrationError)
67
+ expect { described_class.new.id_component }.to raise_error(FedoraMigrate::Errors::MigrationError)
69
68
  end
70
69
  end
71
70
  end
72
-
73
71
  end
@@ -1,10 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::ObjectMover do
4
-
5
- before do
6
- allow_any_instance_of(FedoraMigrate::ObjectMover).to receive(:create_target_model).and_return("foo")
7
- end
4
+ let(:mock_target) { double("Target", id: "1234") }
5
+ before { allow_any_instance_of(described_class).to receive(:target).and_return(mock_target) }
8
6
 
9
7
  describe "#new" do
10
8
  it { is_expected.to respond_to :source }
@@ -13,24 +11,19 @@ describe FedoraMigrate::ObjectMover do
13
11
  end
14
12
 
15
13
  describe "#prepare_target" do
16
- subject do
17
- FedoraMigrate::ObjectMover.new("source", double("Target", id: nil)).prepare_target
18
- end
19
- it "should call the before hook and save the target" do
20
- expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:before_object_migration)
14
+ subject { described_class.new("source", double("Target", id: nil)).prepare_target }
15
+ it "calls the before hook and save the target" do
16
+ expect_any_instance_of(described_class).to receive(:before_object_migration)
21
17
  expect(subject).to be nil
22
18
  end
23
19
  end
24
20
 
25
21
  describe "#complete_target" do
26
- subject do
27
- FedoraMigrate::ObjectMover.new("source", double("Target", id: nil)).complete_target
28
- end
29
- it "should call the after hook and save the target" do
30
- expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:after_object_migration)
31
- expect_any_instance_of(FedoraMigrate::ObjectMover).to receive(:save).and_return(true)
22
+ subject { described_class.new("source", double("Target", id: nil)).complete_target }
23
+ it "calls the after hook and save the target" do
24
+ expect_any_instance_of(described_class).to receive(:after_object_migration)
25
+ expect_any_instance_of(described_class).to receive(:save).and_return(true)
32
26
  expect(subject).to be true
33
27
  end
34
28
  end
35
-
36
29
  end
@@ -1,12 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::PermissionsMover do
4
-
5
4
  it { is_expected.to respond_to :rightsMetadata }
6
5
 
7
6
  describe "#post_initialize" do
8
7
  specify "a target is required" do
9
- expect{subject.new}.to raise_error(StandardError)
8
+ expect { subject.new }.to raise_error(StandardError)
10
9
  end
11
10
  end
12
11
 
@@ -14,12 +13,12 @@ describe FedoraMigrate::PermissionsMover do
14
13
  let(:target) { instance_double("Target") }
15
14
  let(:source) { instance_double("Source", content: "<rightsMetadata></rightsMetadata>") }
16
15
 
17
- subject { FedoraMigrate::PermissionsMover.new(source, target) }
18
-
19
- it "should be FedoraMigrate::RightsMetadata datastream" do
16
+ subject { described_class.new(source, target) }
17
+
18
+ it "is FedoraMigrate::RightsMetadata datastream" do
20
19
  expect(subject.rightsMetadata).to be_kind_of FedoraMigrate::RightsMetadata
21
20
  end
22
-
21
+
23
22
  context "with a user" do
24
23
  specify "reading" do
25
24
  expect(subject.read_users).to be_empty
@@ -30,7 +29,7 @@ describe FedoraMigrate::PermissionsMover do
30
29
  end
31
30
 
32
31
  specify "discovering" do
33
- expect(subject.discover_users).to be_empty
32
+ expect(subject.discover_users).to be_empty
34
33
  end
35
34
  end
36
35
 
@@ -44,10 +43,8 @@ describe FedoraMigrate::PermissionsMover do
44
43
  end
45
44
 
46
45
  specify "discovering" do
47
- expect(subject.discover_groups).to be_empty
46
+ expect(subject.discover_groups).to be_empty
48
47
  end
49
- end
50
-
48
+ end
51
49
  end
52
-
53
50
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::RelsExtDatastreamMover do
4
-
5
4
  let(:file_id) { "rb68xc11m" }
6
5
  let(:batch_id) { "rb68xc09k" }
7
6
  let(:source) { FedoraMigrate.source.connection.find("sufia:#{file_id}") }
@@ -15,18 +14,18 @@ describe FedoraMigrate::RelsExtDatastreamMover do
15
14
 
16
15
  describe "#initialize" do
17
16
  context "without a target" do
18
- subject { FedoraMigrate::RelsExtDatastreamMover.new(source).target }
17
+ subject { described_class.new(source).target }
19
18
  it { is_expected.to be_kind_of(ActiveFedora::Base) }
20
19
  end
21
20
  context "with a supplied target" do
22
- subject { FedoraMigrate::RelsExtDatastreamMover.new(source, "a target").target }
21
+ subject { described_class.new(source, "a target").target }
23
22
  it { is_expected.to eql "a target" }
24
23
  end
25
24
  end
26
25
 
27
26
  describe "#migrate" do
28
27
  context "with an existing target" do
29
- before { FedoraMigrate::RelsExtDatastreamMover.new(source).migrate }
28
+ before { described_class.new(source).migrate }
30
29
  subject { ActiveFedora::Base.find(file_id).ldp_source.graph.query([nil, ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, nil]) }
31
30
  it "migrates RDF relationships" do
32
31
  expect(subject.first.subject).to eq RDF::URI.new("http://localhost:8983/fedora/rest/test/#{file_id}")
@@ -39,8 +38,7 @@ describe FedoraMigrate::RelsExtDatastreamMover do
39
38
  context "with a non-existent target" do
40
39
  let(:error_message) { "Target object was not found in Fedora 4. Did you migrate it?" }
41
40
  it "raises an error" do
42
- expect { FedoraMigrate::RelsExtDatastreamMover.new(source) }.to raise_error(FedoraMigrate::Errors::MigrationError, error_message)
41
+ expect { described_class.new(source) }.to raise_error(FedoraMigrate::Errors::MigrationError, error_message)
43
42
  end
44
43
  end
45
-
46
44
  end
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::RepositoryMigrator do
4
-
5
4
  let(:namespace) { "sufia" }
6
5
 
7
6
  it { is_expected.to respond_to(:source_objects) }
@@ -13,7 +12,7 @@ describe FedoraMigrate::RepositoryMigrator do
13
12
  let(:failing_report) { { "sufia:rb68xc089" => FedoraMigrate::RepositoryMigrator::SingleObjectReport.new(false, "objects", "relationships") } }
14
13
  before { allow_any_instance_of(FedoraMigrate::MigrationReport).to receive(:results).and_return(failing_report) }
15
14
  subject do
16
- migrator = FedoraMigrate::RepositoryMigrator.new(namespace)
15
+ migrator = described_class.new(namespace)
17
16
  migrator.failures
18
17
  end
19
18
  it { is_expected.to be 1 }
@@ -22,7 +21,7 @@ describe FedoraMigrate::RepositoryMigrator do
22
21
  let(:passing_report) { { "sufia:rb68xc089" => FedoraMigrate::RepositoryMigrator::SingleObjectReport.new(true, "objects", "relationships") } }
23
22
  before { allow_any_instance_of(FedoraMigrate::MigrationReport).to receive(:results).and_return(passing_report) }
24
23
  subject do
25
- migrator = FedoraMigrate::RepositoryMigrator.new(namespace)
24
+ migrator = described_class.new(namespace)
26
25
  migrator.failures
27
26
  end
28
27
  it { is_expected.to eql 0 }
@@ -35,15 +34,15 @@ describe FedoraMigrate::RepositoryMigrator do
35
34
  allow(subject).to receive(:failures).and_return(1)
36
35
  end
37
36
  context "without an explicit force" do
38
- subject { FedoraMigrate::RepositoryMigrator.new(namespace) }
39
- it "should not migrate relationships" do
37
+ subject { described_class.new(namespace) }
38
+ it "does not migrate relationships" do
40
39
  expect(subject.migrate_relationships).to eql("Relationship migration halted because 1 objects didn't migrate successfully.")
41
40
  end
42
41
  end
43
42
  context "with an explicit force" do
44
- subject { FedoraMigrate::RepositoryMigrator.new(namespace, { force: true }) }
45
- it "should migrate relationships" do
46
- expect(subject.migrate_relationships).to_not be_nil
43
+ subject { described_class.new(namespace, force: true) }
44
+ it "migrates relationships" do
45
+ expect(subject.migrate_relationships).not_to be_nil
47
46
  end
48
47
  end
49
48
  end
@@ -57,21 +56,20 @@ describe FedoraMigrate::RepositoryMigrator do
57
56
  end
58
57
 
59
58
  context "with a given namespace" do
60
- subject { FedoraMigrate::RepositoryMigrator.new(namespace) }
59
+ subject { described_class.new(namespace) }
61
60
  describe "#namespace" do
62
61
  specify "is the one provided" do
63
62
  expect(subject.namespace).to eql(namespace)
64
63
  end
65
64
  end
66
65
  describe "#source_objects" do
67
- it "should reuturn an array of all digital objects from Rubydora" do
68
- expect(subject.source_objects.collect { |o| o.pid }).to include("sufia:rb68xc089", "sufia:rb68xc11m")
66
+ it "reuturns an array of all digital objects from Rubydora" do
67
+ expect(subject.source_objects.collect(&:pid)).to include("sufia:rb68xc089", "sufia:rb68xc11m")
69
68
  end
70
- it "should exclude fedora-system objects" do
71
- expect(subject.source_objects).to_not include("fedora-system:ContentModel-3.0")
69
+ it "excludes fedora-system objects" do
70
+ expect(subject.source_objects).not_to include("fedora-system:ContentModel-3.0")
72
71
  expect(subject.source_objects.count).to eql 9
73
72
  end
74
73
  end
75
74
  end
76
-
77
75
  end
@@ -2,21 +2,20 @@ require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::RubydoraConnection do
4
4
  describe 'initialize' do
5
-
6
- let (:fedora_url) { "http://my.fedora3.instance" }
5
+ let(:fedora_url) { "http://my.fedora3.instance" }
7
6
 
8
7
  before do
9
8
  allow_any_instance_of(Rubydora::Repository).to receive(:check_repository_version!).and_return("3.8")
10
9
  end
11
10
 
12
11
  subject {
13
- FedoraMigrate::RubydoraConnection.new timeout: 3600, validateChecksum: true, url: fedora_url
12
+ described_class.new timeout: 3600, validateChecksum: true, url: fedora_url
14
13
  }
15
14
 
16
15
  specify "a timeout" do
17
16
  expect(subject.connection.client.options[:timeout]).to eql(3600)
18
17
  end
19
-
18
+
20
19
  specify "validate a checksum" do
21
20
  expect(subject.connection.config[:validateChecksum]).to be true
22
21
  end
@@ -24,6 +23,5 @@ describe FedoraMigrate::RubydoraConnection do
24
23
  specify "a Fedora3 url" do
25
24
  expect(subject.connection.client.url).to eql fedora_url
26
25
  end
27
-
28
26
  end
29
27
  end
@@ -1,34 +1,28 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe FedoraMigrate::TargetConstructor do
4
-
4
+ let(:mock_source) { instance_double("Source", models: list, pid: "pid:1234") }
5
5
  context "with one qualified model" do
6
6
  let(:list) { ["info:fedora/fedora-system:FedoraObject-3.0", "info:fedora/afmodel:String"] }
7
- subject { FedoraMigrate::TargetConstructor.new(list).build }
8
- it "should choose the one that is valid" do
9
- expect(subject.target).to eql String
10
- end
7
+ subject { described_class.new(mock_source) }
8
+ its(:target) { is_expected.to eql String }
11
9
  end
12
10
 
13
11
  context "with multiple qualified models" do
14
12
  let(:list) { ["info:fedora/fedora-system:FedoraObject-3.0", "info:fedora/afmodel:Array", "info:fedora/afmodel:String"] }
15
- subject { FedoraMigrate::TargetConstructor.new(list).build }
16
- it "should choose the first one that is valid" do
17
- expect(subject.target).to eql Array
18
- end
13
+ subject { described_class.new(mock_source) }
14
+ its(:target) { is_expected.to eql Array }
19
15
  end
20
16
 
21
17
  context "with a single qualified model" do
22
- subject { FedoraMigrate::TargetConstructor.new("info:fedora/afmodel:Array").build }
23
- it "should be valid" do
24
- expect(subject.target).to eql Array
25
- end
18
+ let(:list) { "info:fedora/afmodel:Array" }
19
+ subject { described_class.new(mock_source) }
20
+ its(:target) { is_expected.to eql Array }
26
21
  end
27
22
 
28
23
  context "with multiple unqualified models" do
29
24
  let(:list) { ["info:fedora/fedora-system:FedoraObject-3.0", "info:fedora/fedora-system:FooObject"] }
30
- subject { FedoraMigrate::TargetConstructor.new(list).build.target }
31
- it { is_expected.to be_nil }
25
+ subject { described_class.new(mock_source) }
26
+ its(:target) { is_expected.to be_nil }
32
27
  end
33
-
34
28
  end
@@ -2,12 +2,20 @@ require 'fedora-migrate'
2
2
  require 'rspec/core'
3
3
  require 'rspec/core/rake_task'
4
4
  require 'jettywrapper'
5
+ require 'rubocop/rake_task'
6
+
5
7
  Jettywrapper.url = "https://github.com/projecthydra/hydra-jetty/archive/migrate.zip"
6
8
 
7
9
  RSpec::Core::RakeTask.new(:spec)
8
10
 
11
+ desc 'Run style checker'
12
+ RuboCop::RakeTask.new(:rubocop) do |task|
13
+ task.requires << 'rubocop-rspec'
14
+ task.fail_on_error = true
15
+ end
16
+
9
17
  desc "Run continuous integration tests"
10
- task ci: ['jetty:clean'] do
18
+ task ci: [:rubocop, 'jetty:clean'] do
11
19
  jetty_params = Jettywrapper.load_config
12
20
  error = Jettywrapper.wrap(jetty_params) do
13
21
  Rake::Task['fixtures:load'].invoke
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fedora-migrate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wead
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2016-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hydra-head
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec-its
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description: Migrates data (models, datastreams, content) from a Fedora3 repository
140
154
  to Fedora4
141
155
  email:
@@ -146,6 +160,8 @@ extra_rdoc_files: []
146
160
  files:
147
161
  - ".gitignore"
148
162
  - ".rspec"
163
+ - ".rubocop.yml"
164
+ - ".rubocop_todo.yml"
149
165
  - ".travis.yml"
150
166
  - Gemfile
151
167
  - LICENSE
@@ -210,6 +226,7 @@ files:
210
226
  - spec/fixtures/reports/sample/scholarsphere_6395wb555.json
211
227
  - spec/fixtures/reports/sample/scholarsphere_x346dm27k.json
212
228
  - spec/integration/content_versions_spec.rb
229
+ - spec/integration/custom_target_spec.rb
213
230
  - spec/integration/fedora3_interface_spec.rb
214
231
  - spec/integration/missing_relationships_spec.rb
215
232
  - spec/integration/object_migration_spec.rb
@@ -256,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
256
273
  version: '0'
257
274
  requirements: []
258
275
  rubyforge_project:
259
- rubygems_version: 2.4.3
276
+ rubygems_version: 2.5.1
260
277
  signing_key:
261
278
  specification_version: 4
262
279
  summary: Migrate Hydra-based repository data from Fedora3 to Fedora4
@@ -292,6 +309,7 @@ test_files:
292
309
  - spec/fixtures/reports/sample/scholarsphere_6395wb555.json
293
310
  - spec/fixtures/reports/sample/scholarsphere_x346dm27k.json
294
311
  - spec/integration/content_versions_spec.rb
312
+ - spec/integration/custom_target_spec.rb
295
313
  - spec/integration/fedora3_interface_spec.rb
296
314
  - spec/integration/missing_relationships_spec.rb
297
315
  - spec/integration/object_migration_spec.rb