specify_cli 0.0.5

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 (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