berkeley_library-tind 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/build.yml +18 -0
- data/.gitignore +388 -0
- data/.idea/inspectionProfiles/Project_Default.xml +20 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/tind.iml +138 -0
- data/.idea/vcs.xml +6 -0
- data/.rubocop.yml +334 -0
- data/.ruby-version +1 -0
- data/.simplecov +8 -0
- data/.yardopts +1 -0
- data/CHANGES.md +58 -0
- data/Dockerfile +57 -0
- data/Gemfile +3 -0
- data/Jenkinsfile +18 -0
- data/LICENSE.md +21 -0
- data/README.md +73 -0
- data/Rakefile +20 -0
- data/berkeley_library-tind.gemspec +50 -0
- data/bin/tind-export +14 -0
- data/docker-compose.yml +15 -0
- data/lib/berkeley_library/tind.rb +3 -0
- data/lib/berkeley_library/tind/api.rb +1 -0
- data/lib/berkeley_library/tind/api/api.rb +132 -0
- data/lib/berkeley_library/tind/api/api_exception.rb +131 -0
- data/lib/berkeley_library/tind/api/collection.rb +82 -0
- data/lib/berkeley_library/tind/api/date_range.rb +67 -0
- data/lib/berkeley_library/tind/api/format.rb +32 -0
- data/lib/berkeley_library/tind/api/search.rb +100 -0
- data/lib/berkeley_library/tind/config.rb +103 -0
- data/lib/berkeley_library/tind/export.rb +1 -0
- data/lib/berkeley_library/tind/export/column.rb +54 -0
- data/lib/berkeley_library/tind/export/column_group.rb +144 -0
- data/lib/berkeley_library/tind/export/column_group_list.rb +131 -0
- data/lib/berkeley_library/tind/export/column_width_calculator.rb +76 -0
- data/lib/berkeley_library/tind/export/config.rb +154 -0
- data/lib/berkeley_library/tind/export/csv_exporter.rb +29 -0
- data/lib/berkeley_library/tind/export/export.rb +47 -0
- data/lib/berkeley_library/tind/export/export_command.rb +168 -0
- data/lib/berkeley_library/tind/export/export_exception.rb +8 -0
- data/lib/berkeley_library/tind/export/export_format.rb +67 -0
- data/lib/berkeley_library/tind/export/exporter.rb +105 -0
- data/lib/berkeley_library/tind/export/filter.rb +52 -0
- data/lib/berkeley_library/tind/export/no_results_error.rb +7 -0
- data/lib/berkeley_library/tind/export/ods_exporter.rb +138 -0
- data/lib/berkeley_library/tind/export/row.rb +24 -0
- data/lib/berkeley_library/tind/export/row_metrics.rb +18 -0
- data/lib/berkeley_library/tind/export/table.rb +175 -0
- data/lib/berkeley_library/tind/export/table_metrics.rb +116 -0
- data/lib/berkeley_library/tind/marc.rb +1 -0
- data/lib/berkeley_library/tind/marc/xml_reader.rb +144 -0
- data/lib/berkeley_library/tind/module_info.rb +14 -0
- data/lib/berkeley_library/util/arrays.rb +178 -0
- data/lib/berkeley_library/util/logging.rb +1 -0
- data/lib/berkeley_library/util/ods/spreadsheet.rb +170 -0
- data/lib/berkeley_library/util/ods/xml/content_doc.rb +26 -0
- data/lib/berkeley_library/util/ods/xml/document_node.rb +57 -0
- data/lib/berkeley_library/util/ods/xml/element_node.rb +106 -0
- data/lib/berkeley_library/util/ods/xml/loext/table_protection.rb +26 -0
- data/lib/berkeley_library/util/ods/xml/manifest/file_entry.rb +42 -0
- data/lib/berkeley_library/util/ods/xml/manifest/manifest.rb +73 -0
- data/lib/berkeley_library/util/ods/xml/manifest_doc.rb +26 -0
- data/lib/berkeley_library/util/ods/xml/namespace.rb +46 -0
- data/lib/berkeley_library/util/ods/xml/office/automatic_styles.rb +181 -0
- data/lib/berkeley_library/util/ods/xml/office/body.rb +17 -0
- data/lib/berkeley_library/util/ods/xml/office/document_content.rb +98 -0
- data/lib/berkeley_library/util/ods/xml/office/document_styles.rb +39 -0
- data/lib/berkeley_library/util/ods/xml/office/font_face_decls.rb +30 -0
- data/lib/berkeley_library/util/ods/xml/office/scripts.rb +17 -0
- data/lib/berkeley_library/util/ods/xml/office/spreadsheet.rb +37 -0
- data/lib/berkeley_library/util/ods/xml/office/styles.rb +39 -0
- data/lib/berkeley_library/util/ods/xml/style/cell_style.rb +58 -0
- data/lib/berkeley_library/util/ods/xml/style/column_style.rb +36 -0
- data/lib/berkeley_library/util/ods/xml/style/default_style.rb +31 -0
- data/lib/berkeley_library/util/ods/xml/style/family.rb +85 -0
- data/lib/berkeley_library/util/ods/xml/style/font_face.rb +46 -0
- data/lib/berkeley_library/util/ods/xml/style/paragraph_properties.rb +30 -0
- data/lib/berkeley_library/util/ods/xml/style/row_style.rb +37 -0
- data/lib/berkeley_library/util/ods/xml/style/style.rb +44 -0
- data/lib/berkeley_library/util/ods/xml/style/table_cell_properties.rb +40 -0
- data/lib/berkeley_library/util/ods/xml/style/table_column_properties.rb +30 -0
- data/lib/berkeley_library/util/ods/xml/style/table_properties.rb +25 -0
- data/lib/berkeley_library/util/ods/xml/style/table_row_properties.rb +28 -0
- data/lib/berkeley_library/util/ods/xml/style/table_style.rb +27 -0
- data/lib/berkeley_library/util/ods/xml/style/text_properties.rb +52 -0
- data/lib/berkeley_library/util/ods/xml/styles_doc.rb +26 -0
- data/lib/berkeley_library/util/ods/xml/table/named_expressions.rb +17 -0
- data/lib/berkeley_library/util/ods/xml/table/repeatable.rb +38 -0
- data/lib/berkeley_library/util/ods/xml/table/table.rb +193 -0
- data/lib/berkeley_library/util/ods/xml/table/table_cell.rb +46 -0
- data/lib/berkeley_library/util/ods/xml/table/table_column.rb +43 -0
- data/lib/berkeley_library/util/ods/xml/table/table_row.rb +136 -0
- data/lib/berkeley_library/util/ods/xml/text/p.rb +118 -0
- data/lib/berkeley_library/util/paths.rb +111 -0
- data/lib/berkeley_library/util/stringios.rb +30 -0
- data/lib/berkeley_library/util/strings.rb +42 -0
- data/lib/berkeley_library/util/sys_exits.rb +15 -0
- data/lib/berkeley_library/util/times.rb +22 -0
- data/lib/berkeley_library/util/uris.rb +44 -0
- data/lib/berkeley_library/util/uris/appender.rb +162 -0
- data/lib/berkeley_library/util/uris/requester.rb +62 -0
- data/lib/berkeley_library/util/uris/validator.rb +32 -0
- data/rakelib/bundle.rake +8 -0
- data/rakelib/coverage.rake +11 -0
- data/rakelib/gem.rake +54 -0
- data/rakelib/rubocop.rake +18 -0
- data/rakelib/spec.rake +2 -0
- data/spec/.rubocop.yml +40 -0
- data/spec/berkeley_library/tind/api/api_exception_spec.rb +91 -0
- data/spec/berkeley_library/tind/api/api_spec.rb +143 -0
- data/spec/berkeley_library/tind/api/collection_spec.rb +74 -0
- data/spec/berkeley_library/tind/api/date_range_spec.rb +110 -0
- data/spec/berkeley_library/tind/api/format_spec.rb +54 -0
- data/spec/berkeley_library/tind/api/search_spec.rb +364 -0
- data/spec/berkeley_library/tind/config_spec.rb +86 -0
- data/spec/berkeley_library/tind/export/column_group_spec.rb +29 -0
- data/spec/berkeley_library/tind/export/column_spec.rb +43 -0
- data/spec/berkeley_library/tind/export/config_spec.rb +206 -0
- data/spec/berkeley_library/tind/export/export_command_spec.rb +169 -0
- data/spec/berkeley_library/tind/export/export_format_spec.rb +59 -0
- data/spec/berkeley_library/tind/export/export_matcher.rb +112 -0
- data/spec/berkeley_library/tind/export/export_spec.rb +150 -0
- data/spec/berkeley_library/tind/export/exporter_spec.rb +125 -0
- data/spec/berkeley_library/tind/export/row_spec.rb +118 -0
- data/spec/berkeley_library/tind/export/table_spec.rb +322 -0
- data/spec/berkeley_library/tind/marc/xml_reader_spec.rb +93 -0
- data/spec/berkeley_library/util/arrays_spec.rb +340 -0
- data/spec/berkeley_library/util/ods/spreadsheet_spec.rb +124 -0
- data/spec/berkeley_library/util/ods/xml/content_doc_spec.rb +121 -0
- data/spec/berkeley_library/util/ods/xml/manifest/file_entry_spec.rb +27 -0
- data/spec/berkeley_library/util/ods/xml/manifest/manifest_spec.rb +33 -0
- data/spec/berkeley_library/util/ods/xml/office/document_content_spec.rb +60 -0
- data/spec/berkeley_library/util/ods/xml/style/automatic_styles_spec.rb +37 -0
- data/spec/berkeley_library/util/ods/xml/style/family_spec.rb +57 -0
- data/spec/berkeley_library/util/ods/xml/table/table_row_spec.rb +179 -0
- data/spec/berkeley_library/util/ods/xml/table/table_spec.rb +218 -0
- data/spec/berkeley_library/util/paths_spec.rb +90 -0
- data/spec/berkeley_library/util/stringios_spec.rb +34 -0
- data/spec/berkeley_library/util/strings_spec.rb +27 -0
- data/spec/berkeley_library/util/times_spec.rb +39 -0
- data/spec/berkeley_library/util/uris_spec.rb +118 -0
- data/spec/data/collection-names.txt +438 -0
- data/spec/data/collections.json +4827 -0
- data/spec/data/disjoint-records.xml +187 -0
- data/spec/data/record-184453.xml +58 -0
- data/spec/data/record-184458.xml +63 -0
- data/spec/data/record-187888.xml +78 -0
- data/spec/data/records-api-search-cjk-p1.xml +6381 -0
- data/spec/data/records-api-search-cjk-p2.xml +5 -0
- data/spec/data/records-api-search-p1.xml +4506 -0
- data/spec/data/records-api-search-p2.xml +4509 -0
- data/spec/data/records-api-search-p3.xml +4506 -0
- data/spec/data/records-api-search-p4.xml +4509 -0
- data/spec/data/records-api-search-p5.xml +4506 -0
- data/spec/data/records-api-search-p6.xml +2436 -0
- data/spec/data/records-api-search-p7.xml +5 -0
- data/spec/data/records-api-search.xml +234 -0
- data/spec/data/records-manual-search.xml +547 -0
- data/spec/spec_helper.rb +30 -0
- data/test/profile/table_from_records_profile.rb +46 -0
- metadata +585 -0
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'rexml/document'
|
4
|
+
|
5
|
+
module BerkeleyLibrary
|
6
|
+
module Util
|
7
|
+
module ODS
|
8
|
+
module XML
|
9
|
+
describe ContentDoc do
|
10
|
+
let(:content) { ContentDoc.new }
|
11
|
+
|
12
|
+
describe :document_content do
|
13
|
+
it 'returns a DocumentContent' do
|
14
|
+
expect(content.document_content).to be_a(Office::DocumentContent)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe :to_xml do
|
19
|
+
attr_reader :doc, :root
|
20
|
+
|
21
|
+
before(:each) do
|
22
|
+
xml_str = content.to_xml
|
23
|
+
@doc = REXML::Document.new(xml_str)
|
24
|
+
@root = doc.root
|
25
|
+
end
|
26
|
+
|
27
|
+
describe :root do
|
28
|
+
|
29
|
+
it 'is a <document-content/> element' do
|
30
|
+
expect(root).to be_a(REXML::Element)
|
31
|
+
expect(root.prefix).to eq('office')
|
32
|
+
expect(root.name).to eq('document-content')
|
33
|
+
expect(root.namespace).to eq('urn:oasis:names:tc:opendocument:xmlns:office:1.0')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'includes all namespaces' do
|
37
|
+
aggregate_failures('namespaces') do
|
38
|
+
Office::DocumentContent::REQUIRED_NAMESPACES.each do |ns|
|
39
|
+
expect(root["xmlns:#{ns.prefix}"]).to eq(ns.uri)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '<scripts/>' do
|
45
|
+
it 'includes a <scripts/> element' do
|
46
|
+
elem = root.elements[1]
|
47
|
+
expect(elem).to be_a(REXML::Element)
|
48
|
+
expect(elem.prefix).to eq('office')
|
49
|
+
expect(elem.name).to eq('scripts')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '<font-face-decls/>' do
|
54
|
+
attr_reader :decls
|
55
|
+
|
56
|
+
before(:each) do
|
57
|
+
@decls = root.elements[2]
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'includes a <font-face-decls/> element' do
|
61
|
+
expect(decls).to be_a(REXML::Element)
|
62
|
+
expect(decls.prefix).to eq('office')
|
63
|
+
expect(decls.name).to eq('font-face-decls')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'includes the default font face' do
|
67
|
+
face = decls.elements[1]
|
68
|
+
expect(face).to be_a(REXML::Element)
|
69
|
+
expect(face.prefix).to eq('style')
|
70
|
+
expect(face.name).to eq('font-face')
|
71
|
+
|
72
|
+
expected_face = Style::FontFace::DEFAULT_FONT_FACE
|
73
|
+
|
74
|
+
expect(face['style:name']).to eq(expected_face)
|
75
|
+
expect(face['svg:font-family']).to eq("'#{expected_face}'")
|
76
|
+
expect(face['style:font-family-generic']).to eq('swiss')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '<automatic-styles/>' do
|
81
|
+
attr_reader :styles
|
82
|
+
|
83
|
+
before(:each) do
|
84
|
+
@styles = root.elements[3]
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'includes an <automatic-styles/> element' do
|
88
|
+
expect(styles).to be_a(REXML::Element)
|
89
|
+
expect(styles.prefix).to eq('office')
|
90
|
+
expect(styles.name).to eq('automatic-styles')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '<body/>' do
|
95
|
+
attr_reader :body
|
96
|
+
|
97
|
+
before(:each) do
|
98
|
+
@body = root.elements[4]
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'includes a <body/> element' do
|
102
|
+
expect(body).to be_a(REXML::Element)
|
103
|
+
expect(body.prefix).to eq('office')
|
104
|
+
expect(body.name).to eq('body')
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'includes a <spreadsheet/> element' do
|
108
|
+
spreadsheet = body.elements[1]
|
109
|
+
expect(spreadsheet).to be_a(REXML::Element)
|
110
|
+
expect(spreadsheet.prefix).to eq('office')
|
111
|
+
expect(spreadsheet.name).to eq('spreadsheet')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Manifest
|
8
|
+
describe FileEntry do
|
9
|
+
let(:doc) { Nokogiri::XML::Document.new }
|
10
|
+
let(:manifest) { Manifest.new(doc: doc) }
|
11
|
+
|
12
|
+
describe :new do
|
13
|
+
it 'guesses the media type' do
|
14
|
+
entry = FileEntry.new('foo.xml', manifest: manifest)
|
15
|
+
expect(entry.media_type).to eq('text/xml')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'rejects unknown types' do
|
19
|
+
expect { FileEntry.new('foo.bar', manifest: manifest) }.to raise_error(ArgumentError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Manifest
|
8
|
+
describe Manifest do
|
9
|
+
let(:doc) { Nokogiri::XML::Document.new }
|
10
|
+
|
11
|
+
attr_reader :manifest
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@manifest = Manifest.new(doc: doc)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe :add_child do
|
18
|
+
it 'adds a FileEntry' do
|
19
|
+
entry = FileEntry.new('foo.bar', 'foo/bar', manifest: manifest)
|
20
|
+
manifest.add_child(entry)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'adds a non-FileEntry' do
|
24
|
+
child = ElementNode.new(:office, 'test', doc: doc)
|
25
|
+
manifest.add_child(child)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Office
|
8
|
+
describe DocumentContent do
|
9
|
+
let(:content) { ContentDoc.new }
|
10
|
+
let(:doc_content) { content.document_content }
|
11
|
+
|
12
|
+
# TODO: move to some kind of helper & share w/table_spec
|
13
|
+
def doc_content_xml
|
14
|
+
xml_str = content.to_xml
|
15
|
+
# File.open("tmp/content-#{Time.now.to_i}.xml", 'wb') { |f| f.write(xml_str) }
|
16
|
+
rexml_doc = REXML::Document.new(xml_str)
|
17
|
+
rexml_doc.root
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO: move to some kind of helper & share w/table_spec
|
21
|
+
def find_table_xml(dc_xml = doc_content_xml, table_index = 1)
|
22
|
+
body = dc_xml.elements[4]
|
23
|
+
expect(body).to be_a(REXML::Element) # just to be sure
|
24
|
+
|
25
|
+
spreadsheet = body.elements[1]
|
26
|
+
expect(spreadsheet).to be_a(REXML::Element) # just to be sure
|
27
|
+
|
28
|
+
spreadsheet.elements[table_index]
|
29
|
+
end
|
30
|
+
|
31
|
+
describe :add_table do
|
32
|
+
|
33
|
+
let(:table_name) { "Table for #{File.basename(__FILE__, '.rb')}" }
|
34
|
+
|
35
|
+
attr_reader :table
|
36
|
+
|
37
|
+
before(:each) do
|
38
|
+
@table = doc_content.add_table(table_name)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'creates a table' do
|
42
|
+
expect(table).to be_a(XML::Table::Table)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'adds the table to the XML' do
|
46
|
+
table_xml = find_table_xml
|
47
|
+
expect(table_xml).to be_a(REXML::Element)
|
48
|
+
expect(table_xml.prefix).to eq('table')
|
49
|
+
expect(table_xml.name).to eq('table')
|
50
|
+
|
51
|
+
expect(table_xml['table:name']).to eq(table_name)
|
52
|
+
expect(table_xml['table:protected']).to eq('true')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Office
|
8
|
+
describe AutomaticStyles do
|
9
|
+
let(:doc) { Nokogiri::XML::Document.new }
|
10
|
+
|
11
|
+
attr_reader :styles
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@styles = AutomaticStyles.new(doc: doc)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe :add_child do
|
18
|
+
it 'adds a style' do
|
19
|
+
protected = false
|
20
|
+
color = '#abcdef'
|
21
|
+
|
22
|
+
style = Style::CellStyle.new('my-style', protected, color, styles: styles)
|
23
|
+
styles.add_child(style)
|
24
|
+
expect(styles.find_cell_style(protected, color: color)).to be(style)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'adds a non-style' do
|
28
|
+
non_style = XML::Text::P.new('abcdef', doc: doc)
|
29
|
+
styles.add_child(non_style)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Style
|
8
|
+
describe Family do
|
9
|
+
describe :ensure_family do
|
10
|
+
it "returns a #{Family} as itself" do
|
11
|
+
Family.each do |f|
|
12
|
+
expect(Family.ensure_family(f)).to be(f)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'finds a family by key' do
|
17
|
+
Family.each do |f|
|
18
|
+
variants = [
|
19
|
+
f.key.to_s,
|
20
|
+
f.key.to_sym,
|
21
|
+
f.key.to_s.upcase,
|
22
|
+
f.key.to_s.upcase.to_sym,
|
23
|
+
f.key.to_s.downcase,
|
24
|
+
f.key.to_s.downcase.to_sym
|
25
|
+
]
|
26
|
+
variants.each do |k|
|
27
|
+
expect(Family.ensure_family(k)).to be(f)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'finds a family by value' do
|
33
|
+
Family.each do |f|
|
34
|
+
variants = [
|
35
|
+
f.value.to_s,
|
36
|
+
f.value.to_sym,
|
37
|
+
f.value.to_s.upcase,
|
38
|
+
f.value.to_s.upcase.to_sym,
|
39
|
+
f.value.to_s.downcase,
|
40
|
+
f.value.to_s.downcase.to_sym
|
41
|
+
]
|
42
|
+
variants.each do |v|
|
43
|
+
expect(Family.ensure_family(v)).to be(f)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'rejects invalid families' do
|
49
|
+
expect { Family.ensure_family(:not_a_family) }.to raise_error(ArgumentError)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Util
|
5
|
+
module ODS
|
6
|
+
module XML
|
7
|
+
module Table
|
8
|
+
describe TableRow do
|
9
|
+
let(:content) { ContentDoc.new }
|
10
|
+
let(:doc_content) { content.document_content }
|
11
|
+
let(:table_name) { "Table for #{File.basename(__FILE__, '.rb')}" }
|
12
|
+
|
13
|
+
attr_reader :table, :row
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@table = doc_content.add_table(table_name)
|
17
|
+
table.add_column('Column 1')
|
18
|
+
@row = table.add_row
|
19
|
+
end
|
20
|
+
|
21
|
+
# TODO: move to some kind of helper & share w/table_spec
|
22
|
+
def doc_content_xml
|
23
|
+
xml_str = content.to_xml
|
24
|
+
# File.open("tmp/content-#{Time.now.to_i}.xml", 'wb') { |f| f.write(xml_str) }
|
25
|
+
rexml_doc = REXML::Document.new(xml_str)
|
26
|
+
rexml_doc.root
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: move to some kind of helper & share w/table_spec
|
30
|
+
def find_table_xml(dc_xml = doc_content_xml, table_index = 1)
|
31
|
+
body = dc_xml.elements[4]
|
32
|
+
expect(body).to be_a(REXML::Element) # just to be sure
|
33
|
+
|
34
|
+
spreadsheet = body.elements[1]
|
35
|
+
expect(spreadsheet).to be_a(REXML::Element) # just to be sure
|
36
|
+
|
37
|
+
spreadsheet.elements[table_index]
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_row_xml(table_xml = find_table_xml, row_index = 2)
|
41
|
+
table_xml.elements[row_index, 'table-row']
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_cell_xml(table_xml = find_table_xml, row_index = 2, col_index = 0)
|
45
|
+
row_xml = table_xml.elements[row_index, 'table-row']
|
46
|
+
cells_xml = row_xml.elements.select { |e| e.name == 'table-cell' }
|
47
|
+
cells_xml[col_index]
|
48
|
+
end
|
49
|
+
|
50
|
+
describe :set_value_at do
|
51
|
+
it 'sets a value' do
|
52
|
+
value = 'Value 0'
|
53
|
+
row.set_value_at(0, value)
|
54
|
+
expect(table.get_value_at(1, 0)).to eq(value)
|
55
|
+
|
56
|
+
row_xml = find_row_xml
|
57
|
+
cells_xml = row_xml.elements.select { |e| e.name == 'table-cell' }
|
58
|
+
expect(cells_xml.size).to eq(2)
|
59
|
+
|
60
|
+
cell_xml = cells_xml[0]
|
61
|
+
p = cell_xml.elements[1, 'p'] # row 1 is header
|
62
|
+
expect(p).to be_a(REXML::Element)
|
63
|
+
expect(p.prefix).to eq('text')
|
64
|
+
|
65
|
+
texts = p.texts
|
66
|
+
expect(texts.size).to eq(1)
|
67
|
+
expect(texts[0].value).to eq(value)
|
68
|
+
|
69
|
+
dummy_cell_xml = cells_xml[1]
|
70
|
+
expected_dummy_cols = Table::MIN_COLUMNS - 1
|
71
|
+
expect(dummy_cell_xml['table:number-columns-repeated']).to eq(expected_dummy_cols.to_s)
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'escapes tabs, newlines, and runs of spaces' do
|
75
|
+
value_fragments = [
|
76
|
+
' test test ', "\t", 'test ', ' ', ' ', 'test test', "\n", 'test test ', ' '
|
77
|
+
]
|
78
|
+
value = value_fragments.join
|
79
|
+
row.set_value_at(0, value)
|
80
|
+
expect(table.get_value_at(1, 0)).to eq(value)
|
81
|
+
|
82
|
+
row_xml = find_row_xml
|
83
|
+
cells_xml = row_xml.elements.select { |e| e.name == 'table-cell' }
|
84
|
+
expect(cells_xml.size).to eq(2)
|
85
|
+
|
86
|
+
escape_elements = { ' ' => 's', "\t" => 'tab', "\n" => 'line-break' }
|
87
|
+
|
88
|
+
cell_xml = cells_xml[0]
|
89
|
+
p_xml = cell_xml.elements[1, 'p']
|
90
|
+
|
91
|
+
p_children = p_xml.to_a
|
92
|
+
expect(p_children.size).to eq(value_fragments.size)
|
93
|
+
|
94
|
+
value_fragments.each_with_index do |vf, i|
|
95
|
+
expected_element = escape_elements[vf]
|
96
|
+
if expected_element
|
97
|
+
element = p_children[i]
|
98
|
+
expect(element).to be_a(REXML::Element)
|
99
|
+
expect(element.name).to eq(expected_element)
|
100
|
+
expect(element.prefix).to eq('text')
|
101
|
+
else
|
102
|
+
text = p_children[i]
|
103
|
+
expect(text).to be_a(REXML::Text)
|
104
|
+
expect(text.value).to eq(vf)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe :to_xml do
|
111
|
+
it 'collapses consecutive nils' do
|
112
|
+
(2..7).each { |col| table.add_column("Column #{col}") }
|
113
|
+
|
114
|
+
row.set_value_at(0, 'Value 0')
|
115
|
+
row.set_value_at(2, 'Value 2')
|
116
|
+
row.set_value_at(6, 'Value 6')
|
117
|
+
|
118
|
+
row_xml = find_row_xml
|
119
|
+
cells_xml = row_xml.elements.select { |e| e.name == 'table-cell' }
|
120
|
+
expect(cells_xml.size).to eq(6)
|
121
|
+
|
122
|
+
expected_values = ['Value 0', nil, 'Value 2', nil, 'Value 6', nil]
|
123
|
+
expected_repeats = [nil, nil, nil, 3, nil, Table::MIN_COLUMNS - 7]
|
124
|
+
cells_xml.each_with_index do |cell_xml, i|
|
125
|
+
p = cell_xml.elements[1, 'p']
|
126
|
+
if (expected_value = expected_values[i])
|
127
|
+
expect(p).to be_a(REXML::Element)
|
128
|
+
texts = p.texts
|
129
|
+
expect(texts.size).to eq(1)
|
130
|
+
expect(texts[0].value).to eq(expected_value)
|
131
|
+
else
|
132
|
+
expect(p).to be_nil
|
133
|
+
end
|
134
|
+
|
135
|
+
num_cols_repeated = cell_xml['table:number-columns-repeated']
|
136
|
+
expected_repeat = expected_repeats[i]
|
137
|
+
if expected_repeat
|
138
|
+
expect(num_cols_repeated).to eq(expected_repeat.to_s)
|
139
|
+
else
|
140
|
+
expect(num_cols_repeated).to be_nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe :add_child do
|
147
|
+
it 'adds a cell' do
|
148
|
+
value = 'Value 0'
|
149
|
+
cell = TableCell.new(value, table: table)
|
150
|
+
row.add_child(cell)
|
151
|
+
expect(table.get_value_at(1, 0)).to eq(value)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'adds a non-cell child' do
|
155
|
+
child = ElementNode.new(:office, 'test', doc: table.doc)
|
156
|
+
row.add_child(child)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "fails if there aren't enough columns" do
|
160
|
+
column_count = table.column_count
|
161
|
+
(0..column_count).each do |col_index|
|
162
|
+
value = "Value #{col_index}"
|
163
|
+
cell = TableCell.new(value, table: table)
|
164
|
+
if col_index < column_count
|
165
|
+
expect { row.add_child(cell) }.not_to raise_error
|
166
|
+
expect(table.get_value_at(1, col_index)).to eq(value)
|
167
|
+
else
|
168
|
+
expect { row.add_child(cell) }.to raise_error(ArgumentError)
|
169
|
+
expect(table.get_value_at(1, col_index)).to be_nil
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|