specify_cli 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +17 -0
  5. data/Gemfile.lock +117 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.rdoc +43 -0
  8. data/Rakefile +15 -0
  9. data/bin/specify_cli +248 -0
  10. data/lib/specify.rb +45 -0
  11. data/lib/specify/branch_parser.rb +85 -0
  12. data/lib/specify/cli.rb +11 -0
  13. data/lib/specify/cli/database_setup.rb +46 -0
  14. data/lib/specify/cli/stubs.rb +63 -0
  15. data/lib/specify/cli/viewset.rb +21 -0
  16. data/lib/specify/configuration.rb +12 -0
  17. data/lib/specify/configuration/config.rb +120 -0
  18. data/lib/specify/configuration/db_config.rb +162 -0
  19. data/lib/specify/configuration/host_config.rb +37 -0
  20. data/lib/specify/database.rb +140 -0
  21. data/lib/specify/models.rb +43 -0
  22. data/lib/specify/models/accession.rb +33 -0
  23. data/lib/specify/models/agent.rb +138 -0
  24. data/lib/specify/models/app_resource_data.rb +32 -0
  25. data/lib/specify/models/app_resource_dir.rb +43 -0
  26. data/lib/specify/models/auto_numbering_scheme.rb +94 -0
  27. data/lib/specify/models/collecting_event.rb +38 -0
  28. data/lib/specify/models/collection.rb +67 -0
  29. data/lib/specify/models/collection_object.rb +127 -0
  30. data/lib/specify/models/createable.rb +21 -0
  31. data/lib/specify/models/determination.rb +63 -0
  32. data/lib/specify/models/discipline.rb +61 -0
  33. data/lib/specify/models/division.rb +26 -0
  34. data/lib/specify/models/geography.rb +5 -0
  35. data/lib/specify/models/geography/administrative_division.rb +32 -0
  36. data/lib/specify/models/geography/geographic_name.rb +66 -0
  37. data/lib/specify/models/geography/geography.rb +23 -0
  38. data/lib/specify/models/institution.rb +13 -0
  39. data/lib/specify/models/locality.rb +50 -0
  40. data/lib/specify/models/preparation.rb +53 -0
  41. data/lib/specify/models/preparation_type.rb +30 -0
  42. data/lib/specify/models/record_set.rb +55 -0
  43. data/lib/specify/models/record_set_item.rb +29 -0
  44. data/lib/specify/models/taxonomy.rb +6 -0
  45. data/lib/specify/models/taxonomy/common_name.rb +14 -0
  46. data/lib/specify/models/taxonomy/rank.rb +31 -0
  47. data/lib/specify/models/taxonomy/taxon.rb +54 -0
  48. data/lib/specify/models/taxonomy/taxonomy.rb +21 -0
  49. data/lib/specify/models/tree_queryable.rb +55 -0
  50. data/lib/specify/models/updateable.rb +20 -0
  51. data/lib/specify/models/user.rb +104 -0
  52. data/lib/specify/models/view_set_object.rb +32 -0
  53. data/lib/specify/number_format.rb +60 -0
  54. data/lib/specify/services.rb +18 -0
  55. data/lib/specify/services/service.rb +51 -0
  56. data/lib/specify/services/stub_generator.rb +291 -0
  57. data/lib/specify/services/view_loader.rb +177 -0
  58. data/lib/specify/session.rb +77 -0
  59. data/lib/specify/user_type.rb +61 -0
  60. data/lib/specify/version.rb +19 -0
  61. data/man/specify_cli-database.1 +60 -0
  62. data/man/specify_cli-database.1.html +137 -0
  63. data/man/specify_cli-database.1.ronn +53 -0
  64. data/man/specify_cli-repository.1 +55 -0
  65. data/man/specify_cli-repository.1.html +128 -0
  66. data/man/specify_cli-repository.1.ronn +42 -0
  67. data/man/specify_cli-stubs.1 +177 -0
  68. data/man/specify_cli-stubs.1.html +239 -0
  69. data/man/specify_cli-stubs.1.ronn +147 -0
  70. data/man/specify_cli-viewset.1 +92 -0
  71. data/man/specify_cli-viewset.1.html +154 -0
  72. data/man/specify_cli-viewset.1.ronn +72 -0
  73. data/man/specify_cli.1 +213 -0
  74. data/man/specify_cli.1.html +252 -0
  75. data/man/specify_cli.1.ronn +157 -0
  76. data/spec/branch_parser_spec.rb +94 -0
  77. data/spec/cli/stubs_spec.rb +44 -0
  78. data/spec/configuration/config_spec.rb +269 -0
  79. data/spec/configuration/db_config_spec.rb +299 -0
  80. data/spec/configuration/host_config_spec.rb +64 -0
  81. data/spec/database_spec.rb +83 -0
  82. data/spec/examples.txt +217 -0
  83. data/spec/helpers.rb +15 -0
  84. data/spec/models/app_resource_data_spec.rb +38 -0
  85. data/spec/models/app_resource_dir_spec.rb +8 -0
  86. data/spec/models/auto_numbering_scheme_spec.rb +78 -0
  87. data/spec/models/collection_object_spec.rb +92 -0
  88. data/spec/models/collection_spec.rb +32 -0
  89. data/spec/models/discipline_spec.rb +31 -0
  90. data/spec/models/record_set_spec.rb +18 -0
  91. data/spec/models/user_spec.rb +182 -0
  92. data/spec/models/view_set_object_spec.rb +70 -0
  93. data/spec/number_format_spec.rb +43 -0
  94. data/spec/services/stub_generator_spec.rb +635 -0
  95. data/spec/services/view_loader_spec.rb +436 -0
  96. data/spec/session_spec.rb +105 -0
  97. data/spec/spec_helper.rb +116 -0
  98. data/spec/support/db.yml +12 -0
  99. data/spec/support/stub.yaml +17 -0
  100. data/spec/support/stub_locality.yaml +19 -0
  101. data/spec/support/viewsets/paleo.views.xml +30 -0
  102. data/spec/support/viewsets/paleo.xml +30 -0
  103. data/spec/user_type_spec.rb +79 -0
  104. data/specify_cli.gemspec +27 -0
  105. data/specify_cli.rdoc +1 -0
  106. metadata +246 -0
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe ViewSetObject do
6
+ let :file do
7
+ Pathname.new(Dir.pwd).join('spec', 'support',
8
+ 'viewsets', 'paleo.views.xml')
9
+ end
10
+
11
+ let :view_set_object do
12
+ Collection.first(CollectionName: 'Test Collection').view_set
13
+ end
14
+
15
+ describe '#import(views_file)' do
16
+ subject(:view_set_import) { view_set_object.import(file) }
17
+
18
+ before { view_set_object.app_resource_data.data = nil }
19
+
20
+ it do
21
+ expect { view_set_import }
22
+ .to change(view_set_object, :Version)
23
+ .by 1
24
+ end
25
+
26
+ it do
27
+ just_before = Time.now
28
+ expect { view_set_import }
29
+ .to change(view_set_object, :TimestampModified)
30
+ .from(a_value <= just_before)
31
+ .to a_value >= just_before
32
+ end
33
+
34
+ it do
35
+ expect { view_set_import }
36
+ .to change { view_set_object.app_resource_dir.Version }
37
+ .by 1
38
+ end
39
+
40
+ it do
41
+ just_before = Time.now
42
+ expect { view_set_import }
43
+ .to change(view_set_object.app_resource_dir, :TimestampModified)
44
+ .from(a_value <= just_before)
45
+ .to a_value >= just_before
46
+ end
47
+
48
+ it do
49
+ expect { view_set_import }
50
+ .to change { view_set_object.app_resource_data.Version }
51
+ .by 1
52
+ end
53
+
54
+ it do
55
+ just_before = Time.now
56
+ expect { view_set_import }
57
+ .to change(view_set_object.app_resource_data, :TimestampModified)
58
+ .from(a_value <= just_before)
59
+ .to a_value >= just_before
60
+ end
61
+
62
+ it do
63
+ expect { view_set_import }
64
+ .to change { view_set_object.app_resource_data.data }
65
+ .from(nil).to(Sequel.blob(File.read(file)))
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ RSpec.describe NumberFormat do
5
+ describe '#create' do
6
+ subject { described_class.new(9).create(123) }
7
+
8
+ it { is_expected.to eq '000000123' }
9
+ end
10
+
11
+ describe '#incrementer' do
12
+ subject { described_class.new(9).incrementer('000000123') }
13
+
14
+ it { is_expected.to be 123 }
15
+ end
16
+
17
+ describe '#numeric?' do
18
+ context 'when the number format is numeric' do
19
+ subject { described_class.new(9).numeric? }
20
+
21
+ it { is_expected.to be_truthy }
22
+ end
23
+
24
+ context 'when the number format is not numeric' do
25
+ subject { described_class.new(9, template: 'YYYY-#########').numeric? }
26
+
27
+ it { is_expected.to be_falsey }
28
+ end
29
+ end
30
+
31
+ describe '#template' do
32
+ subject { described_class.new(9).template }
33
+
34
+ it { is_expected.to eq '#########' }
35
+ end
36
+
37
+ describe '#to_regexp' do
38
+ subject { described_class.new(9).to_regexp }
39
+
40
+ it { is_expected.to eq /^(?<incrementer>\d{9})$/ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,635 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Tests for the
4
+ module Specify
5
+ module Service
6
+ RSpec.describe StubGenerator do
7
+ let :stub_generator do
8
+ file = Pathname.new(Dir.pwd).join('spec', 'support', 'db.yml')
9
+ described_class.new host: 'localhost',
10
+ database: 'SPSPEC',
11
+ collection: 'Test Collection',
12
+ config: file
13
+ end
14
+
15
+ let(:det) { { 'Family' => 'Asaphidae' } }
16
+ let(:prep) { { type: 'Specimen', count: 1 } }
17
+
18
+ let :accession do
19
+ an_instance_of(Model::Accession)
20
+ .and have_attributes(AccessionNumber: '2018-AA-001')
21
+ end
22
+
23
+ let :agent do
24
+ an_instance_of(Model::Agent) & having_attributes(LastName: 'Specman')
25
+ end
26
+
27
+ let :taxon do
28
+ rank = an_instance_of(Model::Rank) & have_attributes(Name: 'Family')
29
+ an_instance_of(Model::Taxon) & have_attributes(Name: 'Asaphidae',
30
+ rank: rank)
31
+ end
32
+
33
+ let :country do
34
+ rank = an_instance_of(Model::AdministrativeDivision)
35
+ .and have_attributes(Name: 'Country')
36
+ an_instance_of(Model::GeographicName)
37
+ .and have_attributes(Name: 'United States',
38
+ rank: rank)
39
+ end
40
+
41
+ let :county do
42
+ rank = an_instance_of(Model::AdministrativeDivision)
43
+ .and have_attributes(Name: 'County')
44
+ an_instance_of(Model::GeographicName)
45
+ .and have_attributes(Name: 'Douglas County',
46
+ rank: rank)
47
+ end
48
+
49
+ let :disciplines do
50
+ a_collection_including(stub_generator.discipline)
51
+ end
52
+
53
+ let :prep_type do
54
+ an_instance_of(Model::PreparationType)
55
+ .and have_attributes Name: 'Specimen'
56
+ end
57
+
58
+ describe '.load_yaml(file)' do
59
+ context 'when YAML specifies locality' do
60
+ subject { described_class.load_yaml file }
61
+
62
+ let :file do
63
+ Pathname.new(Dir.pwd).join('spec', 'support', 'stub_locality.yaml')
64
+ end
65
+
66
+ let :locality do
67
+ have_attributes LocalityName: 'Downtown Lawrence',
68
+ geographic_name: county
69
+ end
70
+
71
+ it { is_expected.to have_attributes accession: accession }
72
+
73
+ it { is_expected.to have_attributes cataloger: agent }
74
+
75
+ it { is_expected.to have_attributes collecting_geography: county }
76
+
77
+ it { is_expected.to have_attributes collecting_locality: locality }
78
+
79
+ it { is_expected.to have_attributes taxon: taxon }
80
+
81
+ it { is_expected.to have_attributes preparation_type: prep_type }
82
+
83
+ it { is_expected.to have_attributes preparation_count: 1 }
84
+
85
+ it do
86
+ is_expected
87
+ .to have_attributes dataset_name: 'stubs with locality'
88
+ end
89
+ end
90
+
91
+ context 'when YAML does not specify locality' do
92
+ subject { described_class.load_yaml file }
93
+
94
+ let :file do
95
+ Pathname.new(Dir.pwd).join('spec', 'support', 'stub.yaml')
96
+ end
97
+
98
+ let :locality do
99
+ have_attributes LocalityName: 'default stub locality US',
100
+ geographic_name: country
101
+ end
102
+
103
+ it { is_expected.to have_attributes accession: accession }
104
+
105
+ it { is_expected.to have_attributes cataloger: agent }
106
+
107
+ it { is_expected.to have_attributes collecting_geography: country }
108
+
109
+ it { is_expected.to have_attributes default_locality: locality }
110
+
111
+ it { is_expected.to have_attributes taxon: taxon }
112
+
113
+ it { is_expected.to have_attributes preparation_type: prep_type }
114
+
115
+ it { is_expected.to have_attributes preparation_count: 1 }
116
+
117
+ it do
118
+ is_expected
119
+ .to have_attributes dataset_name: 'stubs with default locality'
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#accession' do
125
+ context 'when passed a known accession number' do
126
+ subject(:set_accession) { stub_generator.accession = '2018-AA-001' }
127
+
128
+ it do
129
+ expect { set_accession }
130
+ .to change(stub_generator, :accession).from(be_nil).to accession
131
+ end
132
+ end
133
+
134
+ context 'when passed an unknown accession number' do
135
+ subject(:set_accession) { stub_generator.accession = 'void' }
136
+
137
+ it do
138
+ expect { set_accession }
139
+ .to raise_error ACCESSION_NOT_FOUND_ERROR + 'void'
140
+ end
141
+ end
142
+ end
143
+
144
+ describe '#cataloger=(user_name)' do
145
+ context 'when passed a known user name' do
146
+ subject(:set_cataloger) { stub_generator.cataloger = 'specmanager' }
147
+
148
+ it do
149
+ expect { set_cataloger }
150
+ .to change(stub_generator, :cataloger)
151
+ .from(stub_generator.agent).to agent
152
+ end
153
+ end
154
+
155
+ context 'when passed an unknown user name' do
156
+ subject(:set_cataloger) { stub_generator.cataloger = 'nobody' }
157
+
158
+ it do
159
+ expect { set_cataloger }
160
+ .to raise_error USER_NOT_FOUND_ERROR + 'nobody'
161
+ end
162
+ end
163
+ end
164
+
165
+ describe '#collecting_data=(vals)' do
166
+ let :locality do
167
+ an_instance_of(Model::Locality)
168
+ .and have_attributes(LocalityName: 'Downtown Lawrence',
169
+ geographic_name: county)
170
+ end
171
+
172
+ context 'when passed country only' do
173
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
174
+
175
+ let(:cd) { { 'Country' => 'United States' } }
176
+
177
+ it do
178
+ expect { set_collecting }
179
+ .to change(stub_generator, :collecting_geography)
180
+ .from(be_nil).to country
181
+ end
182
+ end
183
+
184
+ context 'when passed country, state, and county' do
185
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
186
+
187
+ let :cd do
188
+ { 'Country' => 'United States',
189
+ 'State' => 'Kansas',
190
+ 'County' => 'Douglas County' }
191
+ end
192
+
193
+ it do
194
+ expect { set_collecting }
195
+ .to change(stub_generator, :collecting_geography)
196
+ .from(be_nil).to county
197
+ end
198
+ end
199
+
200
+ context 'when passed county only and county is ambiguous' do
201
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
202
+
203
+ let(:cd) { { 'County' => 'Douglas County' } }
204
+
205
+ it do
206
+ expect { set_collecting }
207
+ .to raise_error Model::TreeQueryable::AMBIGUOUS_MATCH_ERROR +
208
+ ' for Douglas County: ["United States, Kansas,'\
209
+ ' Douglas County", "United States, Wisconsin,'\
210
+ ' Douglas County"]'
211
+ end
212
+ end
213
+
214
+ context 'when passed geography and locality' do
215
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
216
+
217
+ let :cd do
218
+ { 'Country' => 'United States',
219
+ 'State' => 'Kansas',
220
+ 'County' => 'Douglas County',
221
+ locality: 'Downtown Lawrence' }
222
+ end
223
+
224
+ it do
225
+ expect { set_collecting }
226
+ .to change(stub_generator, :collecting_geography)
227
+ .from(be_nil).to(county)
228
+ .and change(stub_generator, :collecting_locality)
229
+ .from(be_nil).to(locality)
230
+ end
231
+ end
232
+
233
+ context 'when passed locality only' do
234
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
235
+
236
+ let(:cd) { { locality: 'Downtown Lawrence' } }
237
+
238
+ it do
239
+ expect { set_collecting }
240
+ .to change(stub_generator, :collecting_locality)
241
+ .from(be_nil).to locality
242
+ end
243
+ end
244
+
245
+ context 'when passing an unknown locality' do
246
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
247
+
248
+ let(:cd) { { locality: 'No place' } }
249
+
250
+ it do
251
+ expect { set_collecting }
252
+ .to raise_error LOCALITY_NOT_FOUND_ERROR + 'No place'
253
+ end
254
+ end
255
+
256
+ context 'when passed an unknown geography' do
257
+ subject(:set_collecting) { stub_generator.collecting_data = cd }
258
+
259
+ let(:cd) do
260
+ { 'Country' => 'United States',
261
+ 'State' => 'British Columbia' }
262
+ end
263
+
264
+ it do
265
+ expect { set_collecting }
266
+ .to raise_error GEOGRAPHY_NOT_FOUND_ERROR + cd.values.join(', ')
267
+ end
268
+ end
269
+ end
270
+
271
+ describe '#collecting_locality!' do
272
+ subject { stub_generator.collecting_locality! }
273
+
274
+ context 'when collecting locality is set' do
275
+ let :cd do
276
+ { 'Country' => 'United States',
277
+ 'State' => 'Kansas',
278
+ 'County' => 'Douglas County',
279
+ locality: 'Downtown Lawrence' }
280
+ end
281
+
282
+ before { stub_generator.collecting_data = cd }
283
+
284
+ it do
285
+ is_expected.to be_a(Model::Locality)
286
+ .and have_attributes LocalityName: 'Downtown Lawrence',
287
+ geographic_name: county
288
+ end
289
+ end
290
+
291
+ context 'when collecting locality is not set but geography is set' do
292
+ before do
293
+ stub_generator.default_locality_name = 'default stub locality US'
294
+ stub_generator.collecting_data = { 'Country' => 'United States' }
295
+ end
296
+
297
+ it do
298
+ is_expected.to be_a(Model::Locality)
299
+ .and have_attributes LocalityName: 'default stub locality US',
300
+ geographic_name: country
301
+ end
302
+ end
303
+
304
+ context 'when collecting locality and geography are not set' do
305
+ it { is_expected.to be_nil }
306
+ end
307
+ end
308
+
309
+ describe '#create(count)' do
310
+ let :record_set_items do
311
+ first_item = an_instance_of(Model::RecordSetItem)
312
+ .and(have_attributes(OrderNumber: 0))
313
+ last_item = an_instance_of(Model::RecordSetItem)
314
+ .and(have_attributes(OrderNumber: 9))
315
+ a_collection_including(first_item, last_item)
316
+ .and have_attributes count: 10
317
+ end
318
+
319
+ let :generated do
320
+ first_collection_object = an_instance_of(Model::CollectionObject)
321
+ .and(have_attributes(CatalogNumber: '000000001'))
322
+ last_collection_object = an_instance_of(Model::CollectionObject)
323
+ .and(have_attributes(CatalogNumber: '000000010'))
324
+ a_collection_including(first_collection_object,
325
+ last_collection_object)
326
+ .and have_attributes count: 10
327
+ end
328
+
329
+ it do
330
+ expect { stub_generator.create(10) }
331
+ .to change { Model::CollectionObject.dataset.count }.by 10
332
+ end
333
+
334
+ it do
335
+ expect { stub_generator.create 1 }
336
+ .to change { Model::CollectionObject.dataset.last }
337
+ .from(be_nil).to having_attributes(cataloger: stub_generator.agent)
338
+ end
339
+
340
+ it do
341
+ expect { stub_generator.create 10 }
342
+ .to change(stub_generator, :record_set)
343
+ .from(be_nil)
344
+ .to an_instance_of(Model::RecordSet)
345
+ .and have_attributes record_set_items: record_set_items
346
+ end
347
+
348
+ it do
349
+ expect { stub_generator.create 10 }
350
+ .to change(stub_generator, :generated)
351
+ .from(be_nil)
352
+ .to generated
353
+ end
354
+
355
+ context 'when creating with an accession' do
356
+ before { stub_generator.accession = '2018-AA-001' }
357
+
358
+ it do
359
+ expect { stub_generator.create 1 }
360
+ .to change { Model::CollectionObject.dataset.last }
361
+ .from(be_nil).to having_attributes(accession: accession)
362
+ end
363
+ end
364
+
365
+ context 'when creating with another cataloger' do
366
+ before { stub_generator.cataloger = 'specmanager' }
367
+
368
+ it do
369
+ expect { stub_generator.create 1 }
370
+ .to change { Model::CollectionObject.dataset.last }
371
+ .from(be_nil)
372
+ .to having_attributes(cataloger: agent)
373
+ end
374
+ end
375
+
376
+ context 'when creating with determinations' do
377
+ before { stub_generator.determination = det }
378
+
379
+ let :determinations do
380
+ a_collection_including an_instance_of(Model::Determination)
381
+ .and have_attributes(taxon: taxon)
382
+ end
383
+
384
+ it do
385
+ expect { stub_generator.create 1 }
386
+ .to change { Model::CollectionObject.dataset.last }
387
+ .from(be_nil)
388
+ .to having_attributes(determinations: determinations)
389
+ end
390
+ end
391
+
392
+ context 'when creating with collecting event with locality' do
393
+ let :cd do
394
+ { 'Country' => 'United States',
395
+ 'State' => 'Kansas',
396
+ 'County' => 'Douglas County',
397
+ locality: 'Downtown Lawrence' }
398
+ end
399
+
400
+ let :collecting_event do
401
+ an_instance_of(Model::CollectingEvent)
402
+ .and have_attributes locality: locality
403
+ end
404
+
405
+ let :locality do
406
+ an_instance_of(Model::Locality)
407
+ .and have_attributes(LocalityName: 'Downtown Lawrence',
408
+ geographic_name: county)
409
+ end
410
+
411
+ before { stub_generator.collecting_data = cd }
412
+
413
+ it do
414
+ expect { stub_generator.create 1 }
415
+ .to change { Model::CollectionObject.dataset.last }
416
+ .from(be_nil)
417
+ .to having_attributes(collecting_event: collecting_event)
418
+ end
419
+ end
420
+
421
+ context 'when creating with collecting event without locality' do
422
+ let :cd do
423
+ { 'Country' => 'United States',
424
+ 'State' => 'Kansas',
425
+ 'County' => 'Douglas County' }
426
+ end
427
+
428
+ let :collecting_event do
429
+ an_instance_of(Model::CollectingEvent)
430
+ .and have_attributes locality: locality
431
+ end
432
+
433
+ let :locality do
434
+ an_instance_of(Model::Locality)
435
+ .and have_attributes(LocalityName: 'default locality',
436
+ geographic_name: county)
437
+ end
438
+
439
+ before do
440
+ stub_generator.default_locality_name = 'default locality'
441
+ stub_generator.collecting_data = cd
442
+ end
443
+
444
+ it do
445
+ expect { stub_generator.create 1 }
446
+ .to change { Model::CollectionObject.dataset.last }
447
+ .from(be_nil)
448
+ .to having_attributes(collecting_event: collecting_event)
449
+ end
450
+ end
451
+
452
+ context 'when creating with preparations' do
453
+ before { stub_generator.preparation = prep }
454
+
455
+ let :preparations do
456
+ preptype = an_instance_of(Model::PreparationType)
457
+ .and have_attributes(Name: 'Specimen')
458
+ a_collection_including an_instance_of(Model::Preparation)
459
+ .and have_attributes(CountAmt: 1,
460
+ preparation_type: preptype)
461
+ end
462
+
463
+ it do
464
+ expect { stub_generator.create 1 }
465
+ .to change { Model::CollectionObject.dataset.last }
466
+ .from(be_nil)
467
+ .to having_attributes(preparations: preparations)
468
+ end
469
+ end
470
+ end
471
+
472
+ describe '#default_locality' do
473
+ subject { stub_generator.default_locality }
474
+
475
+ context 'when the default locality is known' do
476
+ before do
477
+ stub_generator.default_locality_name = 'default stub locality'
478
+ end
479
+
480
+ it do
481
+ is_expected.to be_a(Model::Locality)
482
+ .and have_attributes LocalityName: 'default stub locality'
483
+ end
484
+ end
485
+
486
+ context 'when the default locality is not known' do
487
+ it { is_expected.to be_nil }
488
+ end
489
+ end
490
+
491
+ describe '#default_locality!' do
492
+ subject(:get_default) { stub_generator.default_locality! }
493
+
494
+ let(:name) { 'not cataloged, see label' }
495
+
496
+ context 'when the default locality is known' do
497
+ before do
498
+ stub_generator.default_locality_name = 'default stub locality'
499
+ end
500
+
501
+ it do
502
+ is_expected.to be_a(Model::Locality)
503
+ .and have_attributes LocalityName: 'default stub locality'
504
+ end
505
+ end
506
+
507
+ context 'when the default locality is not known and'\
508
+ ' collecting_geography is set' do
509
+ let :locality do
510
+ an_instance_of(Model::Locality)
511
+ .and have_attributes LocalityName: 'not cataloged, see label',
512
+ geographic_name: country
513
+ end
514
+
515
+ before do
516
+ stub_generator.collecting_data = { 'Country' => 'United States' }
517
+ end
518
+
519
+ it do
520
+ expect { get_default }
521
+ .to change(stub_generator, :default_locality)
522
+ .from(be_nil)
523
+ .to locality
524
+ end
525
+ end
526
+
527
+ context 'when the default locality is not known and'\
528
+ ' collecting_geography is not set' do
529
+ let :locality do
530
+ an_instance_of(Model::Locality)
531
+ .and have_attributes(LocalityName: 'not cataloged, see label',
532
+ geographic_name: be_nil)
533
+ end
534
+
535
+ it do
536
+ expect { get_default }
537
+ .to change(stub_generator, :default_locality)
538
+ .from(be_nil)
539
+ .to locality
540
+ end
541
+ end
542
+ end
543
+
544
+ describe '#determination=(vals)' do
545
+ context 'when passed a known taxon' do
546
+ subject(:set_determination) { stub_generator.determination = det }
547
+
548
+ it do
549
+ expect { set_determination }
550
+ .to change(stub_generator, :taxon).from(be_nil).to taxon
551
+ end
552
+ end
553
+
554
+ context 'when passed an unknown taxon' do
555
+ subject(:set_determination) { stub_generator.determination = indet }
556
+
557
+ let(:indet) { { 'Family' => 'Illaenidae' } }
558
+
559
+ it do
560
+ expect { set_determination }
561
+ .to raise_error TAXON_NOT_FOUND_ERROR + '{"Family"=>"Illaenidae"}'
562
+ end
563
+ end
564
+ end
565
+
566
+ describe '#find_locality(locality_name)' do
567
+ subject { stub_generator.find_locality 'Downtown Lawrence' }
568
+
569
+ it do
570
+ is_expected.to be_a(Model::Locality)
571
+ .and have_attributes(LocalityName: 'Downtown Lawrence',
572
+ geographic_name: county)
573
+ end
574
+ end
575
+
576
+ describe '#geography' do
577
+ subject { stub_generator.geography }
578
+
579
+ it do
580
+ is_expected.to be_a(Model::Geography)
581
+ .and have_attributes disciplines: disciplines
582
+ end
583
+ end
584
+
585
+ describe '#localities' do
586
+ subject { stub_generator.localities }
587
+
588
+ let :locality do
589
+ an_instance_of(Model::Locality)
590
+ .and have_attributes(LocalityName: 'Downtown Lawrence',
591
+ geographic_name: county)
592
+ end
593
+
594
+ it do pending 'example broken in rspec 3.8'
595
+ is_expected.to be_a(Sequel::Dataset)
596
+ .and include locality
597
+ end
598
+ end
599
+
600
+ describe '#preparation=(type:, count:)' do
601
+ context 'when type is known' do
602
+ subject(:set_preparation) { stub_generator.preparation = prep }
603
+
604
+ it do
605
+ expect { set_preparation }
606
+ .to change(stub_generator, :preparation_type)
607
+ .from(be_nil).to(prep_type)
608
+ .and change(stub_generator, :preparation_count)
609
+ .from(be_nil).to 1
610
+ end
611
+ end
612
+
613
+ context 'when type is unknown' do
614
+ subject(:set_preparation) { stub_generator.preparation = unprep }
615
+
616
+ let(:unprep) { { type: 'Thing', count: 1 } }
617
+
618
+ it do
619
+ expect { set_preparation }
620
+ .to raise_error PREPTYPE_NOT_FOUND_ERROR + 'Thing'
621
+ end
622
+ end
623
+ end
624
+
625
+ describe '#taxonomy' do
626
+ subject { stub_generator.taxonomy }
627
+
628
+ it do
629
+ is_expected.to be_a(Model::Taxonomy)
630
+ .and have_attributes disciplines: disciplines
631
+ end
632
+ end
633
+ end
634
+ end
635
+ end