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
data/spec/helpers.rb ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+
5
+ # RSpec helpers
6
+ module Helpers
7
+ def set_branch
8
+ branch = `git branch --list #{TEST_BRANCH}`.chomp
9
+ `git branch #{TEST_BRANCH}` if branch.empty?
10
+ system("git checkout #{TEST_BRANCH}")
11
+ e = "Error checking out #{TEST_BRANCH}
12
+ there are probably uncommited changes on #{@origin}"
13
+ raise e unless $CHILD_STATUS == 0
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe AppResourceData do
6
+ let :file do
7
+ Pathname.new(Dir.pwd).join('spec', 'support',
8
+ 'viewsets', 'paleo.views.xml')
9
+ end
10
+
11
+ let :app_resource_data do
12
+ Collection.first(CollectionName: 'Test Collection')
13
+ .view_set.app_resource_data
14
+ end
15
+
16
+ context 'when uploading a file' do
17
+ it 'increments the version number' do
18
+ v = app_resource_data.Version
19
+ expect { app_resource_data.import(file) }
20
+ .to change { app_resource_data.Version }
21
+ .from(v).to(v + 1)
22
+ end
23
+
24
+ it 'updates the modification timestamp' do
25
+ expect { app_resource_data.import(file) }
26
+ .to change(app_resource_data, :TimestampModified)
27
+ end
28
+
29
+ it 'uploads the files content as a Sequel Blob' do
30
+ app_resource_data.data = nil
31
+ expect { app_resource_data.import(file) }
32
+ .to change { app_resource_data.data }
33
+ .from(nil).to(Sequel.blob(File.read(file)))
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe AppResourceDir do
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe AutoNumberingScheme do
6
+ # FIXME: move to shared context
7
+ before :all do
8
+ cataloger = Agent.first(FirstName: 'John', LastName: 'Specman')
9
+ collection_a = Collection.first Code: 'SIP'
10
+ collection_b = Collection.first Code: 'NECE'
11
+
12
+ collection_a.add_collection_object(cataloger: cataloger,
13
+ CatalogNumber: '000000011')
14
+ collection_a.add_collection_object(cataloger: cataloger,
15
+ CatalogNumber: '000000012')
16
+ collection_b.add_collection_object(cataloger: cataloger,
17
+ CatalogNumber: '000000013')
18
+ end
19
+
20
+ let :auto_numbering_scheme do
21
+ Collection.first(CollectionName: 'Test Collection')
22
+ .auto_numbering_scheme
23
+ end
24
+
25
+ describe '#catalog_number?' do
26
+ context 'when the scheme is a catalog number' do
27
+ subject { auto_numbering_scheme.catalog_number? }
28
+
29
+ it { is_expected.to be true }
30
+ end
31
+ end
32
+
33
+ describe '#increment' do
34
+ subject { auto_numbering_scheme.increment }
35
+
36
+ it { is_expected.to eq '000000014' }
37
+ end
38
+
39
+ describe '#max' do
40
+ subject { auto_numbering_scheme.max }
41
+
42
+ it { is_expected.to eq '000000013' }
43
+ end
44
+
45
+ describe '#number_format' do
46
+ context 'when the scheme is a numeric catalog number format' do
47
+ subject { auto_numbering_scheme.number_format }
48
+
49
+ it do
50
+ is_expected.to have_attributes incrementer_length: 9
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#scheme_model' do
56
+ context 'when the scheme is defined for collection objects' do
57
+ subject { auto_numbering_scheme.scheme_model }
58
+
59
+ it { is_expected.to be CollectionObject }
60
+ end
61
+ end
62
+
63
+ describe '#scheme_type' do
64
+ context 'when the scheme is a catalog number' do
65
+ subject { auto_numbering_scheme.scheme_type }
66
+
67
+ it { is_expected.to be :catalog_number }
68
+ end
69
+ end
70
+
71
+ # FIXME: move to shared context
72
+ after :all do
73
+ CollectionObject.dataset.delete
74
+ CollectingEvent.dataset.delete
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe CollectionObject do
6
+ # FIXME: move to shared context
7
+ before :all do
8
+ cataloger = Agent.first(FirstName: 'John', LastName: 'Specman')
9
+ collection_a = Collection.first Code: 'SIP'
10
+ collection_b = Collection.first Code: 'NECE'
11
+
12
+ collection_a.add_collection_object(cataloger: cataloger,
13
+ CatalogNumber: '000000011')
14
+ collection_a.add_collection_object(cataloger: cataloger,
15
+ CatalogNumber: '000000012')
16
+ collection_b.add_collection_object(cataloger: cataloger,
17
+ CatalogNumber: '000000013')
18
+ end
19
+
20
+ let :collection do
21
+ Collection.first CollectionName: 'Test Collection'
22
+ end
23
+
24
+ context 'when adding to collection' do
25
+ let :cataloger do
26
+ Agent.first(FirstName: 'John', LastName: 'Specman')
27
+ end
28
+
29
+ context 'when passing the catalog number' do
30
+ subject do
31
+ collection.add_collection_object(cataloger: cataloger,
32
+ CatalogNumber: '000000009')
33
+ end
34
+
35
+ it do
36
+ is_expected.to have_attributes Version: 0,
37
+ TimestampCreated: an_instance_of(Time),
38
+ collection_member: collection,
39
+ CatalogedDate: an_instance_of(Date),
40
+ CatalogedDatePrecision: 1,
41
+ GUID: an_instance_of(String),
42
+ CatalogNumber: '000000009'
43
+ end
44
+ end
45
+
46
+ context 'when passing no catalog number' do
47
+ subject do
48
+ collection.add_collection_object(cataloger: cataloger)
49
+ end
50
+
51
+ it do
52
+ is_expected.to have_attributes Version: 0,
53
+ TimestampCreated: an_instance_of(Time),
54
+ collection_member: collection,
55
+ CatalogedDate: an_instance_of(Date),
56
+ CatalogedDatePrecision: 1,
57
+ GUID: an_instance_of(String),
58
+ CatalogNumber: '000000014'
59
+ end
60
+ end
61
+
62
+ context 'when collecting event is emebedded' do
63
+ subject do
64
+ collection.add_collection_object(cataloger: cataloger)
65
+ end
66
+
67
+ it do
68
+ ce = an_instance_of(CollectingEvent)
69
+ is_expected.to have_attributes collecting_event: ce
70
+ end
71
+ end
72
+
73
+ context 'when collecting event is not embedded' do
74
+ subject do
75
+ Collection.first(Code: 'NECE')
76
+ .add_collection_object(CatalogNumber: '2')
77
+ end
78
+
79
+ it do
80
+ is_expected.to have_attributes collecting_event: nil
81
+ end
82
+ end
83
+ end
84
+
85
+ # FIXME: move to shared context
86
+ after :all do
87
+ CollectionObject.dataset.delete
88
+ CollectingEvent.dataset.delete
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe Collection do
6
+ let :collection do
7
+ described_class.first CollectionName: 'Test Collection'
8
+ end
9
+
10
+ describe '#view_set_dir' do
11
+ subject { collection.view_set_dir }
12
+
13
+ it do
14
+ is_expected
15
+ .to have_attributes DisciplineType: 'Invertebrate Paleontology',
16
+ IsPersonal: false,
17
+ UserType: nil,
18
+ collection: collection,
19
+ discipline: collection.discipline
20
+ end
21
+ end
22
+
23
+ describe '#view_set' do
24
+ subject { collection.view_set }
25
+
26
+ it do
27
+ is_expected.to have_attributes Name: 'paleo.views'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe Discipline do
6
+ let :discipline do
7
+ described_class.first Name: 'Test Discipline'
8
+ end
9
+
10
+ describe '#view_set_dir' do
11
+ subject { discipline.view_set_dir }
12
+
13
+ it do
14
+ is_expected
15
+ .to have_attributes DisciplineType: 'Invertebrate Paleontology',
16
+ IsPersonal: false,
17
+ UserType: nil,
18
+ collection: nil
19
+ end
20
+ end
21
+
22
+ describe '#view_set' do
23
+ subject { discipline.view_set }
24
+
25
+ it 'returns the ViewSetObject for the given collection' do
26
+ is_expected.to have_attributes Name: 'Paleo Views'
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe RecordSet do
6
+ subject do
7
+ described_class.create Name: 'Test Record Set',
8
+ user: user,
9
+ collection: collection
10
+ end
11
+
12
+ let(:collection) { Collection.first Code: 'SIP' }
13
+ let(:user) { User.first Name: 'specuser' }
14
+
15
+ it { p subject.highest_order_number }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specify
4
+ module Model
5
+ RSpec.describe User do
6
+ let(:collection) { Collection.first CollectionName: 'Test Collection' }
7
+ let(:user) { described_class.first Name: 'specuser' }
8
+
9
+ describe '#collection_valid?' do
10
+ before { user.log_out }
11
+
12
+ context 'when logged in to the collection passed as argument' do
13
+ subject { user.collection_valid? collection }
14
+
15
+ before { user.log_in collection }
16
+
17
+ it { is_expected.to be_truthy }
18
+ end
19
+
20
+ context 'when logged in to another collection' do
21
+ subject { user.collection_valid? collection }
22
+
23
+ before { user.log_in(Collection.first(Code: 'NECE')) }
24
+
25
+ it { is_expected.to be_falsey }
26
+ end
27
+ end
28
+
29
+ describe '#log_in' do
30
+ context 'when not logged in' do
31
+ before { user.log_out }
32
+
33
+ it do
34
+ just_before = Time.now
35
+ expect(user.log_in(collection))
36
+ .to include collection => a_value >= just_before
37
+ end
38
+
39
+ it do
40
+ just_before = Time.now
41
+ expect { user.log_in(collection) }
42
+ .to change(user, :values)
43
+ .from(including(IsLoggedIn: false,
44
+ LoginCollectionName: nil,
45
+ LoginDisciplineName: nil,
46
+ LoginOutTime: a_value <= just_before))
47
+ .to(including(IsLoggedIn: true,
48
+ LoginCollectionName: collection[:CollectionName],
49
+ LoginDisciplineName: collection.discipline[:Name],
50
+ LoginOutTime: a_value >= just_before))
51
+ end
52
+ end
53
+
54
+ context 'when already logged in' do
55
+ before { user.log_in(collection) }
56
+
57
+ it do
58
+ just_before = Time.now
59
+ expect(user.log_in(collection))
60
+ .to include collection => a_value <= just_before
61
+ end
62
+
63
+ it do
64
+ expect { user.log_in(collection) }
65
+ .not_to change(user, :values)
66
+ end
67
+ end
68
+
69
+ context 'when already logged in to a different collection' do
70
+ before { user.log_in(Collection.first(Code: 'NECE')) }
71
+
72
+ it do
73
+ expect { user.log_in collection }
74
+ .to raise_error LoginError::INCONSISTENT_LOGIN
75
+ end
76
+ end
77
+ end
78
+
79
+ describe '#log_out' do
80
+ before { user.log_in collection }
81
+
82
+ it do
83
+ just_before = Time.now
84
+ expect(user.log_out)
85
+ .to be >= just_before
86
+ end
87
+
88
+ it do
89
+ just_before = Time.now
90
+ expect { user.log_out }
91
+ .to change(user, :values)
92
+ .from(including(IsLoggedIn: true,
93
+ LoginCollectionName: collection[:CollectionName],
94
+ LoginDisciplineName: collection.discipline[:Name],
95
+ LoginOutTime: a_value <= just_before))
96
+ .to(including(IsLoggedIn: false,
97
+ LoginCollectionName: nil,
98
+ LoginDisciplineName: nil,
99
+ LoginOutTime: a_value >= just_before))
100
+ end
101
+ end
102
+
103
+ describe '#logged_in?' do
104
+ before { user.log_out }
105
+
106
+ context 'when logged in to the collection passed as argument' do
107
+ subject { user.logged_in? collection }
108
+
109
+ before { user.log_in collection }
110
+
111
+ it { is_expected.to include collection => a_value <= Time.now }
112
+ end
113
+
114
+ context 'when logged in to another collection' do
115
+ before { user.log_in(Collection.first(Code: 'NECE')) }
116
+
117
+ it do
118
+ expect { user.log_in collection }
119
+ .to raise_error LoginError::INCONSISTENT_LOGIN
120
+ end
121
+ end
122
+ end
123
+
124
+ describe '#logged_in_agent' do
125
+ subject { user.logged_in_agent }
126
+
127
+ before { user.log_in collection }
128
+
129
+ it do
130
+ is_expected
131
+ .to have_attributes FirstName: 'John', LastName: 'Doe'
132
+ end
133
+ end
134
+
135
+ describe '#new_login' do
136
+ before { user.log_out }
137
+
138
+ it do
139
+ just_before = Time.now
140
+ expect(user.new_login(collection))
141
+ .to include collection => a_value >= just_before
142
+ end
143
+
144
+ it do
145
+ just_before = Time.now
146
+ expect { user.new_login(collection) }
147
+ .to change(user, :values)
148
+ .from(including(IsLoggedIn: false,
149
+ LoginCollectionName: nil,
150
+ LoginDisciplineName: nil,
151
+ LoginOutTime: a_value <= just_before))
152
+ .to(including(IsLoggedIn: true,
153
+ LoginCollectionName: collection[:CollectionName],
154
+ LoginDisciplineName: collection.discipline[:Name],
155
+ LoginOutTime: a_value >= just_before))
156
+ end
157
+ end
158
+
159
+ describe '#view_set_dir' do
160
+ subject { user.view_set_dir(collection) }
161
+
162
+ it do
163
+ is_expected
164
+ .to have_attributes DisciplineType: 'Invertebrate Paleontology',
165
+ IsPersonal: true,
166
+ UserType: 'manager',
167
+ collection: collection,
168
+ user: user,
169
+ discipline: collection.discipline
170
+ end
171
+ end
172
+
173
+ describe '#view_set' do
174
+ subject { user.view_set(collection) }
175
+
176
+ it do
177
+ is_expected.to have_attributes Name: 'paleo.views'
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end