defmastership-core 1.1.0 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e02b53e306be26b56798011f57225ffce2c03d247faab3846375b2279e87c2fa
4
- data.tar.gz: 5c236cdea358de4137c53667dd9a4c42ae3fcdffde9298977a5b56f14dd36b07
3
+ metadata.gz: '034357962fd2a1625b213b5ed29b83bd7cc9a659c24b1b0a8f5b202dea47113a'
4
+ data.tar.gz: d32796f5f8cb5eef96568e35011a09033badccb5d7708c3077ccd9519df71228
5
5
  SHA512:
6
- metadata.gz: 479cfc833f1a4e2364e5f620cfee9b66dc5847636182aefcdc779a4c8a465a9eb0335e740fe3eff5d148fb96b8b38401d80617b02462cd4bd882387645f8a3a6
7
- data.tar.gz: 5e498d2697e36fc40ee377308611c44b4323230082d0e071f05d604b398042cbd5eb0e87d1663a619441e2077d851fdcbf3a120b1648eab2e0cc00b63e196c63
6
+ metadata.gz: 04b9343450b59869b5100144cbf1ec8388ff72cfba713be83be2292b81a6f55e20e087fec8b91f3b49a63df88a2312cc9bdffca4f415c401581167021b60738a
7
+ data.tar.gz: 979b8eed01f02b85ff4d2b314779c4210cd8372e6f901335662163d72c2135d480e3af501702de4a5ed88ab29410e3aa7cc58598133cdd2204e61ad83fc41c71
@@ -7,60 +7,102 @@ module Defmastership
7
7
  # set of regexp of added asciidoctor constructions
8
8
  # This module smells of :reek:TooManyConstants
9
9
  module DMRegexp
10
+ # generic regexp pattern for ids
11
+ #
12
+ # @param backref_name [String] set the name of the id's backref
13
+ def self.an_id(backref_name)
14
+ "(?<#{backref_name}>[\\w-]+)"
15
+ end
16
+
10
17
  # [Regexp] to match a single line comment
11
18
  SINGLE_LINE_COMMENT = %r{^//[^/]}.freeze
12
19
  public_constant :SINGLE_LINE_COMMENT
13
20
 
21
+ # [Regexp] match the definition keyword
22
+ DEF_KEYWORD = '\s*define\s*'
23
+ public_constant :DEF_KEYWORD
24
+
25
+ # [Regexp] match a definition type
26
+ DEF_TYPE = ",\\s*#{an_id('type')}\\s*"
27
+ public_constant :DEF_TYPE
28
+
14
29
  # [Regexp] match all text before the definition's reference
15
- DEF_BEFORE_REF = <<~'BEF'
16
- ^\s*
17
- \[\s*define\s*,
18
- \s*(?<type>[\w:_-]+)\s*,
19
- \s*
30
+ DEF_BEFORE_REF = <<~"BEF"
31
+ ^
32
+ \\s*
33
+ \\[
34
+ #{DEF_KEYWORD}
35
+ #{DEF_TYPE}
36
+ ,
37
+ \\s*
20
38
  BEF
21
39
  public_constant :DEF_BEFORE_REF
22
40
 
23
- # [Regexp] match all text after the definition's reference
24
- DEF_AFTER_REF = <<~'AFT'
25
- \s*
26
- (,\s*\[\s*(?<labels>.*?)\s*\])?\s*\]
27
- AFT
28
- public_constant :DEF_AFTER_REF
29
-
30
41
  # [Regexp] match optional explicit version and explicit checksum
31
42
  DEF_VERSION_AND_CHECKSUM = '(?<version_and_checksum>' \
32
- '\((?<explicit_version>[^~]+)?(?<explicit_checksum>~[[:alnum:]]+)?\)' \
43
+ '\((?<explicit_version>[^~]+)?(?<explicit_checksum>~\h+)?\)' \
33
44
  ')?'
34
45
  public_constant :DEF_VERSION_AND_CHECKSUM
35
46
 
36
47
  # [Regexp] match reference
37
- REFERENCE = '(?<reference>[\\w:_-]+)'
48
+ REFERENCE = an_id('reference').freeze
38
49
  public_constant :REFERENCE
39
50
 
51
+ # [Regexp] match defintion summary
52
+ DEF_SUMMARY = '\s*(,\s*(?<summary>[^\s,\[\]][^,\[\]]*?)\s*)?'
53
+ public_constant :DEF_SUMMARY
54
+
55
+ # [Regexp] match definition labels
56
+ DEF_LABELS = '(,\s*\[\s*(?<labels>.*\b)\s*\])?'
57
+ public_constant :DEF_LABELS
58
+
59
+ # [Regexp] match all text after the definition's reference
60
+ DEF_AFTER_REF = <<~"AFT"
61
+ \\s*
62
+ #{DEF_SUMMARY}
63
+ #{DEF_LABELS}
64
+ \\s*
65
+ \\]
66
+ AFT
67
+ public_constant :DEF_AFTER_REF
68
+
40
69
  # [Regexp] match a definition line
41
- DEFINITION = Regexp.new(
42
- "#{DEF_BEFORE_REF}#{REFERENCE}#{DEF_VERSION_AND_CHECKSUM}#{DEF_AFTER_REF}",
43
- Regexp::EXTENDED
44
- )
70
+ definition_re_string = <<~"DEF"
71
+ ^
72
+ \\s*
73
+ \\[
74
+ #{DEF_KEYWORD}
75
+ #{DEF_TYPE}
76
+ ,
77
+ \\s*
78
+ #{REFERENCE}
79
+ #{DEF_VERSION_AND_CHECKSUM}
80
+ \\s*
81
+ #{DEF_SUMMARY}
82
+ #{DEF_LABELS}
83
+ \\s*
84
+ \\]
85
+ DEF
86
+ DEFINITION = Regexp.new(definition_re_string, Regexp::EXTENDED)
45
87
  public_constant :DEFINITION
46
88
 
47
89
  # [Regexp] match a asciidcotor attribute definition
48
- VARIABLE_DEF = /^\s*:(?<varname>[\w:_-]+):\s+
90
+ VARIABLE_DEF = /^\s*:#{an_id('varname')}:\s+
49
91
  (?<value>\S.*\S)\s*$/x.freeze
50
92
  public_constant :VARIABLE_DEF
51
93
 
52
94
  # [Regexp] match a asciidcotor attribute use
53
- VARIABLE_USE = /{(?<varname>[\w:_-]+)}/x.freeze
95
+ VARIABLE_USE = /{#{an_id('varname')}}/x.freeze
54
96
  public_constant :VARIABLE_USE
55
97
 
56
98
  # [Regexp] match an external cross reference type configuration
57
- EREF_CONFIG = /^\s*:eref-(?<reference>[\w:_-]+)-(?<symb>prefix|url):\s*
99
+ EREF_CONFIG = /^\s*:eref-#{an_id('reference')}-(?<symb>prefix|url):\s*
58
100
  \s*(?<value>\S.*\S)\s*/x.freeze
59
101
  public_constant :EREF_CONFIG
60
102
  # [Regexp] match an external cross reference use
61
103
  EREF_DEF = /^\s*
62
104
  defs:eref\[
63
- \s*(?<reference>[\w:_-]+)\s*,
105
+ \s*#{an_id('reference')}\s*,
64
106
  \s*\[\s*(?<extrefs>[^\]]+?)\s*\]\s*\]/x.freeze
65
107
  public_constant :EREF_DEF
66
108
 
@@ -76,19 +118,19 @@ module Defmastership
76
118
  public_constant :IREF_DEF_AFT
77
119
  # [Regexp] match an internal cross reference
78
120
  IREF_DEF = Regexp.new(
79
- "#{IREF_DEF_BEF}(?<intref>[\\w:_-]+)#{IREF_DEF_AFT}",
121
+ "#{IREF_DEF_BEF}#{an_id('intref')}#{IREF_DEF_AFT}",
80
122
  Regexp::EXTENDED
81
123
  )
82
124
  public_constant :IREF_DEF
83
125
 
84
126
  # [Regexp] match an attribute configuration
85
- ATTR_CONFIG = /\s*:attr-(?<attr>[\w:_-]+)-prefix:
127
+ ATTR_CONFIG = /\s*:attr-#{an_id('attr')}-prefix:
86
128
  \s+(?<prefix>.+?)\s*$/x.freeze
87
129
  public_constant :ATTR_CONFIG
88
130
  # [Regexp] match an attribute use
89
131
  ATTR_SET = /\s*
90
132
  defs:attribute\[
91
- \s*(?<attr>[\w:_-]+)\s*,
133
+ \s*#{an_id('attr')}\s*,
92
134
  \s*(?<value>.+?)\s*\]/x.freeze
93
135
  public_constant :ATTR_SET
94
136
 
@@ -101,13 +143,13 @@ module Defmastership
101
143
  public_constant :WHATEVER
102
144
 
103
145
  # [Regexp] match asciidoc include statement keyword
104
- INCLUDE_KEYWORD = '\binclude::'
146
+ INCLUDE_KEYWORD = '^\s*include::'
105
147
  public_constant :INCLUDE_KEYWORD
106
148
  # [Regexp] match asciidoc include statement path
107
149
  INCLUDE_PATH = '(?<path>.*/)?'
108
150
  public_constant :INCLUDE_PATH
109
151
  # [Regexp] match asciidoc include statement filename
110
- INCLUDE_FILENAME = '(?<filename>[^\\/]+)'
152
+ INCLUDE_FILENAME = '(?<filename>[^\\\/]+)'
111
153
  public_constant :INCLUDE_FILENAME
112
154
  # [Regexp] match asciidoc include statement options
113
155
  INCLUDE_OPTIONS = '\[(?<options>[^\]]*)\]'
@@ -1,6 +1,9 @@
1
1
  # Copyright (c) 2020 Jerome Arbez-Gindre
2
2
  # frozen_string_literal: true
3
3
 
4
+ require('defmastership/core/constants')
5
+ require('defmastership/core/parsing_state')
6
+
4
7
  module Defmastership
5
8
  module Core
6
9
  # Allow to know if we need to parse the line or simply ignore it
@@ -5,7 +5,7 @@ module Defmastership
5
5
  # Common to defmastership and asciidoctor-defmastership
6
6
  module Core
7
7
  # [String] Gem version
8
- VERSION = '1.1.0'
8
+ VERSION = '1.3.0'
9
9
  public_constant :VERSION
10
10
  end
11
11
  end
data/spec/spec_helper.rb CHANGED
@@ -25,5 +25,3 @@ RSpec::Matchers.define(:matchdata_including) do |h|
25
25
  end
26
26
  end
27
27
  end
28
-
29
- require('defmastership')
@@ -0,0 +1,652 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('defmastership/core/constants')
5
+
6
+ RSpec.describe(Defmastership::Core::DMRegexp) do
7
+ describe '#an id' do
8
+ subject(:regexp) { Regexp.new("^#{described_class.an_id('backref')}$", Regexp::EXTENDED) }
9
+
10
+ context 'when valid id' do
11
+ [
12
+ 'abc',
13
+ 'abc_efg',
14
+ '_abc_efg_',
15
+ 'abc-efg',
16
+ '-abc-efg-',
17
+ '67abc123-efg12',
18
+ 'REFERENCE-0001'
19
+ ].each do |line|
20
+ it { is_expected.to(match(line)) }
21
+ end
22
+
23
+ it { expect(regexp.match('67abc123-efg12')[:backref]).to(eq('67abc123-efg12')) }
24
+
25
+ context 'when not valid id' do
26
+ [
27
+ '&abcg',
28
+ 'ab@cg',
29
+ 'abc12:3-efg'
30
+ ].each do |line|
31
+ it { is_expected.not_to(match(line)) }
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ describe 'SINGLE_LINE_COMMENT' do
38
+ subject { described_class::SINGLE_LINE_COMMENT }
39
+
40
+ context 'when the string is a single line comment' do
41
+ [
42
+ '// This is a comment',
43
+ '// This is a // comment'
44
+ ].each do |the_line|
45
+ it { is_expected.to(match(the_line)) }
46
+ end
47
+ end
48
+
49
+ context 'when the string is not a single line comment' do
50
+ [
51
+ 'This is not a comment',
52
+ ' // This is not a comment'
53
+ ].each do |the_bad_line|
54
+ it { is_expected.not_to(match(the_bad_line)) }
55
+ end
56
+ end
57
+ end
58
+
59
+ describe 'DEF_KEYWORD' do
60
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_KEYWORD}$", Regexp::EXTENDED) }
61
+
62
+ context 'with valid definition keyword' do
63
+ [
64
+ 'define',
65
+ ' define',
66
+ ' define '
67
+ ].each do |line|
68
+ it { is_expected.to(match(line)) }
69
+ end
70
+ end
71
+
72
+ context 'with invalid definition keyword' do
73
+ it { is_expected.not_to(match('defoune')) }
74
+ end
75
+ end
76
+
77
+ describe 'DEF_TYPE' do
78
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_TYPE}$", Regexp::EXTENDED) }
79
+
80
+ context 'with valid definition type' do
81
+ [
82
+ ', a_type',
83
+ ', a-type',
84
+ ', a-type '
85
+ ].each do |line|
86
+ it { is_expected.to(match(line)) }
87
+ end
88
+
89
+ it { expect(regexp.match(', a-type ')[:type]).to(eq('a-type')) }
90
+ end
91
+
92
+ context 'with invalid definition type' do
93
+ it { is_expected.not_to(match(' , a_type')) }
94
+ it { is_expected.not_to(match(', a type with blank ')) }
95
+ end
96
+ end
97
+
98
+ describe 'DEF_BEFORE_REF' do
99
+ subject(:regexp) { Regexp.new("#{described_class::DEF_BEFORE_REF}$", Regexp::EXTENDED) }
100
+
101
+ context 'when valid definitions beginning' do
102
+ [
103
+ '[define,def_type,',
104
+ ' [define,def_type,',
105
+ ' [ define,def_type,',
106
+ ' [ define, def_type,',
107
+ ' [ define, def_type, '
108
+ ].each do |def_beg|
109
+ it { is_expected.to(match(def_beg)) }
110
+ it { expect(regexp.match(def_beg)[:type]).to(eq('def_type')) }
111
+ end
112
+ end
113
+
114
+ context 'when does not match invalid definitions beginning' do
115
+ [
116
+ 'define def_type,',
117
+ '[define def_type,',
118
+ '[define, def_type',
119
+ 'something [define, def_type'
120
+ ].each do |bad_def_beg|
121
+ it { is_expected.not_to(match(bad_def_beg)) }
122
+ end
123
+ end
124
+ end
125
+
126
+ describe 'DEF_AFTER_REF' do
127
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_AFTER_REF}$", Regexp::EXTENDED) }
128
+
129
+ context 'when valid definitions end' do
130
+ [
131
+ ']',
132
+ ',[label1]]',
133
+ ', a nice summary,[label1]]',
134
+ ', a nice summary]'
135
+ ].each do |def_end|
136
+ it { is_expected.to(match(def_end)) }
137
+ end
138
+
139
+ it { expect(regexp.match(' ,[ label1 , label2 ] ]')[:labels]).to(eq('label1 , label2')) }
140
+ it { expect(regexp.match(' ,[ label1 , label2 ] ]')[:summary]).to(be_nil) }
141
+ it { expect(regexp.match(', a summary ]')[:summary]).to(eq('a summary')) }
142
+ it { expect(regexp.match(', a summary ]')[:labels]).to(be_nil) }
143
+ end
144
+
145
+ context 'when invalid definitions end' do
146
+ it { is_expected.not_to(match('whatever')) }
147
+ it { is_expected.not_to(match(',[label1]')) }
148
+ it { is_expected.not_to(match('[label1]]')) }
149
+ it { is_expected.not_to(match(',label1,label2]]')) }
150
+ end
151
+ end
152
+
153
+ describe 'DEF_VERSION_AND_CHECKSUM' do
154
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_VERSION_AND_CHECKSUM}$", Regexp::EXTENDED) }
155
+
156
+ context 'when valid input' do
157
+ context 'when version without checksum' do
158
+ it { is_expected.to(match('(abc)')) }
159
+ it { expect(regexp.match('(abc)')[:version_and_checksum]).to(eq('(abc)')) }
160
+ it { expect(regexp.match('(abc)')[:explicit_version]).to(eq('abc')) }
161
+ it { expect(regexp.match('(abc)')[:explicit_checksum]).to(be_nil) }
162
+ end
163
+
164
+ context 'when checksum without version' do
165
+ it { is_expected.to(match('(~abcd1234)')) }
166
+ it { expect(regexp.match('(~abcd1234)')[:version_and_checksum]).to(eq('(~abcd1234)')) }
167
+ it { expect(regexp.match('(~abcd1234)')[:explicit_version]).to(be_nil) }
168
+ it { expect(regexp.match('(~abcd1234)')[:explicit_checksum]).to(eq('~abcd1234')) }
169
+ it { expect(regexp.match('(~ABCD1234)')[:explicit_checksum]).to(eq('~ABCD1234')) }
170
+ end
171
+
172
+ context 'when version and checksum' do
173
+ it { is_expected.to(match('(abc~abcd1234)')) }
174
+ it { expect(regexp.match('(abc~abcd1234)')[:version_and_checksum]).to(eq('(abc~abcd1234)')) }
175
+ it { expect(regexp.match('(abc~abcd1234)')[:explicit_version]).to(eq('abc')) }
176
+ it { expect(regexp.match('(abc~abcd1234)')[:explicit_checksum]).to(eq('~abcd1234')) }
177
+ end
178
+ end
179
+
180
+ context 'when invalid input' do
181
+ it { is_expected.not_to(match('whatever')) }
182
+ it { is_expected.not_to(match('(abc~ghij1234)')) }
183
+ end
184
+ end
185
+
186
+ describe 'REFERENCE' do
187
+ subject(:regexp) { Regexp.new("^#{described_class::REFERENCE}$", Regexp::EXTENDED) }
188
+
189
+ context 'when valid definition reference' do
190
+ [
191
+ 'abc',
192
+ 'abc_efg',
193
+ '_abc_efg_',
194
+ 'abc-efg',
195
+ '-abc-efg-',
196
+ '67abc123-efg12',
197
+ 'REFERENCE-0001'
198
+ ].each do |line|
199
+ it { is_expected.to(match(line)) }
200
+ end
201
+
202
+ it { expect(regexp.match('67abc123-efg12')[:reference]).to(eq('67abc123-efg12')) }
203
+ end
204
+
205
+ context 'when not valid definition reference' do
206
+ [
207
+ '&abcg',
208
+ 'ab@cg',
209
+ 'abc12:3-efg'
210
+ ].each do |line|
211
+ it { is_expected.not_to(match(line)) }
212
+ end
213
+ end
214
+ end
215
+
216
+ describe 'DEF_SUMMARY' do
217
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_SUMMARY}$", Regexp::EXTENDED) }
218
+
219
+ context 'with valid definition summary' do
220
+ [
221
+ '',
222
+ ', bla bla bli',
223
+ ', bla bla bli ',
224
+ ' , bla bla bli '
225
+ ].each do |line|
226
+ it { is_expected.to(match(line)) }
227
+ end
228
+
229
+ it { expect(regexp.match('')[:summary]).to(be_nil) }
230
+ it { expect(regexp.match(', bla bla bli ')[:summary]).to(eq('bla bla bli')) }
231
+ end
232
+
233
+ context 'with invalid definition summary' do
234
+ it { is_expected.not_to(match('blabla without coma')) }
235
+ it { is_expected.not_to(match(', [bla bla bli')) }
236
+ it { is_expected.not_to(match(', bla bla bli]')) }
237
+ it { is_expected.not_to(match(',')) }
238
+ it { is_expected.not_to(match(', ')) }
239
+ it { is_expected.not_to(match(',,')) }
240
+ end
241
+ end
242
+
243
+ describe 'DEF_LABELS' do
244
+ subject(:regexp) { Regexp.new("^#{described_class::DEF_LABELS}$", Regexp::EXTENDED) }
245
+
246
+ context 'with valid definition labels' do
247
+ [
248
+ '',
249
+ ', [ label1 ]',
250
+ ', [ label1, label2 ]',
251
+ ', [ label1 , label2 ]',
252
+ ', [ label with blank ]'
253
+ ].each do |line|
254
+ it { is_expected.to(match(line)) }
255
+ end
256
+
257
+ it { expect(regexp.match('')[:labels]).to(be_nil) }
258
+ it { expect(regexp.match(', [ label1 , label2 ]')[:labels]).to(eq('label1 , label2')) }
259
+ end
260
+
261
+ context 'with invalid definition summary' do
262
+ it { is_expected.not_to(match(' , [ label1 , label2 ]')) }
263
+ it { is_expected.not_to(match(', [ label1 , label2 ] ')) }
264
+ it { is_expected.not_to(match(', label1 , label2 ')) }
265
+ end
266
+ end
267
+
268
+ describe 'DEFINITION' do
269
+ subject(:regexp) { described_class::DEFINITION }
270
+
271
+ context 'with valid definition lines' do
272
+ [
273
+ '[ define, definition_type, REFERENCE_0001(abcd~abcdef) ]',
274
+ '[define , definition_type, REFERENCE-0001]',
275
+ '[ define,def-type , 001-REFERENCE, [ label1, label2 ] ] ',
276
+ '[ define, def-type , REFERENCE-001 , [ label1, label2 ] ]',
277
+ '[ define, def-type , REFERENCE-001 , a summary, [ label1, label2 ] ]'
278
+ ].each do |line|
279
+ it { is_expected.to(match(line)) }
280
+ end
281
+
282
+ let(:one_match) { regexp.match('[define,type,REF_01(a~1234),a summary,[a,b]]') }
283
+
284
+ it { expect(one_match[:type]).to(eq('type')) }
285
+ it { expect(one_match[:reference]).to(eq('REF_01')) }
286
+ it { expect(one_match[:explicit_version]).to(eq('a')) }
287
+ it { expect(one_match[:explicit_checksum]).to(eq('~1234')) }
288
+ it { expect(one_match[:summary]).to(eq('a summary')) }
289
+ it { expect(one_match[:labels]).to(eq('a,b')) }
290
+ end
291
+
292
+ context 'with invalid definition lines' do
293
+ [
294
+ 'define, type, ref',
295
+ '[define type , ref]',
296
+ '[defineeee, type , ref]',
297
+ '[defineeee, type , ref, pouet, [tagada, tsointsoin]]',
298
+ '[defineeee, type , ref, [tagada, tsointsoin], pouet]'
299
+ ].each do |line|
300
+ it { is_expected.not_to(match(line)) }
301
+ end
302
+ end
303
+ end
304
+
305
+ describe 'VARIABLE_DEF' do
306
+ subject(:regexp) { described_class::VARIABLE_DEF }
307
+
308
+ context 'with valid variable definitions' do
309
+ [
310
+ ':my_var: value',
311
+ ' :my_var: value',
312
+ ':var_with_underscores: another_value',
313
+ ':var-with_dash: another_value',
314
+ ':var_with_leading_space: value',
315
+ ':var_with_trailing_space: value '
316
+ ].each do |line|
317
+ it { is_expected.to(match(line)) }
318
+ end
319
+
320
+ let(:one_match) { regexp.match(':my_nice-var: nice value ') }
321
+
322
+ it { expect(one_match[:varname]).to(eq('my_nice-var')) }
323
+ it { expect(one_match[:value]).to(eq('nice value')) }
324
+ end
325
+
326
+ context 'with invalid variable definitions' do
327
+ [
328
+ ':var_@: value',
329
+ ':var space: value',
330
+ ':var_space : value',
331
+ ':var_with:: value'
332
+ ].each do |line|
333
+ it { is_expected.not_to(match(line)) }
334
+ end
335
+ end
336
+ end
337
+
338
+ describe 'VARIABLE_USE' do
339
+ subject(:regexp) { described_class::VARIABLE_USE }
340
+
341
+ context 'with valid variable utilization' do
342
+ [
343
+ '{my_var}',
344
+ ' {my_var} ',
345
+ '{var-with_dash}'
346
+ ].each do |line|
347
+ it { is_expected.to(match(line)) }
348
+ end
349
+
350
+ let(:one_match) { regexp.match(' {my_nice-var} ') }
351
+
352
+ it { expect(one_match[:varname]).to(eq('my_nice-var')) }
353
+ end
354
+
355
+ context 'with invalid variable definitions' do
356
+ [
357
+ '{var_@}',
358
+ '{var space}',
359
+ '{var_space }',
360
+ '{var_with:}'
361
+ ].each do |line|
362
+ it { is_expected.not_to(match(line)) }
363
+ end
364
+ end
365
+ end
366
+
367
+ describe 'EREF_CONFIG' do
368
+ subject(:regexp) { described_class::EREF_CONFIG }
369
+
370
+ context 'with valid external ref configuration' do
371
+ let(:one_match_prefix) { regexp.match(' :eref-something-prefix: a_prefix ') }
372
+ let(:one_match_url) { regexp.match(':eref-something-url: an url ') }
373
+
374
+ [
375
+ ':eref-something-prefix: a_prefix',
376
+ ':eref-something-url: a_url',
377
+ ' :eref-something-url: a_url'
378
+ ].each do |line|
379
+ it { is_expected.to(match(line)) }
380
+ end
381
+
382
+ it { expect(one_match_prefix[:reference]).to(eq('something')) }
383
+ it { expect(one_match_prefix[:symb]).to(eq('prefix')) }
384
+ it { expect(one_match_prefix[:value]).to(eq('a_prefix')) }
385
+
386
+ it { expect(one_match_url[:reference]).to(eq('something')) }
387
+ it { expect(one_match_url[:symb]).to(eq('url')) }
388
+ it { expect(one_match_url[:value]).to(eq('an url')) }
389
+ end
390
+
391
+ context 'with invalid ref configuration' do
392
+ [
393
+ ':eref-something-plop: a_prefix',
394
+ ': eref-something-prefix: a_prefix',
395
+ ':eref-something-prefix : a_prefix',
396
+ ':eref- something-prefix: a_prefix',
397
+ ':eref-something -prefix: a_prefix',
398
+ ':eref-something- prefix: a_prefix'
399
+ ].each do |line|
400
+ it { is_expected.not_to(match(line)) }
401
+ end
402
+ end
403
+ end
404
+
405
+ describe 'EREF_DEF' do
406
+ subject(:regexp) { described_class::EREF_DEF }
407
+
408
+ let(:one_match) { regexp.match('defs:eref[abcdef, [ABC, EDF]]') }
409
+
410
+ context 'with valid external ref' do
411
+ [
412
+ 'defs:eref[abcdef, [ABC, EDF]]',
413
+ ' defs:eref[abcdef, [ABC, EDF]]',
414
+ 'defs:eref[ abcdef, [ABC, EDF]]',
415
+ 'defs:eref[abcdef,[ABC,EDF]]',
416
+ 'defs:eref[abcdef, [ABC, EDF] ]',
417
+ 'defs:eref[abcdef, [ABC, EDF ]]',
418
+ 'defs:eref[abcdef, [ABC]]'
419
+ ].each do |line|
420
+ it { is_expected.to(match(line)) }
421
+ end
422
+
423
+ it { expect(one_match[:reference]).to(eq('abcdef')) }
424
+ it { expect(one_match[:extrefs]).to(eq('ABC, EDF')) }
425
+ end
426
+
427
+ context 'with invalid external ref' do
428
+ [
429
+ 'defs :eref[abcdef, [ABC, EDF]]',
430
+ 'defs: eref[abcdef, [ABC, EDF]]',
431
+ 'defs:eref [abcdef, [ABC, EDF]]'
432
+ ].each do |line|
433
+ it { is_expected.not_to(match(line)) }
434
+ end
435
+ end
436
+ end
437
+
438
+ describe 'BLOCK' do
439
+ subject(:regexp) { described_class::BLOCK }
440
+
441
+ context 'with valid block delimiter' do
442
+ it { is_expected.to(match('--')) }
443
+ it { is_expected.to(match('-- ')) }
444
+ end
445
+
446
+ context 'with invalid block delimiter' do
447
+ it { is_expected.not_to(match(' --')) }
448
+ it { is_expected.not_to(match('-- qsdqsd')) }
449
+ end
450
+ end
451
+
452
+ describe 'IREF_DEF_BEF' do
453
+ subject(:regexp) { Regexp.new("^#{described_class::IREF_DEF_BEF}$") }
454
+
455
+ context 'with valid IREF_DEF_BEF' do
456
+ it { is_expected.to(match('defs:iref[')) }
457
+ it { is_expected.to(match('defs:iref[ ')) }
458
+ end
459
+
460
+ context 'with invalid IREF_DEF_BEF' do
461
+ it { is_expected.not_to(match(' defs:iref[')) }
462
+ it { is_expected.not_to(match('defs :iref[')) }
463
+ it { is_expected.not_to(match('defs: iref[')) }
464
+ it { is_expected.not_to(match('defs:iref [')) }
465
+ it { is_expected.not_to(match('defs:iref[ a')) }
466
+ end
467
+ end
468
+
469
+ describe 'IREF_DEF_AFT' do
470
+ subject(:regexp) { Regexp.new("^#{described_class::IREF_DEF_AFT}$") }
471
+
472
+ context 'with valid IREF_DEF_AFT' do
473
+ it { is_expected.to(match(']')) }
474
+ it { is_expected.to(match(' ]')) }
475
+ end
476
+
477
+ context 'with invalid IREF_DEF_AFT' do
478
+ it { is_expected.not_to(match('a]')) }
479
+ it { is_expected.not_to(match('] ')) }
480
+ end
481
+ end
482
+
483
+ describe 'IREF_DEF' do
484
+ subject(:regexp) { described_class::IREF_DEF }
485
+
486
+ context 'with valid IREF_DEF' do
487
+ it { is_expected.to(match('defs:iref[blabla]')) }
488
+ it { is_expected.to(match('defs:iref[bla-bla]')) }
489
+ it { is_expected.to(match('defs:iref[bla_bla]')) }
490
+ it { is_expected.to(match(' defs:iref[bla_bla]')) }
491
+ it { is_expected.to(match(' defs:iref[ bla_bla]')) }
492
+ it { is_expected.to(match(' defs:iref[ bla_bla ]')) }
493
+ it { is_expected.to(match(' defs:iref[ bla_bla ] ')) }
494
+
495
+ it { expect(regexp.match(' defs:iref[ bla_bla ] ')[:intref]).to(eq('bla_bla')) }
496
+ end
497
+
498
+ context 'with invalid IREF_DEF' do
499
+ it { is_expected.not_to(match('defs :iref[blabla]')) }
500
+ it { is_expected.not_to(match('defs: iref[blabla]')) }
501
+ it { is_expected.not_to(match('defs:iref [blabla]')) }
502
+ end
503
+ end
504
+
505
+ describe 'ATTR_CONFIG' do
506
+ subject(:regexp) { described_class::ATTR_CONFIG }
507
+
508
+ context 'when valid attribute configuration' do
509
+ it { is_expected.to(match(':attr-my_attribute-prefix: my_prefix')) }
510
+ it { is_expected.to(match(':attr-my-attribute-prefix: my blala prefix')) }
511
+ it { expect(regexp.match(':attr-my_attribute-prefix: my_prefix')[:attr]).to(eq('my_attribute')) }
512
+ it { expect(regexp.match(':attr-my_attribute-prefix: my_prefix')[:prefix]).to(eq('my_prefix')) }
513
+ it { expect(regexp.match(':attr-my_attribute-prefix: with blank: ')[:prefix]).to(eq('with blank:')) }
514
+ end
515
+
516
+ context 'when invalid attribute configuration' do
517
+ it { is_expected.not_to(match('attr-my_attribute-prefix: my_prefix')) }
518
+ it { is_expected.not_to(match(':atttr-my_attribute-prefix: my_prefix')) }
519
+ it { is_expected.not_to(match(':attr-my_attribute-prefixx: my_prefix')) }
520
+ it { is_expected.not_to(match(':attr-my_attribute-prefix : my_prefix')) }
521
+ it { is_expected.not_to(match(':attr-my_attribute-prefix: ')) }
522
+ end
523
+ end
524
+
525
+ describe 'ATTR_SET' do
526
+ subject(:regexp) { described_class::ATTR_SET }
527
+
528
+ context 'when valid attribute setting' do
529
+ it { is_expected.to(match('defs:attribute[my-attribute, attr value]')) }
530
+ it { is_expected.to(match('defs:attribute[ my-attribute, attr value]')) }
531
+ it { is_expected.to(match('defs:attribute[my-attribute , attr value]')) }
532
+ it { is_expected.to(match('defs:attribute[my-attribute, attr value ]')) }
533
+ it { is_expected.to(match('defs:attribute[ my-attribute , attr value ]')) }
534
+ it { expect(regexp.match('defs:attribute[ my-attribute , attr value ]')[:attr]).to(eq('my-attribute')) }
535
+ it { expect(regexp.match('defs:attribute[ my-attribute , attr value ]')[:value]).to(eq('attr value')) }
536
+ end
537
+
538
+ context 'when invalid attribute setting' do
539
+ it { is_expected.not_to(match('defs :attribute[my-attribute, attr value]')) }
540
+ it { is_expected.not_to(match('defs: attribute[my-attribute, attr value]')) }
541
+ it { is_expected.not_to(match('defs:attribute [my-attribute, attr value]')) }
542
+ it { is_expected.not_to(match('defs:attribute[my@attribute, attr value]')) }
543
+ end
544
+ end
545
+
546
+ describe 'EMPTY_LINE' do
547
+ subject(:regexp) { described_class::EMPTY_LINE }
548
+
549
+ context 'when valid empty line' do
550
+ it { is_expected.to(match('')) }
551
+ it { is_expected.to(match(' ')) }
552
+ it { is_expected.to(match(" \t ")) }
553
+ end
554
+
555
+ context 'when invalid empty match' do
556
+ it { is_expected.not_to(match(' a ')) }
557
+ end
558
+ end
559
+
560
+ describe 'WHATEVER' do
561
+ subject(:regexp) { described_class::WHATEVER }
562
+
563
+ context 'when matching everything' do
564
+ it { is_expected.to(match('')) }
565
+ it { is_expected.to(match('qsdqsd')) }
566
+ it { is_expected.to(match(" \t qsdqsd \n qsdqsd ")) }
567
+ end
568
+ end
569
+
570
+ describe 'INCLUDE_KEYWORD' do
571
+ subject(:regexp) { Regexp.new("#{described_class::INCLUDE_KEYWORD}$") }
572
+
573
+ context 'when matching include keyword' do
574
+ it { is_expected.to(match('include::')) }
575
+ it { is_expected.to(match(' include::')) }
576
+ end
577
+
578
+ context 'when not matching bad include keyword' do
579
+ it { is_expected.not_to(match(' _include::')) }
580
+ it { is_expected.not_to(match(' a include::')) }
581
+ it { is_expected.not_to(match(' -include::')) }
582
+ end
583
+ end
584
+
585
+ describe 'INCLUDE_PATH' do
586
+ subject(:regexp) { Regexp.new("^#{described_class::INCLUDE_PATH}$") }
587
+
588
+ context 'when matching include path' do
589
+ it { is_expected.to(match('')) }
590
+ it { is_expected.to(match('bla bla/')) }
591
+ it { is_expected.to(match('bla //// bla/')) }
592
+ it { is_expected.to(match(' bla //// bla/')) }
593
+ it { expect(regexp.match(' bla //// bla/')[:path]).to(eq(' bla //// bla/')) }
594
+ it { expect(regexp.match('')[:path]).to(be_nil) }
595
+ end
596
+
597
+ context 'when not matching bad include path' do
598
+ it { is_expected.not_to(match('bla bla')) }
599
+ it { is_expected.not_to(match('bla bla/ ')) }
600
+ end
601
+ end
602
+
603
+ describe 'INCLUDE_FILENAME' do
604
+ subject(:regexp) { Regexp.new("^#{described_class::INCLUDE_FILENAME}$") }
605
+
606
+ context 'when matching valid filename' do
607
+ it { is_expected.to(match('bla bla @ -')) }
608
+ it { expect(regexp.match('bla bla @ -')[:filename]).to(eq('bla bla @ -')) }
609
+ end
610
+
611
+ context 'when not matching bad filename' do
612
+ it { is_expected.not_to(match('')) }
613
+ it { is_expected.not_to(match('bla / bla')) }
614
+ it { is_expected.not_to(match('bla \ bla ')) }
615
+ end
616
+ end
617
+
618
+ describe 'INCLUDE_OPTIONS' do
619
+ subject(:regexp) { Regexp.new("^#{described_class::INCLUDE_OPTIONS}$") }
620
+
621
+ context 'when matching include options' do
622
+ it { is_expected.to(match('[]')) }
623
+ it { is_expected.to(match('[whatever qsddl qmlsdkml qsdl]')) }
624
+ it { expect(regexp.match('[]')[:options]).to(eq('')) }
625
+ it { expect(regexp.match('[whatever blabla ]')[:options]).to(eq('whatever blabla ')) }
626
+ end
627
+
628
+ context 'when not matching bad include options' do
629
+ it { is_expected.not_to(match('[whatever]]')) }
630
+ it { is_expected.not_to(match('[whate]ver]')) }
631
+ end
632
+ end
633
+
634
+ describe 'INCLUDE' do
635
+ subject(:regexp) { described_class::INCLUDE }
636
+
637
+ context 'when matching include statement' do
638
+ let(:line) { 'include::my path/my filename[my options]' }
639
+
640
+ it { is_expected.to(match(line)) }
641
+ it { expect(regexp.match(line)[:path]).to(eq('my path/')) }
642
+ it { expect(regexp.match(line)[:filename]).to(eq('my filename')) }
643
+ it { expect(regexp.match(line)[:options]).to(eq('my options')) }
644
+ end
645
+
646
+ context 'when not matching bad include statement' do
647
+ it { is_expected.not_to(match('a include::my path/my filename[my options]')) }
648
+ it { is_expected.not_to(match('include::my path/my\ filename[my options]')) }
649
+ it { is_expected.not_to(match('include::my path/[my options]')) }
650
+ end
651
+ end
652
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defmastership-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jérôme Arbez-Gindre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-16 00:00:00.000000000 Z
11
+ date: 2024-12-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: jeromearbezgindre@gmail.com
@@ -28,11 +28,11 @@ files:
28
28
  - config/rspec
29
29
  - config/rubocop.yml
30
30
  - defmastership-core.gemspec
31
- - lib/defmastership.rb
32
31
  - lib/defmastership/core/constants.rb
33
32
  - lib/defmastership/core/parsing_state.rb
34
33
  - lib/defmastership/core/version.rb
35
34
  - spec/spec_helper.rb
35
+ - spec/unit/defmastership/core/dm_regexp_spec.rb
36
36
  - spec/unit/defmastership/core/parsing_state_spec.rb
37
37
  - spec/unit/defmastership/core_spec.rb
38
38
  - tasks/code_quality.rake
@@ -61,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  requirements: []
64
- rubygems_version: 3.5.22
64
+ rubygems_version: 3.5.23
65
65
  signing_key:
66
66
  specification_version: 4
67
67
  summary: Handling of references and definitions with asciidoctor - common code
data/lib/defmastership.rb DELETED
@@ -1,9 +0,0 @@
1
- # Copyright (c) 2020 Jerome Arbez-Gindre
2
- # frozen_string_literal: true
3
-
4
- require('defmastership/core/version')
5
-
6
- # Add requires for other files you add to your project here, so
7
- # you just need to require this one file in your bin file
8
- require('defmastership/core/constants')
9
- require('defmastership/core/parsing_state')