berkeley_library-tind 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/build.yml +18 -0
  3. data/.gitignore +388 -0
  4. data/.idea/inspectionProfiles/Project_Default.xml +20 -0
  5. data/.idea/misc.xml +4 -0
  6. data/.idea/modules.xml +8 -0
  7. data/.idea/tind.iml +138 -0
  8. data/.idea/vcs.xml +6 -0
  9. data/.rubocop.yml +334 -0
  10. data/.ruby-version +1 -0
  11. data/.simplecov +8 -0
  12. data/.yardopts +1 -0
  13. data/CHANGES.md +58 -0
  14. data/Dockerfile +57 -0
  15. data/Gemfile +3 -0
  16. data/Jenkinsfile +18 -0
  17. data/LICENSE.md +21 -0
  18. data/README.md +73 -0
  19. data/Rakefile +20 -0
  20. data/berkeley_library-tind.gemspec +50 -0
  21. data/bin/tind-export +14 -0
  22. data/docker-compose.yml +15 -0
  23. data/lib/berkeley_library/tind.rb +3 -0
  24. data/lib/berkeley_library/tind/api.rb +1 -0
  25. data/lib/berkeley_library/tind/api/api.rb +132 -0
  26. data/lib/berkeley_library/tind/api/api_exception.rb +131 -0
  27. data/lib/berkeley_library/tind/api/collection.rb +82 -0
  28. data/lib/berkeley_library/tind/api/date_range.rb +67 -0
  29. data/lib/berkeley_library/tind/api/format.rb +32 -0
  30. data/lib/berkeley_library/tind/api/search.rb +100 -0
  31. data/lib/berkeley_library/tind/config.rb +103 -0
  32. data/lib/berkeley_library/tind/export.rb +1 -0
  33. data/lib/berkeley_library/tind/export/column.rb +54 -0
  34. data/lib/berkeley_library/tind/export/column_group.rb +144 -0
  35. data/lib/berkeley_library/tind/export/column_group_list.rb +131 -0
  36. data/lib/berkeley_library/tind/export/column_width_calculator.rb +76 -0
  37. data/lib/berkeley_library/tind/export/config.rb +154 -0
  38. data/lib/berkeley_library/tind/export/csv_exporter.rb +29 -0
  39. data/lib/berkeley_library/tind/export/export.rb +47 -0
  40. data/lib/berkeley_library/tind/export/export_command.rb +168 -0
  41. data/lib/berkeley_library/tind/export/export_exception.rb +8 -0
  42. data/lib/berkeley_library/tind/export/export_format.rb +67 -0
  43. data/lib/berkeley_library/tind/export/exporter.rb +105 -0
  44. data/lib/berkeley_library/tind/export/filter.rb +52 -0
  45. data/lib/berkeley_library/tind/export/no_results_error.rb +7 -0
  46. data/lib/berkeley_library/tind/export/ods_exporter.rb +138 -0
  47. data/lib/berkeley_library/tind/export/row.rb +24 -0
  48. data/lib/berkeley_library/tind/export/row_metrics.rb +18 -0
  49. data/lib/berkeley_library/tind/export/table.rb +175 -0
  50. data/lib/berkeley_library/tind/export/table_metrics.rb +116 -0
  51. data/lib/berkeley_library/tind/marc.rb +1 -0
  52. data/lib/berkeley_library/tind/marc/xml_reader.rb +144 -0
  53. data/lib/berkeley_library/tind/module_info.rb +14 -0
  54. data/lib/berkeley_library/util/arrays.rb +178 -0
  55. data/lib/berkeley_library/util/logging.rb +1 -0
  56. data/lib/berkeley_library/util/ods/spreadsheet.rb +170 -0
  57. data/lib/berkeley_library/util/ods/xml/content_doc.rb +26 -0
  58. data/lib/berkeley_library/util/ods/xml/document_node.rb +57 -0
  59. data/lib/berkeley_library/util/ods/xml/element_node.rb +106 -0
  60. data/lib/berkeley_library/util/ods/xml/loext/table_protection.rb +26 -0
  61. data/lib/berkeley_library/util/ods/xml/manifest/file_entry.rb +42 -0
  62. data/lib/berkeley_library/util/ods/xml/manifest/manifest.rb +73 -0
  63. data/lib/berkeley_library/util/ods/xml/manifest_doc.rb +26 -0
  64. data/lib/berkeley_library/util/ods/xml/namespace.rb +46 -0
  65. data/lib/berkeley_library/util/ods/xml/office/automatic_styles.rb +181 -0
  66. data/lib/berkeley_library/util/ods/xml/office/body.rb +17 -0
  67. data/lib/berkeley_library/util/ods/xml/office/document_content.rb +98 -0
  68. data/lib/berkeley_library/util/ods/xml/office/document_styles.rb +39 -0
  69. data/lib/berkeley_library/util/ods/xml/office/font_face_decls.rb +30 -0
  70. data/lib/berkeley_library/util/ods/xml/office/scripts.rb +17 -0
  71. data/lib/berkeley_library/util/ods/xml/office/spreadsheet.rb +37 -0
  72. data/lib/berkeley_library/util/ods/xml/office/styles.rb +39 -0
  73. data/lib/berkeley_library/util/ods/xml/style/cell_style.rb +58 -0
  74. data/lib/berkeley_library/util/ods/xml/style/column_style.rb +36 -0
  75. data/lib/berkeley_library/util/ods/xml/style/default_style.rb +31 -0
  76. data/lib/berkeley_library/util/ods/xml/style/family.rb +85 -0
  77. data/lib/berkeley_library/util/ods/xml/style/font_face.rb +46 -0
  78. data/lib/berkeley_library/util/ods/xml/style/paragraph_properties.rb +30 -0
  79. data/lib/berkeley_library/util/ods/xml/style/row_style.rb +37 -0
  80. data/lib/berkeley_library/util/ods/xml/style/style.rb +44 -0
  81. data/lib/berkeley_library/util/ods/xml/style/table_cell_properties.rb +40 -0
  82. data/lib/berkeley_library/util/ods/xml/style/table_column_properties.rb +30 -0
  83. data/lib/berkeley_library/util/ods/xml/style/table_properties.rb +25 -0
  84. data/lib/berkeley_library/util/ods/xml/style/table_row_properties.rb +28 -0
  85. data/lib/berkeley_library/util/ods/xml/style/table_style.rb +27 -0
  86. data/lib/berkeley_library/util/ods/xml/style/text_properties.rb +52 -0
  87. data/lib/berkeley_library/util/ods/xml/styles_doc.rb +26 -0
  88. data/lib/berkeley_library/util/ods/xml/table/named_expressions.rb +17 -0
  89. data/lib/berkeley_library/util/ods/xml/table/repeatable.rb +38 -0
  90. data/lib/berkeley_library/util/ods/xml/table/table.rb +193 -0
  91. data/lib/berkeley_library/util/ods/xml/table/table_cell.rb +46 -0
  92. data/lib/berkeley_library/util/ods/xml/table/table_column.rb +43 -0
  93. data/lib/berkeley_library/util/ods/xml/table/table_row.rb +136 -0
  94. data/lib/berkeley_library/util/ods/xml/text/p.rb +118 -0
  95. data/lib/berkeley_library/util/paths.rb +111 -0
  96. data/lib/berkeley_library/util/stringios.rb +30 -0
  97. data/lib/berkeley_library/util/strings.rb +42 -0
  98. data/lib/berkeley_library/util/sys_exits.rb +15 -0
  99. data/lib/berkeley_library/util/times.rb +22 -0
  100. data/lib/berkeley_library/util/uris.rb +44 -0
  101. data/lib/berkeley_library/util/uris/appender.rb +162 -0
  102. data/lib/berkeley_library/util/uris/requester.rb +62 -0
  103. data/lib/berkeley_library/util/uris/validator.rb +32 -0
  104. data/rakelib/bundle.rake +8 -0
  105. data/rakelib/coverage.rake +11 -0
  106. data/rakelib/gem.rake +54 -0
  107. data/rakelib/rubocop.rake +18 -0
  108. data/rakelib/spec.rake +2 -0
  109. data/spec/.rubocop.yml +40 -0
  110. data/spec/berkeley_library/tind/api/api_exception_spec.rb +91 -0
  111. data/spec/berkeley_library/tind/api/api_spec.rb +143 -0
  112. data/spec/berkeley_library/tind/api/collection_spec.rb +74 -0
  113. data/spec/berkeley_library/tind/api/date_range_spec.rb +110 -0
  114. data/spec/berkeley_library/tind/api/format_spec.rb +54 -0
  115. data/spec/berkeley_library/tind/api/search_spec.rb +364 -0
  116. data/spec/berkeley_library/tind/config_spec.rb +86 -0
  117. data/spec/berkeley_library/tind/export/column_group_spec.rb +29 -0
  118. data/spec/berkeley_library/tind/export/column_spec.rb +43 -0
  119. data/spec/berkeley_library/tind/export/config_spec.rb +206 -0
  120. data/spec/berkeley_library/tind/export/export_command_spec.rb +169 -0
  121. data/spec/berkeley_library/tind/export/export_format_spec.rb +59 -0
  122. data/spec/berkeley_library/tind/export/export_matcher.rb +112 -0
  123. data/spec/berkeley_library/tind/export/export_spec.rb +150 -0
  124. data/spec/berkeley_library/tind/export/exporter_spec.rb +125 -0
  125. data/spec/berkeley_library/tind/export/row_spec.rb +118 -0
  126. data/spec/berkeley_library/tind/export/table_spec.rb +322 -0
  127. data/spec/berkeley_library/tind/marc/xml_reader_spec.rb +93 -0
  128. data/spec/berkeley_library/util/arrays_spec.rb +340 -0
  129. data/spec/berkeley_library/util/ods/spreadsheet_spec.rb +124 -0
  130. data/spec/berkeley_library/util/ods/xml/content_doc_spec.rb +121 -0
  131. data/spec/berkeley_library/util/ods/xml/manifest/file_entry_spec.rb +27 -0
  132. data/spec/berkeley_library/util/ods/xml/manifest/manifest_spec.rb +33 -0
  133. data/spec/berkeley_library/util/ods/xml/office/document_content_spec.rb +60 -0
  134. data/spec/berkeley_library/util/ods/xml/style/automatic_styles_spec.rb +37 -0
  135. data/spec/berkeley_library/util/ods/xml/style/family_spec.rb +57 -0
  136. data/spec/berkeley_library/util/ods/xml/table/table_row_spec.rb +179 -0
  137. data/spec/berkeley_library/util/ods/xml/table/table_spec.rb +218 -0
  138. data/spec/berkeley_library/util/paths_spec.rb +90 -0
  139. data/spec/berkeley_library/util/stringios_spec.rb +34 -0
  140. data/spec/berkeley_library/util/strings_spec.rb +27 -0
  141. data/spec/berkeley_library/util/times_spec.rb +39 -0
  142. data/spec/berkeley_library/util/uris_spec.rb +118 -0
  143. data/spec/data/collection-names.txt +438 -0
  144. data/spec/data/collections.json +4827 -0
  145. data/spec/data/disjoint-records.xml +187 -0
  146. data/spec/data/record-184453.xml +58 -0
  147. data/spec/data/record-184458.xml +63 -0
  148. data/spec/data/record-187888.xml +78 -0
  149. data/spec/data/records-api-search-cjk-p1.xml +6381 -0
  150. data/spec/data/records-api-search-cjk-p2.xml +5 -0
  151. data/spec/data/records-api-search-p1.xml +4506 -0
  152. data/spec/data/records-api-search-p2.xml +4509 -0
  153. data/spec/data/records-api-search-p3.xml +4506 -0
  154. data/spec/data/records-api-search-p4.xml +4509 -0
  155. data/spec/data/records-api-search-p5.xml +4506 -0
  156. data/spec/data/records-api-search-p6.xml +2436 -0
  157. data/spec/data/records-api-search-p7.xml +5 -0
  158. data/spec/data/records-api-search.xml +234 -0
  159. data/spec/data/records-manual-search.xml +547 -0
  160. data/spec/spec_helper.rb +30 -0
  161. data/test/profile/table_from_records_profile.rb +46 -0
  162. metadata +585 -0
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module TIND
5
+ describe Config do
6
+ let(:env_base_url) { 'tind.example.edu' }
7
+ let(:env_api_key) { 'not-a-real-api-key' }
8
+
9
+ before(:each) do
10
+ @base_uri_orig = Config.instance_variable_get(:@base_uri)
11
+ Config.instance_variable_set(:@base_uri, nil)
12
+
13
+ @base_url_orig = ENV['LIT_TIND_BASE_URL']
14
+ ENV['LIT_TIND_BASE_URL'] = env_base_url
15
+
16
+ @api_key_orig = Config.instance_variable_get(:@api_key)
17
+ Config.instance_variable_set(:@api_key, nil)
18
+
19
+ @api_key_env_orig = ENV['LIT_TIND_API_KEY']
20
+ ENV['LIT_TIND_API_KEY'] = env_api_key
21
+ end
22
+
23
+ after(:each) do
24
+ Config.instance_variable_set(:@base_uri, @base_uri_orig)
25
+ ENV['LIT_TIND_BASE_URL'] = @base_url_orig
26
+
27
+ Config.api_key = @api_key_orig
28
+ ENV['LIT_TIND_API_KEY'] = @api_key_env_orig
29
+ end
30
+
31
+ describe :base_uri do
32
+ it 'returns the base URL from the environment as a URI' do
33
+ expect(Config.base_uri).to eq(URI(env_base_url))
34
+ end
35
+
36
+ it 'returns nil if no base URL is set in the environment' do
37
+ ENV['LIT_TIND_BASE_URL'] = nil
38
+ expect(Config.base_uri).to be_nil
39
+ end
40
+
41
+ it 'returns a URI from Rails config if present' do
42
+ expect(defined?(Rails)).to be_nil
43
+
44
+ Object.send(:const_set, 'Rails', OpenStruct.new)
45
+ Rails.application = OpenStruct.new
46
+
47
+ url = 'tind-test.example.edu'
48
+ config = OpenStruct.new(tind_base_uri: url)
49
+ Rails.application.config = config
50
+
51
+ ENV['LIT_TIND_BASE_URL'] = nil
52
+ expect(Config.base_uri).to eq(URI(url))
53
+ ensure
54
+ Object.send(:remove_const, 'Rails')
55
+ end
56
+ end
57
+
58
+ describe :api_key do
59
+ it 'returns the API key from the environment' do
60
+ expect(Config.api_key).to eq(env_api_key)
61
+ end
62
+
63
+ it 'returns nil if no API key is set in the environment' do
64
+ ENV['LIT_TIND_API_KEY'] = nil
65
+ expect(Config.api_key).to be_nil
66
+ end
67
+
68
+ it 'returns an API key from the Rails config if present' do
69
+ expect(defined?(Rails)).to be_nil
70
+
71
+ Object.send(:const_set, 'Rails', OpenStruct.new)
72
+ Rails.application = OpenStruct.new
73
+
74
+ api_key = 'test-api-key'
75
+ config = OpenStruct.new(tind_api_key: api_key)
76
+ Rails.application.config = config
77
+
78
+ ENV['LIT_TIND_API_KEY'] = nil
79
+ expect(Config.api_key).to eq(api_key)
80
+ ensure
81
+ Object.send(:remove_const, 'Rails')
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module TIND
5
+ module Export
6
+ describe ColumnGroup do
7
+ describe :new do
8
+ it 'rejects invalid indicators' do
9
+ expect { ColumnGroup.new('856', 0, '_', '2', 'uyz'.chars) }.to raise_error(ArgumentError)
10
+ expect { ColumnGroup.new('856', 0, '2', '_', 'uyz'.chars) }.to raise_error(ArgumentError)
11
+ end
12
+
13
+ it "allows capital indicators, even if it shouldn't" do
14
+ cg = ColumnGroup.new('856', 0, 'Q', '1', 'uyz'.chars)
15
+ expect(cg.ind1).to eq('Q')
16
+ end
17
+ end
18
+ describe :to_s do
19
+ it 'returns the prefix + subfield codes' do
20
+ cg = ColumnGroup.new('856', 0, '4', '2', 'uyz'.chars)
21
+ cg_str = cg.to_s
22
+ expect(cg_str).to include('85642uyz')
23
+ expect(cg_str).to include('0')
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module TIND
5
+ module Export
6
+ describe Column do
7
+ describe :each_value do
8
+ let(:values) { %w[a b c d] }
9
+ attr_reader :col
10
+
11
+ before(:each) do
12
+ cg = instance_double(ColumnGroup)
13
+ allow(cg).to receive(:row_count).and_return(values.size)
14
+ allow(cg).to receive(:value_at) { |r, _| values[r] }
15
+ allow(cg).to receive(:prefix).and_return('99999')
16
+ allow(cg).to receive(:index_in_tag).and_return(9)
17
+ allow(cg).to receive(:subfield_codes).and_return(['9'])
18
+ @col = Column.new(cg, 0)
19
+ end
20
+
21
+ it 'yields each value' do
22
+ actual = [].tap do |vv|
23
+ col.each_value { |v| vv << v }
24
+ end
25
+ expect(actual).to eq(values)
26
+ end
27
+
28
+ it 'returns an enumerator' do
29
+ enum = col.each_value
30
+ expect(enum.to_a).to eq(values)
31
+ end
32
+
33
+ it 'optionally returns the header' do
34
+ enum = col.each_value(include_header: true)
35
+ enum_values = enum.to_a
36
+ expect(enum_values[0]).to eq(col.header)
37
+ expect(enum_values[1..]).to eq(values)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,206 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module TIND
5
+ module Export
6
+ describe Config do
7
+ let(:env_vars) do
8
+ %w[
9
+ ODS_FONT_SIZE_DEFAULT
10
+ ODS_FORMAT_DIGITS_DEFAULT
11
+ ODS_HEIGHT_INCREMENT_DEFAULT_POINTS
12
+ ODS_LINE_HEIGHT_DEFAULT_EM
13
+ ODS_MAX_COLUMN_WIDTH_INCHES
14
+ ODS_WIDTH_INCREMENT_DEFAULT_INCHES
15
+ ]
16
+ end
17
+
18
+ let(:attrs) do
19
+ %i[
20
+ font_size_pt
21
+ format_digits
22
+ h_incr_pt
23
+ line_height_em
24
+ max_col_width_in
25
+ w_incr_in
26
+ ]
27
+ end
28
+
29
+ let(:inst_vars) { attrs.map { |a| "@#{a}".to_sym } }
30
+
31
+ before(:each) do
32
+ @env_orig = {}
33
+ env_vars.each do |v|
34
+ @env_orig[v] = ENV[v]
35
+ ENV[v] = nil
36
+ end
37
+ @inst_orig = {}
38
+ inst_vars.each do |v|
39
+ if Config.instance_variable_defined?(v)
40
+ @inst_orig[v] = Config.instance_variable_get(v)
41
+ Config.remove_instance_variable(v)
42
+ end
43
+ end
44
+ end
45
+
46
+ after(:each) do
47
+ @env_orig.each do |k, v|
48
+ ENV[k] = v
49
+ end
50
+ @inst_orig.each do |k, v|
51
+ Config.instance_variable_set(k, v)
52
+ end
53
+ end
54
+
55
+ describe 'defaults' do
56
+ it 'returns sensible default values' do
57
+ expected = {
58
+ font_size_pt: Config::FONT_SIZE_DEFAULT,
59
+ max_col_width_in: Config::MAX_COLUMN_WIDTH_INCHES,
60
+ w_incr_in: Config::WIDTH_INCREMENT_DEFAULT_INCHES,
61
+ h_incr_pt: Config::HEIGHT_INCREMENT_DEFAULT_POINTS,
62
+ line_height_em: Config::LINE_HEIGHT_DEFAULT_EM,
63
+ format_digits: Config::FORMAT_DIGITS_DEFAULT
64
+ }
65
+ expected.each do |attr, value|
66
+ expect(Config.send(attr)).to eq(value)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'ENV' do
72
+ it 'can be configured from the environment' do
73
+ env_vars_by_attr = {
74
+ font_size_pt: 'ODS_FONT_SIZE_DEFAULT',
75
+ max_col_width_in: 'ODS_MAX_COLUMN_WIDTH_INCHES',
76
+ w_incr_in: 'ODS_WIDTH_INCREMENT_DEFAULT_INCHES',
77
+ h_incr_pt: 'ODS_HEIGHT_INCREMENT_DEFAULT_POINTS',
78
+ line_height_em: 'ODS_LINE_HEIGHT_DEFAULT_EM',
79
+ format_digits: 'ODS_FORMAT_DIGITS_DEFAULT'
80
+ }
81
+
82
+ expected = env_vars_by_attr.map do |attr, var|
83
+ value = 2 * Config.send(attr)
84
+ ENV[var] = value.to_s
85
+ [attr, value]
86
+ end.to_h
87
+
88
+ inst_vars.each do |v|
89
+ Config.remove_instance_variable(v) if Config.instance_variable_defined?(v)
90
+ end
91
+
92
+ expected.each do |attr, value|
93
+ expect(Config.send(attr)).to eq(value)
94
+ end
95
+ end
96
+ end
97
+
98
+ describe 'setters' do
99
+ let(:attr_nonint) { attrs - [:format_digits] }
100
+
101
+ it 'set the attributes' do
102
+ attrs.each do |attr|
103
+ value = 2 * Config.send(attr)
104
+ Config.send("#{attr}=", value)
105
+ expect(Config.send(attr)).to eq(value)
106
+ end
107
+ end
108
+
109
+ it 'accepts integers' do
110
+ attrs.each do |attr|
111
+ value = (2 * Config.send(attr)).ceil
112
+ Config.send("#{attr}=", value)
113
+ expect(Config.send(attr)).to eq(value)
114
+ end
115
+ end
116
+
117
+ it 'accepts integers as strings' do
118
+ attrs.each do |attr|
119
+ value = (2 * Config.send(attr)).ceil
120
+ Config.send("#{attr}=", value.to_s)
121
+ expect(Config.send(attr)).to eq(value)
122
+ end
123
+ end
124
+
125
+ it 'rejects non-numeric values' do
126
+ attrs.each do |attr|
127
+ value = Config.send(attr)
128
+ expect { Config.send("#{attr}=", 'not a number') }.to raise_error(ArgumentError)
129
+ expect(Config.send(attr)).to eq(value)
130
+ end
131
+ end
132
+
133
+ it 'rejects negative values' do
134
+ attrs.each do |attr|
135
+ value = Config.send(attr)
136
+ expect { Config.send("#{attr}=", -value) }.to raise_error(ArgumentError)
137
+ expect(Config.send(attr)).to eq(value)
138
+ end
139
+ end
140
+
141
+ it 'rejects zero' do
142
+ attrs.each do |attr|
143
+ value = Config.send(attr)
144
+ expect { Config.send("#{attr}=", 0) }.to raise_error(ArgumentError)
145
+ expect(Config.send(attr)).to eq(value)
146
+ end
147
+ end
148
+
149
+ describe :format_digits do
150
+ it 'rejects non-integer numeric values' do
151
+ value = Config.format_digits
152
+ [2.3, '3/5'.to_r].each do |bad_value|
153
+ expect { Config.format_digits = bad_value }.to raise_error(ArgumentError)
154
+ end
155
+ expect(Config.format_digits).to eq(value)
156
+ end
157
+
158
+ it 'accepts hex strings' do
159
+ Config.format_digits = '0xba0bab'
160
+ expect(Config.format_digits).to eq(12_192_683)
161
+ end
162
+
163
+ it 'accepts octal strings' do
164
+ Config.format_digits = '0123'
165
+ expect(Config.format_digits).to eq(83)
166
+ end
167
+ end
168
+
169
+ describe 'non-integer attributes' do
170
+ it 'accepts rationals' do
171
+ attr_nonint.each do |attr|
172
+ value = (2 * Config.send(attr)).to_r
173
+ Config.send("#{attr}=", value)
174
+ expect(Config.send(attr)).to eq(value)
175
+ end
176
+ end
177
+
178
+ it 'accepts floats' do
179
+ attr_nonint.each do |attr|
180
+ value = (2 * Config.send(attr)).to_f
181
+ Config.send("#{attr}=", value)
182
+ expect(Config.send(attr)).to eq(value)
183
+ end
184
+ end
185
+
186
+ it 'accepts rationals as strings' do
187
+ attr_nonint.each do |attr|
188
+ value = (2 * Config.send(attr)).to_r
189
+ Config.send("#{attr}=", value.to_s)
190
+ expect(Config.send(attr)).to eq(value)
191
+ end
192
+ end
193
+
194
+ it 'accepts floats as strings' do
195
+ attr_nonint.each do |attr|
196
+ value = (2 * Config.send(attr)).to_f
197
+ Config.send("#{attr}=", value.to_s)
198
+ expect(Config.send(attr)).to eq(value)
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+ require 'fileutils'
3
+
4
+ module BerkeleyLibrary
5
+ module TIND
6
+ module Export
7
+ describe ExportCommand do
8
+ before(:each) do
9
+ @base_uri_orig = BerkeleyLibrary::TIND::Config.base_uri
10
+ @api_key_orig = BerkeleyLibrary::TIND::Config.api_key
11
+ @logger_orig = BerkeleyLibrary::Logging.logger
12
+ end
13
+
14
+ after(:each) do
15
+ BerkeleyLibrary::Logging.logger = @logger_orig
16
+ BerkeleyLibrary::TIND::Config.api_key = @api_key_orig
17
+ BerkeleyLibrary::TIND::Config.base_uri = @base_uri_orig
18
+ end
19
+
20
+ describe :usage do
21
+ it 'returns the usage' do
22
+ expect(ExportCommand.send(:usage)).to be_a(String)
23
+ end
24
+ end
25
+
26
+ describe :list_collections do
27
+ it 'lists the collection names' do
28
+ collections = BerkeleyLibrary::TIND::API::Collection.all_from_json(File.read('spec/data/collections.json'))
29
+ allow(BerkeleyLibrary::TIND::API::Collection).to receive(:all).and_return(collections)
30
+
31
+ out = StringIO.new
32
+ ExportCommand.new('-l', out: out).execute!
33
+ # TODO: test counts
34
+ names_only = out.string.gsub!(/^[0-9]+\t/, '')
35
+ expect(names_only).to eq(File.read('spec/data/collection-names.txt'))
36
+ end
37
+ end
38
+
39
+ describe :export_collection do
40
+ it 'exports a collection' do
41
+ format = 'csv'
42
+ collection = 'Bancroft Library'
43
+ out = instance_double(IO)
44
+
45
+ expect(BerkeleyLibrary::TIND::Export).to receive(:export).with(collection, ExportFormat.ensure_format(format), out)
46
+ ExportCommand.new('-f', format, collection, out: out).execute!
47
+ end
48
+ end
49
+
50
+ describe 'flags' do
51
+ let(:api_key) { 'ZghOT0eRm4U9s' }
52
+ let(:output_path) { '/tmp/export.ods' }
53
+ let(:collection) { 'Houcun ju shi ji' }
54
+
55
+ attr_reader :command
56
+
57
+ before(:each) do
58
+ @command = ExportCommand.new('-v', '-k', api_key, '-o', output_path, collection)
59
+ end
60
+
61
+ describe '-e' do
62
+ let(:basename) { File.basename(__FILE__, '.rb') }
63
+
64
+ before(:each) do
65
+ @wd = Dir.pwd
66
+
67
+ if defined?(Dotenv)
68
+ @dotenv_old = Dotenv
69
+ Object.send(:remove_const, :Dotenv)
70
+ end
71
+
72
+ allow_any_instance_of(Kernel).to receive(:require).with('dotenv').and_return(true)
73
+ Object.const_set(:Dotenv, double(Module))
74
+ end
75
+
76
+ after(:each) do
77
+ Dir.chdir(@wd)
78
+ next unless @dotenv_old
79
+
80
+ Object.send(:remove_const, :Dotenv)
81
+ Object.const_set(:Dotenv, @dotenv_old)
82
+ end
83
+
84
+ it 'reads the default .env file' do
85
+ Dir.mktmpdir(basename) do |tmpdir|
86
+ env_path = File.join(tmpdir, '.env')
87
+ FileUtils.touch(env_path)
88
+
89
+ env_path_abs = File.realpath(env_path)
90
+ expect(Dotenv).to receive(:load).with(env_path_abs)
91
+ Dir.chdir(tmpdir)
92
+ ExportCommand.new('-l', '-e')
93
+ end
94
+ end
95
+
96
+ it 'reads a specified .env file' do
97
+ Dir.mktmpdir(basename) do |tmpdir|
98
+ env_path = File.join(tmpdir, 'myenv')
99
+ FileUtils.touch(env_path)
100
+
101
+ env_path_abs = File.realpath(env_path)
102
+ expect(Dotenv).to receive(:load).with(env_path_abs)
103
+ Dir.chdir(tmpdir)
104
+ ExportCommand.new('-l', '-e', 'myenv')
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '-v' do
110
+ it 'configures a debug-level logger' do
111
+ expect(BerkeleyLibrary::Logging.logger.level).to eq(0)
112
+ end
113
+ end
114
+
115
+ describe '-k' do
116
+ it 'sets the API key' do
117
+ expect(BerkeleyLibrary::TIND::API.api_key).to eq(api_key)
118
+ end
119
+ end
120
+
121
+ describe '-o' do
122
+ it 'sets the output file and format' do
123
+ expect(command.options[:outfile]).to eq(output_path)
124
+ expect(command.options[:format]).to eq(ExportFormat::ODS)
125
+ end
126
+ end
127
+
128
+ it 'sets the collection' do
129
+ expect(command.options[:collection]).to eq(collection)
130
+ end
131
+ end
132
+
133
+ describe 'error handling' do
134
+ it 'prints usage and exits if given bad options' do
135
+ stderr_orig = $stderr
136
+ begin
137
+ out = StringIO.new
138
+ $stderr = out
139
+ expect { ExportCommand.new('-not', '-a', '-valid', '-option') }.to raise_error(SystemExit) do |e|
140
+ expect(e.status).not_to eq(0)
141
+ end
142
+ expected_usage = ExportCommand.send(:usage)
143
+ expect(out.string).to include(expected_usage)
144
+ ensure
145
+ $stderr = stderr_orig
146
+ end
147
+ end
148
+
149
+ it 'prints usage and exits in the event of an error' do
150
+ err_class = BerkeleyLibrary::TIND::API::APIException
151
+ err_msg = '403 Forbidden'
152
+ expect(BerkeleyLibrary::TIND::Export).to receive(:export).and_raise(err_class, err_msg)
153
+ stderr_orig = $stderr
154
+ begin
155
+ out = StringIO.new
156
+ $stderr = out
157
+ expect { ExportCommand.new('Bancroft Library').execute! }.to raise_error(SystemExit) do |e|
158
+ expect(e.status).not_to eq(0)
159
+ end
160
+ expect(out.string).to include(err_msg)
161
+ ensure
162
+ $stderr = stderr_orig
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end