defmastership 1.0.6 → 1.0.11

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/bin/defmastership +12 -7
  3. data/features/changeref.feature +33 -0
  4. data/features/definition_checksum.feature +298 -0
  5. data/features/definition_version.feature +204 -0
  6. data/features/export.feature +21 -74
  7. data/features/modify.feature +23 -1
  8. data/lib/defmastership.rb +6 -0
  9. data/lib/defmastership/batch_modifier.rb +2 -0
  10. data/lib/defmastership/change_ref_line_modifier.rb +2 -1
  11. data/lib/defmastership/change_ref_modifier.rb +2 -2
  12. data/lib/defmastership/constants.rb +4 -2
  13. data/lib/defmastership/csv_formatter.rb +12 -6
  14. data/lib/defmastership/csv_formatter_body.rb +8 -5
  15. data/lib/defmastership/csv_formatter_header.rb +5 -1
  16. data/lib/defmastership/definition.rb +4 -4
  17. data/lib/defmastership/document.rb +33 -27
  18. data/lib/defmastership/modifier_base.rb +1 -1
  19. data/lib/defmastership/rename_included_files_modifier.rb +2 -17
  20. data/lib/defmastership/update_def_checksum_line_modifier.rb +38 -0
  21. data/lib/defmastership/update_def_checksum_modifier.rb +21 -0
  22. data/lib/defmastership/update_def_version_line_modifier.rb +58 -0
  23. data/lib/defmastership/update_def_version_modifier.rb +25 -0
  24. data/lib/defmastership/version.rb +1 -1
  25. data/spec/unit/defmastership/batch_modifier_spec.rb +8 -0
  26. data/spec/unit/defmastership/change_ref_line_modifier_spec.rb +15 -0
  27. data/spec/unit/defmastership/csv_formatter_body_spec.rb +42 -60
  28. data/spec/unit/defmastership/csv_formatter_header_spec.rb +23 -1
  29. data/spec/unit/defmastership/csv_formatter_spec.rb +204 -67
  30. data/spec/unit/defmastership/definition_spec.rb +19 -4
  31. data/spec/unit/defmastership/document_spec.rb +129 -5
  32. data/spec/unit/defmastership/update_def_checksum_line_modifier_spec.rb +78 -0
  33. data/spec/unit/defmastership/update_def_checksum_modifier_spec.rb +75 -0
  34. data/spec/unit/defmastership/update_def_version_line_modifier_spec.rb +127 -0
  35. data/spec/unit/defmastership/update_def_version_modifier_spec.rb +80 -0
  36. metadata +12 -2
@@ -23,6 +23,7 @@ RSpec.describe(DefMastership::Definition) do
23
23
  it { is_expected.to(have_attributes(attributes: {})) }
24
24
  it { is_expected.to(have_attributes(labels: Set.new)) }
25
25
  it { is_expected.to(have_attributes(wrong_explicit_checksum: nil)) }
26
+ it { is_expected.to(have_attributes(explicit_version: nil)) }
26
27
  end
27
28
 
28
29
  context 'with labels' do
@@ -42,13 +43,13 @@ RSpec.describe(DefMastership::Definition) do
42
43
  described_class.new(
43
44
  type: 'req',
44
45
  reference: 'TUTU-001',
45
- explicit_checksum: '8cc259e6'
46
+ explicit_checksum: '~8cc259e6'
46
47
  )
47
48
  end
48
49
 
49
50
  it do
50
- definition << 'def value with a checksum != 8cc259e6'
51
- expect(definition).to(have_attributes(wrong_explicit_checksum: '8cc259e6'))
51
+ definition << 'def value with a checksum != ~8cc259e6'
52
+ expect(definition).to(have_attributes(wrong_explicit_checksum: '~8cc259e6'))
52
53
  end
53
54
 
54
55
  it do
@@ -56,6 +57,20 @@ RSpec.describe(DefMastership::Definition) do
56
57
  expect(definition).to(have_attributes(wrong_explicit_checksum: nil))
57
58
  end
58
59
  end
60
+
61
+ context 'with explicit_version' do
62
+ subject(:definition) do
63
+ described_class.new(
64
+ type: 'req',
65
+ reference: 'TUTU-001',
66
+ explicit_version: 'pouet'
67
+ )
68
+ end
69
+
70
+ it do
71
+ expect(definition).to(have_attributes(explicit_version: 'pouet'))
72
+ end
73
+ end
59
74
  end
60
75
 
61
76
  describe '#<<' do
@@ -88,7 +103,7 @@ RSpec.describe(DefMastership::Definition) do
88
103
 
89
104
  it 'calculates sha256 of value' do
90
105
  definition << 'first line' << 'second line'
91
- expect(definition.sha256).to(eq('beb0535a'))
106
+ expect(definition.sha256).to(eq('~beb0535a'))
92
107
  end
93
108
  end
94
109
 
@@ -52,12 +52,12 @@ RSpec.describe(DefMastership::Document) do
52
52
  end
53
53
 
54
54
  context 'when simple definition line with explicit checksum' do
55
- let(:input_lines) { ['[define, requirement, TOTO-0001(ab12)]'] }
55
+ let(:input_lines) { ['[define, requirement, TOTO-0001(~ab12)]'] }
56
56
 
57
57
  before do
58
58
  allow(DefMastership::Definition).to(
59
59
  receive(:new).with(
60
- matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_checksum: 'ab12')
60
+ matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_checksum: '~ab12')
61
61
  ).and_return(definition)
62
62
  )
63
63
  document.parse(input_lines)
@@ -66,7 +66,28 @@ RSpec.describe(DefMastership::Document) do
66
66
  it do
67
67
  expect(DefMastership::Definition).to(
68
68
  have_received(:new).with(
69
- matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_checksum: 'ab12')
69
+ matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_checksum: '~ab12')
70
+ )
71
+ )
72
+ end
73
+ end
74
+
75
+ context 'when simple definition line with explicit version' do
76
+ let(:input_lines) { ['[define, requirement, TOTO-0001(pouet)]'] }
77
+
78
+ before do
79
+ allow(DefMastership::Definition).to(
80
+ receive(:new).with(
81
+ matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_version: 'pouet')
82
+ ).and_return(definition)
83
+ )
84
+ document.parse(input_lines)
85
+ end
86
+
87
+ it do
88
+ expect(DefMastership::Definition).to(
89
+ have_received(:new).with(
90
+ matchdata_including(type: 'requirement', reference: 'TOTO-0001', explicit_version: 'pouet')
70
91
  )
71
92
  )
72
93
  end
@@ -426,9 +447,38 @@ RSpec.describe(DefMastership::Document) do
426
447
  end
427
448
  end
428
449
 
429
- describe '#wrong_explicit_checksum?' do
430
- subject(:document) { described_class.new }
450
+ describe '#parse_file_with_preprocessor' do
451
+ let(:definition) { instance_double(DefMastership::Definition, 'definition') }
452
+ let(:input_lines) { ['[define, requirement, TOTO-0001]'] }
453
+ let(:adoc_doc) { instance_double(Asciidoctor::Document, 'adoc_doc') }
454
+ let(:adoc_reader) { instance_double(Asciidoctor::Reader, 'adoc_reader') }
455
+
456
+ before do
457
+ allow(Asciidoctor).to(
458
+ receive(:load_file).with('the_file.adoc', { parse: false, safe: :unsafe }).and_return(adoc_doc)
459
+ )
460
+ allow(adoc_doc).to(receive(:reader).and_return(adoc_reader))
461
+ allow(adoc_reader).to(receive(:read_lines).and_return(input_lines))
462
+ allow(DefMastership::Definition).to(receive(:new).and_return(definition))
463
+ allow(definition).to(receive(:<<).and_return(definition))
464
+ allow(definition).to(receive(:labels).and_return(Set.new))
465
+ document.parse_file_with_preprocessor('the_file.adoc')
466
+ end
467
+
468
+ it { expect(Asciidoctor).to(have_received(:load_file).with('the_file.adoc', { parse: false, safe: :unsafe })) }
469
+ it { expect(adoc_doc).to(have_received(:reader).with(no_args)) }
470
+ it { expect(adoc_reader).to(have_received(:read_lines).with(no_args)) }
471
+
472
+ it do
473
+ expect(DefMastership::Definition).to(
474
+ have_received(:new).with(
475
+ matchdata_including(type: 'requirement', reference: 'TOTO-0001')
476
+ )
477
+ )
478
+ end
479
+ end
431
480
 
481
+ describe '#wrong_explicit_checksum?' do
432
482
  let(:def1) { instance_double(DefMastership::Definition, 'definition') }
433
483
  let(:def2) { instance_double(DefMastership::Definition, 'definition') }
434
484
  let(:input_lines) do
@@ -473,4 +523,78 @@ RSpec.describe(DefMastership::Document) do
473
523
  it { expect(document.wrong_explicit_checksum?).to(eq(true)) }
474
524
  end
475
525
  end
526
+
527
+ describe '#explicit_version?' do
528
+ let(:def1) { instance_double(DefMastership::Definition, 'definition') }
529
+ let(:def2) { instance_double(DefMastership::Definition, 'definition') }
530
+ let(:input_lines) do
531
+ [
532
+ '[define, requirement, TOTO-0001]',
533
+ 'def one',
534
+ '',
535
+ '[define, requirement, TOTO-0002]',
536
+ 'def two'
537
+ ]
538
+ end
539
+
540
+ before do
541
+ allow(DefMastership::Definition).to(receive(:new).twice.and_return(def1, def2))
542
+ allow(def1).to(receive(:labels)).and_return([])
543
+ allow(def2).to(receive(:labels)).and_return([])
544
+ allow(def1).to(receive(:<<).and_return(def1))
545
+ allow(def2).to(receive(:<<).and_return(def2))
546
+ end
547
+
548
+ context 'when no explicit version' do
549
+ before do
550
+ allow(def1).to(receive(:explicit_version)).and_return(nil)
551
+ allow(def2).to(receive(:explicit_version)).and_return(nil)
552
+ document.parse(input_lines)
553
+ document.explicit_version?
554
+ end
555
+
556
+ it { expect(def1).to(have_received(:explicit_version)) }
557
+ it { expect(def2).to(have_received(:explicit_version)) }
558
+ it { expect(document.explicit_version?).to(eq(false)) }
559
+ end
560
+
561
+ context 'when one req has explicit version' do
562
+ before do
563
+ allow(def1).to(receive(:explicit_version)).and_return(nil)
564
+ allow(def2).to(receive(:explicit_version)).and_return('toto')
565
+ document.parse(input_lines)
566
+ document.explicit_version?
567
+ end
568
+
569
+ it { expect(document.explicit_version?).to(eq(true)) }
570
+ end
571
+ end
572
+
573
+ describe '#ref_to_def?' do
574
+ let(:def1) { instance_double(DefMastership::Definition, 'definition') }
575
+ let(:def2) { instance_double(DefMastership::Definition, 'definition') }
576
+ let(:input_lines) do
577
+ [
578
+ '[define, requirement, TOTO-0001]',
579
+ 'def one',
580
+ '',
581
+ '[define, requirement, TOTO-0002(~1234)]',
582
+ 'def two'
583
+ ]
584
+ end
585
+
586
+ before do
587
+ allow(DefMastership::Definition).to(receive(:new).twice.and_return(def1, def2))
588
+ allow(def1).to(receive(:labels)).and_return([])
589
+ allow(def2).to(receive(:labels)).and_return([])
590
+ allow(def1).to(receive(:<<).and_return(def1))
591
+ allow(def2).to(receive(:<<).and_return(def2))
592
+ allow(def1).to(receive(:reference).and_return('TOTO-0001'))
593
+ allow(def2).to(receive(:reference).and_return('TOTO-0002'))
594
+ document.parse(input_lines)
595
+ end
596
+
597
+ it { expect(document.ref_to_def('TOTO-0001')).to(eq(def1)) }
598
+ it { expect(document.ref_to_def('TOTO-0002')).to(eq(def2)) }
599
+ end
476
600
  end
@@ -0,0 +1,78 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('defmastership')
5
+
6
+ RSpec.describe(DefMastership::UpdateDefChecksumLineModifier) do
7
+ subject(:linemodifier) { described_class.new }
8
+
9
+ describe '.new' do
10
+ it { is_expected.not_to(be(nil)) }
11
+ it { is_expected.to(have_attributes(def_type: '')) }
12
+ it { is_expected.to(have_attributes(changes: [])) }
13
+ it { expect { linemodifier.user_defined_attribute }.to(raise_error(NoMethodError)) }
14
+ end
15
+
16
+ describe '.from_config' do
17
+ subject(:linemodifier) do
18
+ described_class.from_config(
19
+ def_type: 'requirement'
20
+ )
21
+ end
22
+
23
+ it { is_expected.not_to(be(nil)) }
24
+ it { is_expected.to(have_attributes(def_type: 'requirement')) }
25
+ it { is_expected.to(have_attributes(document: nil)) }
26
+ end
27
+
28
+ describe '#replace' do
29
+ subject(:linemodifier) do
30
+ described_class.from_config(
31
+ def_type: 'requirement'
32
+ )
33
+ end
34
+
35
+ let(:definition) { instance_double(DefMastership::Definition, 'definition') }
36
+ let(:document) { instance_double(DefMastership::Document, 'document') }
37
+ let(:definitions) { { 'REFERENCE' => definition } }
38
+
39
+ before do
40
+ linemodifier.document = document
41
+ allow(File).to(receive(:rename))
42
+ end
43
+
44
+ context 'when definition has not the good type' do
45
+ it do
46
+ expect(linemodifier.replace('[define,req,REFERENCE]'))
47
+ .to(eq('[define,req,REFERENCE]'))
48
+ end
49
+ end
50
+
51
+ context 'when definition has the good type' do
52
+ before do
53
+ allow(document).to(receive(:ref_to_def).with('REFERENCE').and_return(definition))
54
+ allow(definition).to(receive(:sha256).and_return('~abcd1234'))
55
+ end
56
+
57
+ it do
58
+ expect(linemodifier.replace('[define,requirement,REFERENCE]'))
59
+ .to(eq('[define,requirement,REFERENCE(~abcd1234)]'))
60
+ end
61
+
62
+ it do
63
+ expect(linemodifier.replace('[define,requirement,REFERENCE(~bad)]'))
64
+ .to(eq('[define,requirement,REFERENCE(~abcd1234)]'))
65
+ end
66
+
67
+ it do
68
+ expect(linemodifier.replace('[define,requirement,REFERENCE(toto~bad)]'))
69
+ .to(eq('[define,requirement,REFERENCE(toto~abcd1234)]'))
70
+ end
71
+
72
+ it do
73
+ expect(linemodifier.replace('[define,requirement,REFERENCE(toto)]'))
74
+ .to(eq('[define,requirement,REFERENCE(toto~abcd1234)]'))
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,75 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('defmastership')
5
+
6
+ RSpec.describe(DefMastership::UpdateDefChecksumModifier) do
7
+ subject(:modifier) do
8
+ described_class.new(
9
+ 'fake config'
10
+ )
11
+ end
12
+
13
+ let(:adoc_texts) do
14
+ {
15
+ 'file1.adoc' => "file1 line1\nfile1 line2",
16
+ 'file2.adoc' => "file2 line1\nfile2 line2"
17
+ }
18
+ end
19
+
20
+ describe '.new' do
21
+ it { is_expected.not_to(be(nil)) }
22
+ it { is_expected.to(have_attributes(config: 'fake config')) }
23
+ it { is_expected.to(have_attributes(changes: [])) }
24
+ end
25
+
26
+ describe '#do_modifications' do
27
+ let(:line_modifier) { instance_double(DefMastership::UpdateDefChecksumLineModifier, 'lineModifier') }
28
+ let(:document) { instance_double(DefMastership::Document, 'document') }
29
+
30
+ before do
31
+ allow(DefMastership::UpdateDefChecksumLineModifier).to(
32
+ receive(:from_config).with('fake config').and_return(line_modifier)
33
+ )
34
+ allow(DefMastership::Document).to(receive(:new).and_return(document))
35
+ allow(document).to(receive(:parse_file_with_preprocessor))
36
+ allow(line_modifier).to(receive(:'document=').with(document))
37
+ allow(line_modifier).to(receive(:replace).with("file1 line1\n").and_return("new file1 line1\n"))
38
+ allow(line_modifier).to(receive(:replace).with('file1 line2').and_return('new file1 line2'))
39
+ allow(line_modifier).to(receive(:replace).with("file2 line1\n").and_return("new file2 line1\n"))
40
+ allow(line_modifier).to(receive(:replace).with('file2 line2').and_return('new file2 line2'))
41
+ allow(line_modifier).to(receive(:config).and_return('new fake config'))
42
+ allow(line_modifier).to(receive(:changes).and_return([%w[from1 to1], %w[from2 to2]]))
43
+ end
44
+
45
+ context 'when detailed expectations' do
46
+ before { modifier.do_modifications(adoc_texts) }
47
+
48
+ it do
49
+ expect(DefMastership::UpdateDefChecksumLineModifier).to(
50
+ have_received(:from_config).with('fake config')
51
+ )
52
+ end
53
+
54
+ it { expect(document).to(have_received(:parse_file_with_preprocessor).with('file1.adoc')) }
55
+ it { expect(document).to(have_received(:parse_file_with_preprocessor).with('file2.adoc')) }
56
+ it { expect(line_modifier).to(have_received(:'document=').with(document)) }
57
+ it { expect(line_modifier).to(have_received(:replace).with("file1 line1\n")) }
58
+ it { expect(line_modifier).to(have_received(:replace).with('file1 line2')) }
59
+ it { expect(line_modifier).to(have_received(:replace).with("file2 line1\n")) }
60
+ it { expect(line_modifier).to(have_received(:replace).with('file2 line2')) }
61
+ it { expect(line_modifier).to(have_received(:config)) }
62
+ it { expect(line_modifier).to(have_received(:changes)) }
63
+ it { is_expected.to(have_attributes(config: 'new fake config')) }
64
+ it { is_expected.to(have_attributes(changes: [%w[from1 to1], %w[from2 to2]])) }
65
+ end
66
+
67
+ it do
68
+ expected_adoc = {
69
+ 'file1.adoc' => "new file1 line1\nnew file1 line2",
70
+ 'file2.adoc' => "new file2 line1\nnew file2 line2"
71
+ }
72
+ expect(modifier.do_modifications(adoc_texts)).to(eq(expected_adoc))
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,127 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('defmastership')
5
+
6
+ RSpec.describe(DefMastership::UpdateDefVersionLineModifier) do
7
+ subject(:linemodifier) { described_class.new }
8
+
9
+ describe '.new' do
10
+ it { is_expected.not_to(be(nil)) }
11
+ it { is_expected.to(have_attributes(def_type: '')) }
12
+ it { is_expected.to(have_attributes(changes: [])) }
13
+ it { expect { linemodifier.user_defined_attribute }.to(raise_error(NoMethodError)) }
14
+ end
15
+
16
+ describe '.from_config' do
17
+ subject(:linemodifier) do
18
+ described_class.from_config(
19
+ def_type: 'requirement',
20
+ first_version: 'a'
21
+ )
22
+ end
23
+
24
+ it { is_expected.not_to(be(nil)) }
25
+ it { is_expected.to(have_attributes(def_type: 'requirement')) }
26
+ it { is_expected.to(have_attributes(first_version: 'a')) }
27
+ it { is_expected.to(have_attributes(document: nil)) }
28
+ it { is_expected.to(have_attributes(ref_document: nil)) }
29
+ end
30
+
31
+ describe '#replace' do
32
+ subject(:linemodifier) do
33
+ described_class.from_config(
34
+ def_type: 'requirement',
35
+ first_version: 'a'
36
+ )
37
+ end
38
+
39
+ let(:document) { instance_double(DefMastership::Document, 'document') }
40
+ let(:ref_document) { instance_double(DefMastership::Document, 'ref_document') }
41
+ let(:definition) { instance_double(DefMastership::Definition, 'definition') }
42
+ let(:ref_definition) { instance_double(DefMastership::Definition, 'ref_definitions') }
43
+
44
+ before do
45
+ linemodifier.document = document
46
+ linemodifier.ref_document = ref_document
47
+ allow(File).to(receive(:rename))
48
+ end
49
+
50
+ context 'when definition has not the good type' do
51
+ it do
52
+ expect(linemodifier.replace('[define,req,REFERENCE]'))
53
+ .to(eq('[define,req,REFERENCE]'))
54
+ end
55
+ end
56
+
57
+ context 'when definition has the good type' do
58
+ before do
59
+ allow(document).to(receive(:ref_to_def).with('REFERENCE').and_return(definition))
60
+ allow(definition).to(receive(:sha256).and_return('~abcd1234'))
61
+ end
62
+
63
+ context 'when definition has NOT changed' do
64
+ before do
65
+ allow(ref_document).to(receive(:ref_to_def).with('REFERENCE').and_return(ref_definition))
66
+ allow(ref_definition).to(receive(:sha256).and_return('~abcd1234'))
67
+ end
68
+
69
+ it do
70
+ allow(ref_definition).to(receive(:explicit_version).and_return(nil))
71
+ expect(linemodifier.replace('[define,requirement,REFERENCE]'))
72
+ .to(eq('[define,requirement,REFERENCE]'))
73
+ end
74
+
75
+ it do
76
+ allow(ref_definition).to(receive(:explicit_version).and_return('c'))
77
+ expect(linemodifier.replace('[define,requirement,REFERENCE]'))
78
+ .to(eq('[define,requirement,REFERENCE(c)]'))
79
+ end
80
+
81
+ it do
82
+ allow(ref_definition).to(receive(:explicit_version).and_return('c'))
83
+ expect(linemodifier.replace('[define,requirement,REFERENCE(tyty~1234)]'))
84
+ .to(eq('[define,requirement,REFERENCE(c~1234)]'))
85
+ end
86
+ end
87
+
88
+ context 'when definition has changed' do
89
+ before do
90
+ allow(ref_document).to(receive(:ref_to_def).with('REFERENCE').and_return(ref_definition))
91
+ allow(ref_definition).to(receive(:sha256).and_return('~4321aaaa'))
92
+ end
93
+
94
+ [
95
+ [nil, '', '(a)'],
96
+ ['c', '', '(d)'],
97
+ ['c', '(tyty~1234)', '(d~1234)'],
98
+ ['2', '', '(3)'],
99
+ ['1222', '', '(1223)'],
100
+ ['abb', '', '(abc)']
101
+ ].each do |ref, from, to|
102
+ it do
103
+ allow(ref_definition).to(receive(:explicit_version).and_return(ref))
104
+ expect(linemodifier.replace("[define,requirement,REFERENCE#{from}]"))
105
+ .to(eq("[define,requirement,REFERENCE#{to}]"))
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'when definition is new' do
111
+ before do
112
+ allow(ref_document).to(receive(:ref_to_def).with('REFERENCE').and_return(nil))
113
+ end
114
+
115
+ it do
116
+ expect(linemodifier.replace('[define,requirement,REFERENCE(whatever)]'))
117
+ .to(eq('[define,requirement,REFERENCE]'))
118
+ end
119
+
120
+ it do
121
+ expect(linemodifier.replace('[define,requirement,REFERENCE(~1234)]'))
122
+ .to(eq('[define,requirement,REFERENCE(~1234)]'))
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end