defmastership 1.0.1

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 (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +63 -0
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +140 -0
  7. data/README.rdoc +6 -0
  8. data/Rakefile +53 -0
  9. data/bin/defmastership +99 -0
  10. data/config/devtools.yml +2 -0
  11. data/config/flay.yml +3 -0
  12. data/config/flog.yml +2 -0
  13. data/config/mutant.yml +6 -0
  14. data/config/reek.yml +106 -0
  15. data/config/rubocop.yml +44 -0
  16. data/config/yardstick.yml +2 -0
  17. data/defmastership.gemspec +37 -0
  18. data/defmastership.rdoc +5 -0
  19. data/features/changeref.feature +296 -0
  20. data/features/defmastership.feature +8 -0
  21. data/features/export.feature +275 -0
  22. data/features/step_definitions/defmastership_steps.rb +8 -0
  23. data/features/support/env.rb +18 -0
  24. data/lib/defmastership.rb +15 -0
  25. data/lib/defmastership/batch_changer.rb +40 -0
  26. data/lib/defmastership/comment_filter.rb +42 -0
  27. data/lib/defmastership/constants.rb +77 -0
  28. data/lib/defmastership/csv_formatter.rb +42 -0
  29. data/lib/defmastership/csv_formatter_body.rb +34 -0
  30. data/lib/defmastership/csv_formatter_header.rb +35 -0
  31. data/lib/defmastership/definition.rb +41 -0
  32. data/lib/defmastership/document.rb +153 -0
  33. data/lib/defmastership/project_ref_changer.rb +27 -0
  34. data/lib/defmastership/ref_changer.rb +102 -0
  35. data/lib/defmastership/version.rb +6 -0
  36. data/spec/spec_helper.rb +35 -0
  37. data/spec/unit/defmastership/batch_changer_spec.rb +108 -0
  38. data/spec/unit/defmastership/comment_filter_spec.rb +121 -0
  39. data/spec/unit/defmastership/csv_formatter_body_spec.rb +167 -0
  40. data/spec/unit/defmastership/csv_formatter_header_spec.rb +100 -0
  41. data/spec/unit/defmastership/csv_formatter_spec.rb +171 -0
  42. data/spec/unit/defmastership/definition_spec.rb +110 -0
  43. data/spec/unit/defmastership/document_spec.rb +398 -0
  44. data/spec/unit/defmastership/project_ref_changer_spec.rb +79 -0
  45. data/spec/unit/defmastership/ref_changer_spec.rb +205 -0
  46. data/spec/unit/defmastership_spec.rb +7 -0
  47. metadata +234 -0
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefMastership
4
+ # Change all refs of a given project
5
+ class ProjectRefChanger
6
+ attr_reader :yaml_config, :adoc_texts, :changes
7
+
8
+ def initialize(yaml_config, adoc_texts)
9
+ @yaml_config = yaml_config
10
+ @adoc_texts = adoc_texts
11
+ end
12
+
13
+ def replace_all
14
+ batch = BatchChanger.from_h(@yaml_config)
15
+
16
+ @adoc_texts =
17
+ %i[refdef irefs].reduce(@adoc_texts) do |texts, method|
18
+ texts.transform_values do |text|
19
+ text.lines.map { |line| batch.replace(method, line) }.join
20
+ end
21
+ end
22
+
23
+ @yaml_config = batch.to_h.to_yaml
24
+ @changes = batch.changes
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefMastership
4
+ # Change references from temporary to definitive
5
+ class RefChanger
6
+ attr_reader :changes
7
+
8
+ def self.from_h(hash)
9
+ new.from_h(hash)
10
+ end
11
+
12
+ REGEXP_FROM = {
13
+ definition: {
14
+ before: DMRegexp::DEF_BEFORE_REF,
15
+ after: DMRegexp::DEF_AFTER_REF
16
+ },
17
+ iref: {
18
+ before: DMRegexp::IREF_DEF_BEF,
19
+ after: DMRegexp::IREF_DEF_AFT
20
+ }
21
+ }.freeze
22
+
23
+ private_constant :REGEXP_FROM
24
+
25
+ def initialize
26
+ @h = {
27
+ from_regexp: '',
28
+ to_template: '',
29
+ next_ref: 0
30
+ }
31
+ @changes = []
32
+ @in_literal = false
33
+ end
34
+
35
+ def method_missing(method_name, *args, &block)
36
+ return @h[method_name] if @h[method_name]
37
+
38
+ super
39
+ end
40
+
41
+ def respond_to_missing?(method_name, *args)
42
+ @h[method_name] || super
43
+ end
44
+
45
+ def from_h(hash)
46
+ @h.merge!(hash)
47
+ self
48
+ end
49
+
50
+ def to_h
51
+ @h
52
+ end
53
+
54
+ def replace_refdef(line)
55
+ if in_literal(line)
56
+ line
57
+ else
58
+ do_replace_refdef(line)
59
+ end
60
+ end
61
+
62
+ def replace_irefs(line)
63
+ changes.reduce(line) do |res_line, (from, to)|
64
+ res_line.gsub(regexp_from(:iref, from)) do
65
+ text_with(Regexp.last_match, to)
66
+ end
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def regexp_from(const, from)
73
+ regexp_str =
74
+ "(?<before>#{REGEXP_FROM[const][:before]})" \
75
+ "(?<from>#{from})" \
76
+ "(?<after>#{REGEXP_FROM[const][:after]})"
77
+ Regexp.new(regexp_str, Regexp::EXTENDED)
78
+ end
79
+
80
+ def text_with(match, replacement)
81
+ match[:before] + replacement + match[:after]
82
+ end
83
+
84
+ def hmerge(match)
85
+ @h.merge(Hash[match.names.map(&:to_sym).zip(match.captures)])
86
+ end
87
+
88
+ def in_literal(line)
89
+ @in_literal ^= true if line.chomp == '....'
90
+ @in_literal
91
+ end
92
+
93
+ def do_replace_refdef(line)
94
+ line.gsub(regexp_from(:definition, from_regexp)) do
95
+ replacement = to_template % hmerge(Regexp.last_match)
96
+ changes << [Regexp.last_match[:from], replacement]
97
+ @h[:next_ref] += 1
98
+ text_with(Regexp.last_match, replacement)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DefMastership
4
+ VERSION = '1.0.1'
5
+ public_constant :VERSION
6
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('bundler/setup')
4
+ require('aruba/rspec')
5
+
6
+ # formatter = [SimpleCov::Formatter::HTMLFormatter]
7
+ # SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatter)
8
+
9
+ require('simplecov')
10
+
11
+ SimpleCov.start do
12
+ command_name 'spec:unit'
13
+
14
+ add_group 'Libraries', 'lib'
15
+ add_group 'Unit test', 'spec/unit'
16
+
17
+ add_filter 'config'
18
+ add_filter 'vendor'
19
+
20
+ minimum_coverage 100
21
+ end
22
+
23
+ RSpec.configure do |config|
24
+ config.include(Aruba::Api)
25
+ end
26
+
27
+ RSpec::Matchers.define(:matchdata_including) do |h|
28
+ match do |matchdata|
29
+ h.all? do |key, _|
30
+ matchdata[key] == h[key]
31
+ end
32
+ end
33
+ end
34
+
35
+ require('defmastership')
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('defmastership')
4
+
5
+ RSpec.describe(DefMastership::BatchChanger) do
6
+ subject(:batchchanger) { described_class.new }
7
+
8
+ describe '.new' do
9
+ it { is_expected.not_to(be(nil)) }
10
+ it { is_expected.to(have_attributes(refchangers: {})) }
11
+ end
12
+
13
+ describe '.from_h' do
14
+ before do
15
+ allow(DefMastership::RefChanger).to(receive(:from_h).once
16
+ .with(:whatever_a).and_return(:toto_a))
17
+ end
18
+
19
+ it { expect(described_class.from_h(a: :whatever_a)).not_to(be(nil)) }
20
+
21
+ it {
22
+ batchchanger = described_class.from_h(a: :whatever_a)
23
+ expect(batchchanger).to(have_attributes(refchangers: { a: :toto_a }))
24
+ }
25
+ end
26
+
27
+ describe '#from_h' do
28
+ before do
29
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:whatever_a).and_return(:one))
30
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:whatever_b).and_return(:two))
31
+ batchchanger.from_h(a: :whatever_a, b: :whatever_b)
32
+ end
33
+
34
+ it { expect(DefMastership::RefChanger).to(have_received(:from_h).with(:whatever_a)) }
35
+
36
+ it { expect(DefMastership::RefChanger).to(have_received(:from_h).with(:whatever_b)) }
37
+
38
+ it { expect(batchchanger).to(have_attributes(refchangers: { a: :one, b: :two })) }
39
+ end
40
+
41
+ describe '#to_h' do
42
+ subject(:batchchanger) { described_class.from_h(a: :a, b: :b) }
43
+
44
+ let(:refchanger_a) { instance_double(DefMastership::RefChanger, 'refchanger_a') }
45
+ let(:refchanger_b) { instance_double(DefMastership::RefChanger, 'refchanger_b') }
46
+
47
+ before do
48
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:a).and_return(refchanger_a))
49
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:b).and_return(refchanger_b))
50
+ allow(refchanger_a).to(receive(:to_h).and_return(a_a: :a_a))
51
+ allow(refchanger_b).to(receive(:to_h).and_return(b_b: :b_b))
52
+ batchchanger.to_h
53
+ end
54
+
55
+ it { expect(refchanger_a).to(have_received(:to_h)) }
56
+
57
+ it { expect(refchanger_b).to(have_received(:to_h)) }
58
+
59
+ it do
60
+ expect(batchchanger.to_h).to(eq(
61
+ a: { a_a: :a_a },
62
+ b: { b_b: :b_b }
63
+ ))
64
+ end
65
+ end
66
+
67
+ describe 'replace' do
68
+ subject(:batchchanger) { described_class.from_h(a: :a, b: :b) }
69
+
70
+ let(:refchanger_a) { instance_double(DefMastership::RefChanger, 'refchanger_a') }
71
+ let(:refchanger_b) { instance_double(DefMastership::RefChanger, 'refchanger_b') }
72
+
73
+ before do
74
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:a).and_return(refchanger_a))
75
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:b).and_return(refchanger_b))
76
+ allow(refchanger_a).to(receive(:public_send).with(:replace_toto, 'a line').and_return('b line'))
77
+ allow(refchanger_b).to(receive(:public_send).with(:replace_toto, 'b line').and_return('c line'))
78
+ batchchanger.replace(:toto, 'a line')
79
+ end
80
+
81
+ it { expect(refchanger_a).to(have_received(:public_send).with(:replace_toto, 'a line')) }
82
+
83
+ it { expect(refchanger_b).to(have_received(:public_send).with(:replace_toto, 'b line')) }
84
+
85
+ it { expect(batchchanger.replace(:toto, 'a line')).to(eq('c line')) }
86
+ end
87
+
88
+ describe 'changes' do
89
+ subject(:batchchanger) { described_class.from_h(a: :a, b: :b) }
90
+
91
+ let(:refchanger_a) { instance_double(DefMastership::RefChanger, 'refchanger_a') }
92
+ let(:refchanger_b) { instance_double(DefMastership::RefChanger, 'refchanger_b') }
93
+
94
+ before do
95
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:a).and_return(refchanger_a))
96
+ allow(DefMastership::RefChanger).to(receive(:from_h).with(:b).and_return(refchanger_b))
97
+ allow(refchanger_a).to(receive(:changes).and_return([%w[a1 a2]]))
98
+ allow(refchanger_b).to(receive(:changes).and_return([%w[b1 b2]]))
99
+ end
100
+
101
+ it do
102
+ expect(batchchanger.changes).to(eq([
103
+ %w[a1 a2],
104
+ %w[b1 b2]
105
+ ]))
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('defmastership')
4
+
5
+ RSpec.describe(DefMastership::CommentFilter) do
6
+ describe '.new' do
7
+ it { is_expected.not_to(be(nil)) }
8
+ end
9
+
10
+ describe '#accept?' do
11
+ subject(:comment_filter) { described_class.new }
12
+
13
+ context 'when no comment' do
14
+ it do
15
+ expect(comment_filter.accept?('whatever')).to(be(true))
16
+ end
17
+ end
18
+
19
+ context 'when single line comment' do
20
+ it do
21
+ expect(comment_filter.accept?('// whatever')).to(be(false))
22
+ end
23
+ end
24
+
25
+ context 'when bat formated single line comment' do
26
+ it do
27
+ expect(comment_filter.accept?('///')).to(be(true))
28
+ end
29
+ end
30
+
31
+ context 'when starting multiline comment' do
32
+ it do
33
+ expect(comment_filter.accept?('////')).to(be(false))
34
+ end
35
+ end
36
+
37
+ context 'when multiline comment' do
38
+ before do
39
+ comment_filter.accept?('////')
40
+ end
41
+
42
+ it do
43
+ expect(comment_filter.accept?('whatever')).to(be(false))
44
+ end
45
+ end
46
+
47
+ context 'when exiting multiline comment' do
48
+ before do
49
+ comment_filter.accept?('////')
50
+ comment_filter.accept?('something')
51
+ end
52
+
53
+ it do
54
+ expect(comment_filter.accept?('////')).to(be(false))
55
+ end
56
+ end
57
+
58
+ context 'when end of multiline comment' do
59
+ before do
60
+ comment_filter.accept?('////')
61
+ comment_filter.accept?('something')
62
+ comment_filter.accept?('////')
63
+ end
64
+
65
+ it do
66
+ expect(comment_filter.accept?('whatever')).to(be(true))
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'String .commented?' do
72
+ let(:comment_filter) do
73
+ instance_double(described_class, 'comment_filter')
74
+ end
75
+
76
+ before do
77
+ allow(DefMastership).to(receive(:comment_filter)
78
+ .and_return(comment_filter))
79
+ end
80
+
81
+ context 'when not .commented?' do
82
+ before do
83
+ allow(comment_filter).to(receive(:accept?).with('blabla').and_return(true))
84
+ 'blabla'.commented?
85
+ end
86
+
87
+ it { expect(DefMastership).to(have_received(:comment_filter)) }
88
+
89
+ it { expect(comment_filter).to(have_received(:accept?).with('blabla')) }
90
+
91
+ it { expect('blabla'.commented?).to(be(false)) }
92
+ end
93
+
94
+ context 'when .commented?' do
95
+ before do
96
+ allow(comment_filter).to(receive(:accept?)
97
+ .with('blabla').and_return(false))
98
+ end
99
+
100
+ it do
101
+ expect('blabla'.commented?).to(be(true))
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#reset_comments' do
107
+ before do
108
+ '////'.commented?
109
+ end
110
+
111
+ it do
112
+ expect('whatever'.commented?).to(be(true))
113
+ end
114
+
115
+ it do
116
+ '////'.commented?
117
+ DefMastership.reset_comments
118
+ expect('whatever'.commented?).to(be(false))
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('defmastership')
4
+
5
+ RSpec.describe(DefMastership::CSVFormatterBody) do
6
+ subject(:formatter) { described_class.new(document) }
7
+
8
+ let(:document) { instance_double(DefMastership::Document, 'document') }
9
+ let(:definition) { instance_double(DefMastership::Definition, 'definition') }
10
+
11
+ describe '.new' do
12
+ it { is_expected.not_to(be(nil)) }
13
+ end
14
+
15
+ describe '#fixed_body' do
16
+ before do
17
+ allow(definition).to(receive(:type).with(no_args).and_return('a'))
18
+ allow(definition).to(receive(:reference).with(no_args).and_return('b'))
19
+ allow(definition).to(receive(:value).with(no_args).and_return('c'))
20
+ formatter.fixed_body(definition)
21
+ end
22
+
23
+ it { expect(definition).to(have_received(:type).with(no_args)) }
24
+
25
+ it { expect(definition).to(have_received(:reference).with(no_args)) }
26
+
27
+ it { expect(definition).to(have_received(:value).with(no_args)) }
28
+
29
+ it { expect(formatter.fixed_body(definition)).to(eq(%w[a b c])) }
30
+ end
31
+
32
+ describe '#labels_body' do
33
+ context 'when no labels on document' do
34
+ before do
35
+ allow(document).to(receive(:labels).with(no_args).and_return([]))
36
+ formatter.labels_body(definition)
37
+ end
38
+
39
+ it { expect(document).to(have_received(:labels).once.with(no_args)) }
40
+
41
+ it { expect(formatter.labels_body(definition)).to(eq([])) }
42
+ end
43
+
44
+ context 'when labels on document' do
45
+ before { allow(document).to(receive(:labels).with(no_args).and_return(['whatever'])) }
46
+
47
+ context 'when no labels on definition' do
48
+ before do
49
+ allow(definition).to(receive(:labels).with(no_args).and_return([]))
50
+ formatter.labels_body(definition)
51
+ end
52
+
53
+ it { expect(definition).to(have_received(:labels).once.with(no_args)) }
54
+
55
+ it { expect(formatter.labels_body(definition)).to(eq([''])) }
56
+ end
57
+
58
+ context 'when labels on definition' do
59
+ before do
60
+ allow(definition).to(receive(:labels).with(no_args).and_return(%w[toto tutu]))
61
+ formatter.labels_body(definition)
62
+ end
63
+
64
+ it { expect(definition).to(have_received(:labels).once.with(no_args)) }
65
+
66
+ it { expect(formatter.labels_body(definition)).to(eq(["toto\ntutu"])) }
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#eref_body' do
72
+ context 'when no eref on the document' do
73
+ before do
74
+ allow(document).to(receive(:eref).with(no_args).and_return({}))
75
+ formatter.eref_body(definition)
76
+ end
77
+
78
+ it { expect(document).to(have_received(:eref).with(no_args)) }
79
+
80
+ it { expect(formatter.eref_body(nil)).to(eq([])) }
81
+ end
82
+
83
+ context 'when eref on the document' do
84
+ before do
85
+ allow(document).to(receive(:eref).with(no_args).and_return(
86
+ a: 'whatever',
87
+ b: 'whatever',
88
+ c: 'whatever'
89
+ ))
90
+ allow(definition).to(receive(:eref).with(no_args).and_return(a: %w[A B], b: [], c: ['C']))
91
+ formatter.eref_body(definition)
92
+ end
93
+
94
+ it { expect(definition).to(have_received(:eref).exactly(3).times.with(no_args)) }
95
+
96
+ it { expect(formatter.eref_body(definition)).to(eq(["A\nB", '', 'C'])) }
97
+ end
98
+ end
99
+
100
+ describe '#iref_body' do
101
+ context 'when no iref on the document' do
102
+ before do
103
+ allow(document).to(receive(:iref).with(no_args).and_return(false))
104
+ formatter.iref_body(definition)
105
+ end
106
+
107
+ it { expect(document).to(have_received(:iref).with(no_args)) }
108
+
109
+ it { expect(formatter.iref_body(definition)).to(eq([])) }
110
+ end
111
+
112
+ context 'when iref on the document' do
113
+ before { allow(document).to(receive(:iref).with(no_args).and_return(true)) }
114
+
115
+ context 'when no iref on the definition' do
116
+ before do
117
+ allow(definition).to(receive(:iref).with(no_args).and_return([]))
118
+ formatter.iref_body(definition)
119
+ end
120
+
121
+ it { expect(definition).to(have_received(:iref).with(no_args)) }
122
+
123
+ it { expect(formatter.iref_body(definition)).to(eq([''])) }
124
+ end
125
+
126
+ context 'when iref on the definition' do
127
+ before do
128
+ allow(definition).to(receive(:iref).with(no_args).and_return(%w[A B]))
129
+ formatter.iref_body(definition)
130
+ end
131
+
132
+ it { expect(definition).to(have_received(:iref).with(no_args)) }
133
+
134
+ it { expect(formatter.iref_body(definition)).to(eq(["A\nB"])) }
135
+ end
136
+ end
137
+ end
138
+
139
+ describe '#attributes_body' do
140
+ context 'when no attributes on the document' do
141
+ before do
142
+ allow(document).to(receive(:attributes).with(no_args).and_return({}))
143
+ formatter.attributes_body(definition)
144
+ end
145
+
146
+ it { expect(document).to(have_received(:attributes).with(no_args)) }
147
+
148
+ it { expect(formatter.attributes_body(nil)).to(eq([])) }
149
+ end
150
+
151
+ context 'when attributes on the document' do
152
+ before do
153
+ allow(document).to(receive(:attributes).with(no_args).and_return(
154
+ a: 'whatever',
155
+ b: 'whatever',
156
+ c: 'whatever'
157
+ ))
158
+ allow(definition).to(receive(:attributes).and_return(a: 'X', b: '', c: 'Y'))
159
+ formatter.attributes_body(definition)
160
+ end
161
+
162
+ it { expect(definition).to(have_received(:attributes).exactly(3).times) }
163
+
164
+ it { expect(formatter.attributes_body(definition)).to(eq(['X', '', 'Y'])) }
165
+ end
166
+ end
167
+ end