ruby-marc-spec 0.1.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/.gitmodules +3 -0
- data/.idea/codeStyles/codeStyleConfig.xml +5 -0
- data/.idea/go.imports.xml +6 -0
- data/.idea/inspectionProfiles/Project_Default.xml +23 -0
- data/.idea/marc_spec.iml +102 -0
- data/.idea/misc.xml +6 -0
- data/.idea/modules.xml +8 -0
- data/.idea/templateLanguages.xml +6 -0
- data/.idea/vcs.xml +7 -0
- data/.rubocop.yml +269 -0
- data/.ruby-version +1 -0
- data/.simplecov +8 -0
- data/CHANGES.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE.md +21 -0
- data/README.md +172 -0
- data/Rakefile +20 -0
- data/lib/.rubocop.yml +5 -0
- data/lib/marc/spec/module_info.rb +14 -0
- data/lib/marc/spec/parsing/closed_int_range.rb +28 -0
- data/lib/marc/spec/parsing/closed_lc_alpha_range.rb +28 -0
- data/lib/marc/spec/parsing/parser.rb +213 -0
- data/lib/marc/spec/parsing.rb +1 -0
- data/lib/marc/spec/queries/al_num_range.rb +105 -0
- data/lib/marc/spec/queries/applicable.rb +18 -0
- data/lib/marc/spec/queries/character_spec.rb +81 -0
- data/lib/marc/spec/queries/comparison_string.rb +45 -0
- data/lib/marc/spec/queries/condition.rb +133 -0
- data/lib/marc/spec/queries/condition_context.rb +49 -0
- data/lib/marc/spec/queries/dsl.rb +80 -0
- data/lib/marc/spec/queries/indicator_value.rb +77 -0
- data/lib/marc/spec/queries/operator.rb +129 -0
- data/lib/marc/spec/queries/part.rb +63 -0
- data/lib/marc/spec/queries/position.rb +59 -0
- data/lib/marc/spec/queries/position_or_range.rb +27 -0
- data/lib/marc/spec/queries/query.rb +94 -0
- data/lib/marc/spec/queries/query_executor.rb +52 -0
- data/lib/marc/spec/queries/selector.rb +12 -0
- data/lib/marc/spec/queries/subfield.rb +88 -0
- data/lib/marc/spec/queries/subfield_value.rb +63 -0
- data/lib/marc/spec/queries/tag.rb +107 -0
- data/lib/marc/spec/queries/transform.rb +154 -0
- data/lib/marc/spec/queries.rb +1 -0
- data/lib/marc/spec.rb +32 -0
- data/rakelib/.rubocop.yml +19 -0
- data/rakelib/bundle.rake +8 -0
- data/rakelib/coverage.rake +11 -0
- data/rakelib/gem.rake +54 -0
- data/rakelib/parser_specs/formatter.rb +31 -0
- data/rakelib/parser_specs/parser_specs.rb.txt.erb +35 -0
- data/rakelib/parser_specs/rule.rb +95 -0
- data/rakelib/parser_specs/suite.rb +91 -0
- data/rakelib/parser_specs/test.rb +97 -0
- data/rakelib/parser_specs.rb +1 -0
- data/rakelib/rubocop.rake +18 -0
- data/rakelib/spec.rake +27 -0
- data/ruby-marc-spec.gemspec +42 -0
- data/spec/.rubocop.yml +46 -0
- data/spec/README.md +16 -0
- data/spec/data/b23161018-sru.xml +182 -0
- data/spec/data/sandburg.xml +82 -0
- data/spec/generated/char_indicator_spec.rb +174 -0
- data/spec/generated/char_spec.rb +113 -0
- data/spec/generated/comparison_string_spec.rb +74 -0
- data/spec/generated/field_tag_spec.rb +156 -0
- data/spec/generated/index_char_spec.rb +669 -0
- data/spec/generated/index_indicator_spec.rb +174 -0
- data/spec/generated/index_spec.rb +113 -0
- data/spec/generated/index_sub_spec_spec.rb +1087 -0
- data/spec/generated/indicators_spec.rb +75 -0
- data/spec/generated/position_or_range_spec.rb +110 -0
- data/spec/generated/sub_spec_spec.rb +208 -0
- data/spec/generated/sub_spec_sub_spec_spec.rb +1829 -0
- data/spec/generated/subfield_char_spec.rb +405 -0
- data/spec/generated/subfield_range_range_spec.rb +48 -0
- data/spec/generated/subfield_range_spec.rb +87 -0
- data/spec/generated/subfield_range_sub_spec_spec.rb +214 -0
- data/spec/generated/subfield_tag_range_spec.rb +477 -0
- data/spec/generated/subfield_tag_sub_spec_spec.rb +3216 -0
- data/spec/generated/subfield_tag_tag_spec.rb +5592 -0
- data/spec/marc/spec/parsing/closed_int_range_spec.rb +49 -0
- data/spec/marc/spec/parsing/closed_lc_alpha_range_spec.rb +49 -0
- data/spec/marc/spec/parsing/parser_spec.rb +545 -0
- data/spec/marc/spec/queries/al_num_range_spec.rb +114 -0
- data/spec/marc/spec/queries/character_spec_spec.rb +28 -0
- data/spec/marc/spec/queries/comparison_string_spec.rb +28 -0
- data/spec/marc/spec/queries/indicator_value_spec.rb +28 -0
- data/spec/marc/spec/queries/query_spec.rb +200 -0
- data/spec/marc/spec/queries/subfield_spec.rb +92 -0
- data/spec/marc/spec/queries/subfield_value_spec.rb +31 -0
- data/spec/marc/spec/queries/tag_spec.rb +144 -0
- data/spec/marc/spec/queries/transform_spec.rb +459 -0
- data/spec/marc_spec_spec.rb +247 -0
- data/spec/scratch_spec.rb +112 -0
- data/spec/spec_helper.rb +23 -0
- metadata +341 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parslet/rig/rspec'
|
3
|
+
|
4
|
+
module MARC::Spec
|
5
|
+
module Parsing
|
6
|
+
describe ClosedIntRange do
|
7
|
+
attr_reader :range
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@range = ClosedIntRange.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parses a valid range' do
|
14
|
+
valid_ranges = %w[
|
15
|
+
0-1
|
16
|
+
1-2
|
17
|
+
12-345
|
18
|
+
67890-123456
|
19
|
+
]
|
20
|
+
aggregate_failures 'valid ranges' do
|
21
|
+
valid_ranges.each do |r|
|
22
|
+
expect(range).to parse(r)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'does not parse an invalid range' do
|
28
|
+
invalid_ranges = %w[
|
29
|
+
1-0
|
30
|
+
2-1
|
31
|
+
345-12
|
32
|
+
123456-67890
|
33
|
+
]
|
34
|
+
aggregate_failures 'invalid ranges' do
|
35
|
+
invalid_ranges.each do |r|
|
36
|
+
expect(range).not_to parse(r)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe :to_s do
|
42
|
+
it 'accepts a precedece argument' do
|
43
|
+
prec = Parslet::Atoms::Precedence::OUTER
|
44
|
+
expect(range.to_s(prec)).to eq('ClosedIntRange')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parslet/rig/rspec'
|
3
|
+
|
4
|
+
module MARC::Spec
|
5
|
+
module Parsing
|
6
|
+
describe ClosedLcAlphaRange do
|
7
|
+
attr_reader :range
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
@range = ClosedLcAlphaRange.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parses a valid range' do
|
14
|
+
valid_ranges = %w[
|
15
|
+
a-b
|
16
|
+
c-d
|
17
|
+
e-f
|
18
|
+
g-z
|
19
|
+
]
|
20
|
+
aggregate_failures 'valid ranges' do
|
21
|
+
valid_ranges.each do |r|
|
22
|
+
expect(range).to parse(r)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'does not parse an invalid range' do
|
28
|
+
invalid_ranges = %w[
|
29
|
+
z-a
|
30
|
+
b-a
|
31
|
+
d-c
|
32
|
+
x-f
|
33
|
+
]
|
34
|
+
aggregate_failures 'invalid ranges' do
|
35
|
+
invalid_ranges.each do |r|
|
36
|
+
expect(range).not_to parse(r)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe :to_s do
|
42
|
+
it 'accepts a precedece argument' do
|
43
|
+
prec = Parslet::Atoms::Precedence::OUTER
|
44
|
+
expect(range.to_s(prec)).to eq('ClosedLcAlphaRange')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,545 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parslet/rig/rspec'
|
3
|
+
|
4
|
+
# noinspection RubyResolve
|
5
|
+
module MARC::Spec
|
6
|
+
module Parsing
|
7
|
+
include MARC::Spec::Queries::Part
|
8
|
+
|
9
|
+
describe Parser do
|
10
|
+
let(:parser) { Parser.new }
|
11
|
+
let(:tags) { %w[245 2.. 24. .45 ..5 ... LDR] }
|
12
|
+
let(:positions) { %w[0 3 5] }
|
13
|
+
let(:pos_ranges) { [%w[1 3], %w[1 #], %w[# 1], %w[2 4], %w[# #]] }
|
14
|
+
let(:codes) { %w[b 2 $ \\ { }] }
|
15
|
+
let(:code_ranges) { [%w[a c], %w[1 3]] }
|
16
|
+
let(:inds) { %w[1 2] }
|
17
|
+
|
18
|
+
let(:r) { Parslet::ErrorReporter::Deepest.new }
|
19
|
+
|
20
|
+
# TODO: clean this up
|
21
|
+
# before(:all) do
|
22
|
+
# @all_parses = {}
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# after(:all) do
|
26
|
+
# parse_list = @all_parses.map do |val, parse_tree|
|
27
|
+
# [val.inspect, parse_tree.inspect].join(' => ')
|
28
|
+
# end
|
29
|
+
# parse_list.sort!
|
30
|
+
# parse_list.uniq!
|
31
|
+
# puts "{\n#{parse_list.join(",\n")}\n}"
|
32
|
+
# end
|
33
|
+
|
34
|
+
def parse_with(rule, value)
|
35
|
+
rule.parse(value).tap do |result|
|
36
|
+
# @all_parses[value] = result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe :field_tag do
|
41
|
+
let(:rule) { parser.field_tag }
|
42
|
+
|
43
|
+
it 'parses tags' do
|
44
|
+
aggregate_failures do
|
45
|
+
tags.each do |tag|
|
46
|
+
expect(rule).to parse(tag)
|
47
|
+
result = parse_with(rule, tag)
|
48
|
+
expect(result).to eq(tag)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :position do
|
55
|
+
let(:rule) { parser.position }
|
56
|
+
|
57
|
+
it 'parses positions' do
|
58
|
+
aggregate_failures do
|
59
|
+
%w[0 7 17 317].each do |pos|
|
60
|
+
expect(rule).to parse(pos, reporter: r)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe :position_or_range do
|
67
|
+
let(:rule) { parser.position_or_range }
|
68
|
+
|
69
|
+
it 'parses positions' do
|
70
|
+
aggregate_failures do
|
71
|
+
positions.each do |pos|
|
72
|
+
expect(rule).to parse(pos, reporter: r)
|
73
|
+
result = parse_with(rule, pos)
|
74
|
+
expect(result[:pos]).to eq(pos)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'parses ranges' do
|
80
|
+
aggregate_failures do
|
81
|
+
pos_ranges.each do |from, to|
|
82
|
+
val = "#{from}-#{to}"
|
83
|
+
expect(rule).to parse(val, reporter: r)
|
84
|
+
result = parse_with(rule, val)
|
85
|
+
expect(result[:from]).to eq(from == '#' ? nil : from)
|
86
|
+
expect(result[:to]).to eq(to == '#' ? nil : to)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe :character_spec do
|
93
|
+
let(:rule) { parser.character_spec }
|
94
|
+
|
95
|
+
it 'parses positions' do
|
96
|
+
aggregate_failures do
|
97
|
+
positions.each do |pos|
|
98
|
+
val = "/#{pos}"
|
99
|
+
expect(rule).to parse(val, reporter: r)
|
100
|
+
result = parse_with(rule, val)
|
101
|
+
character_spec = result[:character_spec]
|
102
|
+
expect(character_spec[:pos]).to eq(pos)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'parses ranges' do
|
108
|
+
aggregate_failures do
|
109
|
+
pos_ranges.each do |from, to|
|
110
|
+
val = "/#{from}-#{to}"
|
111
|
+
expect(rule).to parse(val, reporter: r)
|
112
|
+
result = parse_with(rule, val)
|
113
|
+
character_spec = result[:character_spec]
|
114
|
+
expect(character_spec[:from]).to eq(from == '#' ? nil : from)
|
115
|
+
expect(character_spec[:to]).to eq(to == '#' ? nil : to)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe :field_spec do
|
122
|
+
let(:rule) { parser.field_spec }
|
123
|
+
|
124
|
+
it 'parses tags' do
|
125
|
+
aggregate_failures do
|
126
|
+
tags.each do |tag|
|
127
|
+
expect(rule).to parse(tag)
|
128
|
+
result = parse_with(rule, tag)
|
129
|
+
expect(result[:tag]).to eq(tag)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe 'with substrings' do
|
135
|
+
it 'parses positions' do
|
136
|
+
aggregate_failures do
|
137
|
+
tags.each do |tag|
|
138
|
+
positions.each do |pos|
|
139
|
+
val = "#{tag}/#{pos}"
|
140
|
+
expect(rule).to parse(val, reporter: r)
|
141
|
+
result = parse_with(rule, val)
|
142
|
+
expect(result[:tag]).to eq(tag)
|
143
|
+
selector = result[:selector]
|
144
|
+
character_spec = selector[:character_spec]
|
145
|
+
expect(character_spec[:pos]).to eq(pos)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'parses ranges' do
|
152
|
+
aggregate_failures do
|
153
|
+
tags.each do |tag|
|
154
|
+
pos_ranges.each do |from, to|
|
155
|
+
val = "#{tag}/#{from}-#{to}"
|
156
|
+
expect(rule).to parse(val, reporter: r)
|
157
|
+
result = parse_with(rule, val)
|
158
|
+
expect(result[:tag]).to eq(tag)
|
159
|
+
selector = result[:selector]
|
160
|
+
character_spec = selector[:character_spec]
|
161
|
+
expect(character_spec[:from]).to eq(from == '#' ? nil : from)
|
162
|
+
expect(character_spec[:to]).to eq(to == '#' ? nil : to)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe 'with indices' do
|
170
|
+
it 'parses positions' do
|
171
|
+
aggregate_failures do
|
172
|
+
tags.each do |tag|
|
173
|
+
positions.each do |pos_index|
|
174
|
+
val = "#{tag}[#{pos_index}]"
|
175
|
+
expect(rule).to parse(val, reporter: r)
|
176
|
+
result = parse_with(rule, val)
|
177
|
+
expect(result[:tag]).to eq(tag)
|
178
|
+
index = result[:index]
|
179
|
+
expect(index[:pos]).to eq(pos_index)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'parses ranges' do
|
186
|
+
aggregate_failures do
|
187
|
+
tags.each do |tag|
|
188
|
+
pos_ranges.each do |from_index, to_index|
|
189
|
+
val = "#{tag}[#{from_index}-#{to_index}]"
|
190
|
+
expect(rule).to parse(val, reporter: r)
|
191
|
+
result = parse_with(rule, val)
|
192
|
+
expect(result[:tag]).to eq(tag)
|
193
|
+
index = result[:index]
|
194
|
+
expect(index[:from]).to eq(from_index == '#' ? nil : from_index)
|
195
|
+
expect(index[:to]).to eq(to_index == '#' ? nil : to_index)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe :subfield_code do
|
204
|
+
let(:rule) { parser.subfield_code }
|
205
|
+
|
206
|
+
it 'parses codes' do
|
207
|
+
aggregate_failures do
|
208
|
+
codes.each do |code|
|
209
|
+
val = "$#{code}"
|
210
|
+
expect(rule).to parse(val, reporter: r)
|
211
|
+
expect(parse_with(rule, val)).to eq(code)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe :subfield_spec do
|
218
|
+
let(:rule) { parser.subfield_spec }
|
219
|
+
|
220
|
+
it 'parses codes' do
|
221
|
+
aggregate_failures do
|
222
|
+
tags.each do |tag|
|
223
|
+
codes.each do |code|
|
224
|
+
val = "#{tag}$#{code}"
|
225
|
+
expect(rule).to parse(val, reporter: r)
|
226
|
+
result = parse_with(rule, val)
|
227
|
+
expect(result[:tag]).to eq(tag)
|
228
|
+
selector = result[:selector]
|
229
|
+
expect(selector).to eq({ code: code })
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'parses code ranges' do
|
236
|
+
aggregate_failures do
|
237
|
+
tags.each do |tag|
|
238
|
+
code_ranges.each do |from, to|
|
239
|
+
val = "#{tag}$#{from}-#{to}"
|
240
|
+
expect(rule).to parse(val, reporter: r)
|
241
|
+
result = parse_with(rule, val)
|
242
|
+
expect(result[:tag]).to eq(tag)
|
243
|
+
|
244
|
+
selector = result[:selector]
|
245
|
+
expect(selector).not_to be_nil
|
246
|
+
|
247
|
+
code_range = selector[:code]
|
248
|
+
expect(code_range[:from]).to eq(from)
|
249
|
+
expect(code_range[:to]).to eq(to)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'parses codes with indices' do
|
256
|
+
aggregate_failures do
|
257
|
+
tags.each do |tag|
|
258
|
+
positions.each do |pos_index|
|
259
|
+
codes.each do |code|
|
260
|
+
val = "#{tag}[#{pos_index}]$#{code}"
|
261
|
+
expect(rule).to parse(val, reporter: r)
|
262
|
+
result = parse_with(rule, val)
|
263
|
+
expect(result[:tag]).to eq(tag)
|
264
|
+
|
265
|
+
index = result[:index]
|
266
|
+
expect(index[:pos]).to eq(pos_index)
|
267
|
+
|
268
|
+
selector = result[:selector]
|
269
|
+
expect(selector).not_to be_nil
|
270
|
+
expect(selector[:code]).to eq(code)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'parses code ranges with indices' do
|
278
|
+
pos_ranges.each do |from_index, to_index|
|
279
|
+
aggregate_failures do
|
280
|
+
tags.each do |tag|
|
281
|
+
code_ranges.each do |from, to|
|
282
|
+
val = "#{tag}[#{from_index}-#{to_index}]$#{from}-#{to}"
|
283
|
+
expect(rule).to parse(val, reporter: r)
|
284
|
+
result = parse_with(rule, val)
|
285
|
+
expect(result[:tag]).to eq(tag)
|
286
|
+
|
287
|
+
index = result[:index]
|
288
|
+
expect(index[:from]).to eq(from_index == '#' ? nil : from_index)
|
289
|
+
expect(index[:to]).to eq(to_index == '#' ? nil : to_index)
|
290
|
+
|
291
|
+
selector = result[:selector]
|
292
|
+
expect(selector).not_to be_nil
|
293
|
+
|
294
|
+
code_range = selector[:code]
|
295
|
+
expect(code_range[:from]).to eq(from)
|
296
|
+
expect(code_range[:to]).to eq(to)
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe :indicator_spec do
|
305
|
+
let(:rule) { parser.indicator_spec }
|
306
|
+
|
307
|
+
it 'parses indicators with plain tags' do
|
308
|
+
aggregate_failures do
|
309
|
+
tags.each do |tag|
|
310
|
+
inds.each do |ind|
|
311
|
+
val = "#{tag}^#{ind}"
|
312
|
+
expect(rule).to parse(val)
|
313
|
+
result = parse_with(rule, val)
|
314
|
+
expect(result[:tag]).to eq(tag)
|
315
|
+
selector = result[:selector]
|
316
|
+
expect(selector[:ind]).to eq(ind)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'parses indicators with position-indexed tags' do
|
323
|
+
aggregate_failures do
|
324
|
+
tags.each do |tag|
|
325
|
+
positions.each do |pos_index|
|
326
|
+
inds.each do |ind|
|
327
|
+
val = "#{tag}[#{pos_index}]^#{ind}"
|
328
|
+
result = parse_with(rule, val)
|
329
|
+
expect(result[:tag]).to eq(tag)
|
330
|
+
selector = result[:selector]
|
331
|
+
expect(selector[:ind]).to eq(ind)
|
332
|
+
index = result[:index]
|
333
|
+
expect(index[:pos]).to eq(pos_index)
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'parses indicators with range-indexed tags' do
|
341
|
+
aggregate_failures do
|
342
|
+
tags.each do |tag|
|
343
|
+
pos_ranges.each do |from_index, to_index|
|
344
|
+
inds.each do |ind|
|
345
|
+
val = "#{tag}[#{from_index}-#{to_index}]^#{ind}"
|
346
|
+
result = parse_with(rule, val)
|
347
|
+
expect(result[:tag]).to eq(tag)
|
348
|
+
selector = result[:selector]
|
349
|
+
expect(selector[:ind]).to eq(ind)
|
350
|
+
index = result[:index]
|
351
|
+
expect(index[:from]).to eq(from_index == '#' ? nil : from_index)
|
352
|
+
expect(index[:to]).to eq(to_index == '#' ? nil : to_index)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|
360
|
+
|
361
|
+
describe :comparison_string do
|
362
|
+
let(:rule) { parser._comparison_string }
|
363
|
+
|
364
|
+
it 'parses a comparison string' do
|
365
|
+
expecteds = {
|
366
|
+
'\\svalue' => '\\svalue',
|
367
|
+
'\\\\svalue' => '\\svalue',
|
368
|
+
'\\value' => 'value',
|
369
|
+
'\\value\\!' => 'value\\!',
|
370
|
+
'\\!value' => '!value',
|
371
|
+
'\\\\!value' => '\\!value',
|
372
|
+
'\\help\\sI\\sam\\strapped\\sin\\sa\\sunit\\stest\\!\\sso\\sam\\sI' =>
|
373
|
+
'help\\sI\\sam\\strapped\\sin\\sa\\sunit\\stest\\!\\sso\\sam\\sI',
|
374
|
+
'\\a\\{b\\}\\$1\\\\23\\=\\~\\|\\?' => 'a\\{b\\}\\$1\\\\23\\=\\~\\|\\?'
|
375
|
+
}
|
376
|
+
aggregate_failures do
|
377
|
+
expecteds.each do |val, expected|
|
378
|
+
expect(rule).to parse(val, reporter: r)
|
379
|
+
result = parse_with(rule, val)
|
380
|
+
expect(result).to be_a(Hash)
|
381
|
+
next unless result.is_a?(Hash)
|
382
|
+
|
383
|
+
cstr = result[:comparison_string]
|
384
|
+
expect(cstr).to eq(expected)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe :sub_spec do
|
391
|
+
let(:rule) { parser.sub_spec }
|
392
|
+
|
393
|
+
it 'parses a condition' do
|
394
|
+
expecteds = {
|
395
|
+
'{/#=\\/}' => {
|
396
|
+
left: {
|
397
|
+
selector: {
|
398
|
+
character_spec: {
|
399
|
+
pos: '#'
|
400
|
+
}
|
401
|
+
}
|
402
|
+
},
|
403
|
+
operator: '=',
|
404
|
+
right: {
|
405
|
+
comparison_string: '/'
|
406
|
+
}
|
407
|
+
}
|
408
|
+
}
|
409
|
+
aggregate_failures do
|
410
|
+
expecteds.each do |val, expected|
|
411
|
+
expect(rule).to parse(val, reporter: r)
|
412
|
+
result = parse_with(rule, val)
|
413
|
+
expect(result).to eq(expected)
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
describe 'with multiple subfields' do
|
420
|
+
it 'parses subfield code lists' do
|
421
|
+
aggregate_failures do
|
422
|
+
tags.each do |tag|
|
423
|
+
code_list = codes.map { |c| "$#{c}" }.join
|
424
|
+
val = "#{tag}#{code_list}"
|
425
|
+
expect(parser).to parse(val, reporter: r)
|
426
|
+
result = parse_with(parser, val)
|
427
|
+
|
428
|
+
expect(result[:tag]).to eq(tag)
|
429
|
+
|
430
|
+
subqueries = result[:subqueries]
|
431
|
+
expect(subqueries.size).to eq(codes.size)
|
432
|
+
subqueries.each_with_index do |subquery, i|
|
433
|
+
selector = subquery[:selector]
|
434
|
+
subfield = selector
|
435
|
+
expect(subfield[:code]).to eq(codes[i])
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'handles indices' do
|
442
|
+
aggregate_failures do
|
443
|
+
tags.each do |tag|
|
444
|
+
pos_ranges.each do |from_index, to_index|
|
445
|
+
code_list = codes.map { |c| "$#{c}" }.join
|
446
|
+
val = "#{tag}[#{from_index}-#{to_index}]#{code_list}"
|
447
|
+
expect(parser).to parse(val, reporter: r)
|
448
|
+
result = parse_with(parser, val)
|
449
|
+
|
450
|
+
expect(result[:tag]).to eq(tag)
|
451
|
+
index = result[:index]
|
452
|
+
expect(index[:from]).to eq(from_index == '#' ? nil : from_index)
|
453
|
+
expect(index[:to]).to eq(to_index == '#' ? nil : to_index)
|
454
|
+
|
455
|
+
subqueries = result[:subqueries]
|
456
|
+
expect(subqueries.size).to eq(codes.size)
|
457
|
+
subqueries.each_with_index do |subquery, i|
|
458
|
+
selector = subquery[:selector]
|
459
|
+
subfield = selector
|
460
|
+
expect(subfield[:code]).to eq(codes[i])
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
it 'parses subfield code lists with conditions' do
|
468
|
+
aggregate_failures do
|
469
|
+
tags.each do |tag|
|
470
|
+
pos_ranges.each do |from_index, to_index|
|
471
|
+
code_list = codes.map.with_index { |c, i| "$#{c}{~\\ok#{i}}" }.join
|
472
|
+
val = "#{tag}[#{from_index}-#{to_index}]#{code_list}"
|
473
|
+
expect(parser).to parse(val, reporter: r)
|
474
|
+
result = parse_with(parser, val)
|
475
|
+
|
476
|
+
expect(result[:tag]).to eq(tag)
|
477
|
+
index = result[:index]
|
478
|
+
expect(index[:from]).to eq(from_index == '#' ? nil : from_index)
|
479
|
+
expect(index[:to]).to eq(to_index == '#' ? nil : to_index)
|
480
|
+
|
481
|
+
subqueries = result[:subqueries]
|
482
|
+
expect(subqueries.size).to eq(codes.size)
|
483
|
+
subqueries.each_with_index do |subquery, i|
|
484
|
+
selector = subquery[:selector]
|
485
|
+
subfield = selector
|
486
|
+
expect(subfield[:code]).to eq(codes[i])
|
487
|
+
condition = subquery[:condition]
|
488
|
+
expect(condition[:operator]).to eq('~')
|
489
|
+
right_operand = condition[:right]
|
490
|
+
expect(right_operand[:comparison_string]).to eq("ok#{i}")
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
it 'handles complex combinations of subfields and subspecs' do
|
498
|
+
val = '880$a{?$f}$b$c$e{$f=\\q}'
|
499
|
+
|
500
|
+
expect(parser).to parse(val, reporter: r)
|
501
|
+
result = parse_with(parser, val)
|
502
|
+
expect(result[:tag]).to eq('880')
|
503
|
+
|
504
|
+
subqueries = result[:subqueries]
|
505
|
+
expect(subqueries.size).to eq(4)
|
506
|
+
|
507
|
+
expect(subqueries[0][:selector]).to eq({ code: 'a' })
|
508
|
+
condition0 = subqueries[0][:condition]
|
509
|
+
expect(condition0[:operator]).to eq('?')
|
510
|
+
expect(condition0[:right][:selector]).to eq({ code: 'f' })
|
511
|
+
|
512
|
+
expect(subqueries[1][:selector]).to eq({ code: 'b' })
|
513
|
+
|
514
|
+
expect(subqueries[2][:selector]).to eq({ code: 'c' })
|
515
|
+
|
516
|
+
expect(subqueries[3][:selector]).to eq({ code: 'e' })
|
517
|
+
condition3 = subqueries[3][:condition]
|
518
|
+
expect(condition3[:left][:selector]).to eq({ code: 'f' })
|
519
|
+
expect(condition3[:operator]).to eq('=')
|
520
|
+
expect(condition3[:right]).to eq({ comparison_string: 'q' })
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
describe 'indicators with conditions' do
|
525
|
+
it 'handles plain tags' do
|
526
|
+
aggregate_failures do
|
527
|
+
tags.each do |tag|
|
528
|
+
inds.each do |ind|
|
529
|
+
val = "#{tag}^#{ind}{=\\a}"
|
530
|
+
expect(parser).to parse(val)
|
531
|
+
result = parse_with(parser, val)
|
532
|
+
expect(result[:tag]).to eq(tag)
|
533
|
+
selector = result[:selector]
|
534
|
+
expect(selector[:ind]).to eq(ind)
|
535
|
+
condition = result[:condition]
|
536
|
+
expect(condition[:operator]).to eq('=')
|
537
|
+
expect(condition[:right][:comparison_string]).to eq('a')
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|