berkeley_library-tind 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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