defmastership 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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