defmastership 1.3.3 → 1.3.4

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -9
  3. data/Rakefile +1 -1
  4. data/defmastership.gemspec +3 -2
  5. data/features/changeref.feature +30 -0
  6. data/features/export.feature +55 -0
  7. data/features/rename_included_files.feature +27 -0
  8. data/features/step_definitions/git_steps.rb +3 -0
  9. data/lib/defmastership/app.rb +31 -3
  10. data/lib/defmastership/export/csv/formatter.rb +8 -60
  11. data/lib/defmastership/export/formatter.rb +88 -0
  12. data/lib/defmastership/export/json/formatter.rb +34 -0
  13. data/lib/defmastership/export/xlsx/formatter.rb +87 -0
  14. data/lib/defmastership/export/yaml/formatter.rb +34 -0
  15. data/lib/defmastership/modifier/change_ref.rb +13 -5
  16. data/lib/defmastership/modifier/modifier_common.rb +4 -4
  17. data/lib/defmastership/modifier/rename_included_files.rb +7 -5
  18. data/lib/defmastership/modifier/update_def.rb +2 -1
  19. data/lib/defmastership/modifier/update_eref_common.rb +2 -1
  20. data/lib/defmastership/modifier/update_iref_checksum.rb +2 -1
  21. data/lib/defmastership/modifier/update_iref_version.rb +2 -1
  22. data/lib/defmastership/version.rb +1 -1
  23. data/spec/unit/defmastership/app_spec.rb +27 -3
  24. data/spec/unit/defmastership/export/csv/formatter_spec.rb +44 -231
  25. data/spec/unit/defmastership/export/formatter_spec.rb +97 -0
  26. data/spec/unit/defmastership/export/json/formatter_spec.rb +85 -0
  27. data/spec/unit/defmastership/export/xlsx/formatter_spec.rb +82 -0
  28. data/spec/unit/defmastership/export/yaml/formatter_spec.rb +85 -0
  29. data/spec/unit/defmastership/modifier/change_ref_spec.rb +54 -48
  30. data/spec/unit/defmastership/modifier/modifier_common_spec.rb +5 -5
  31. data/spec/unit/defmastership/modifier/rename_included_files_spec.rb +66 -62
  32. data/spec/unit/defmastership/modifier/update_def_checksum_spec.rb +5 -5
  33. data/spec/unit/defmastership/modifier/update_def_spec.rb +12 -10
  34. data/spec/unit/defmastership/modifier/update_def_version_spec.rb +9 -7
  35. data/spec/unit/defmastership/modifier/update_eref_checksum_spec.rb +26 -17
  36. data/spec/unit/defmastership/modifier/update_eref_version_spec.rb +34 -22
  37. data/spec/unit/defmastership/modifier/update_iref_checksum_spec.rb +8 -8
  38. data/spec/unit/defmastership/modifier/update_iref_version_spec.rb +11 -11
  39. data/tasks/code_quality.rake +1 -1
  40. metadata +28 -6
@@ -10,6 +10,7 @@ require('facets/file/writelines')
10
10
  module Defmastership
11
11
  module Modifier
12
12
  # Change references from temporary to definitive with multiple RefChangers
13
+ # This class smells of :reek:DataClump
13
14
  class ChangeRef
14
15
  include ModifierCommon
15
16
 
@@ -52,9 +53,11 @@ module Defmastership
52
53
 
53
54
  # Replace the definition's ref in the line if relevant
54
55
  #
56
+ # @param _filename [String] the filename of the file beeing modified
55
57
  # @param line [String] the current line
56
58
  # @return [String] the modified line
57
- def replace_refdef(line)
59
+ # This method smells of :reek:DataClump
60
+ def replace_refdef(_filename, line)
58
61
  if @parsing_state.enabled?(line)
59
62
  do_replace_refdef(line)
60
63
  else
@@ -64,9 +67,10 @@ module Defmastership
64
67
 
65
68
  # Replace the definition's refs in intenal refs
66
69
  #
70
+ # @param _filename [String] the filename of the file beeing modified
67
71
  # @param line [String] the current line
68
72
  # @return [String] the modified line
69
- def replace_irefs(line)
73
+ def replace_irefs(_filename, line)
70
74
  changes.reduce(line) do |res_line, (from, to)|
71
75
  res_line.gsub(Helper.regexp_from(:iref, from)) do
72
76
  Helper.text_with(Regexp.last_match, to)
@@ -76,9 +80,10 @@ module Defmastership
76
80
 
77
81
  # Replace the definition's refs in tags of include statements
78
82
  #
83
+ # @param _filename [String] the filename of the file beeing modified
79
84
  # @param line [String] the current line
80
85
  # @return [String] the modified line
81
- def replace_include_tags(line)
86
+ def replace_include_tags(_filename, line)
82
87
  return line unless line.match?(Core::DMRegexp::INCLUDE)
83
88
 
84
89
  changes.reduce(line) do |res_line, (from, to)|
@@ -88,11 +93,14 @@ module Defmastership
88
93
 
89
94
  # Replace the definition's refs in included files
90
95
  #
96
+ # @param filename [String] the filename of the file beeing modified
91
97
  # @param line [String] the current line
92
98
  # @return [String] the (unmodified) line
93
- def replace_tags_in_included_files(line)
99
+ def replace_tags_in_included_files(filename, line)
94
100
  if line.match(Core::DMRegexp::INCLUDE)
95
- Helper.replace_tags_in_included_files(Helper::ParsedFilename.full_filename(Regexp.last_match), changes)
101
+ Helper.replace_tags_in_included_files(
102
+ "#{Pathname(filename).dirname}/#{Helper::ParsedFilename.full_filename(Regexp.last_match)}", changes
103
+ )
96
104
  end
97
105
  line
98
106
  end
@@ -57,13 +57,13 @@ module Defmastership
57
57
  private
58
58
 
59
59
  def apply_to_all(texts, method)
60
- texts.transform_values do |text|
61
- apply_to_one(text, method)
60
+ texts.to_h do |filename, text|
61
+ [filename, apply_to_one(filename, text, method)]
62
62
  end
63
63
  end
64
64
 
65
- def apply_to_one(text, method)
66
- text.lines.map { |line| public_send(method, line) }
65
+ def apply_to_one(filename, text, method)
66
+ text.lines.map { |line| public_send(method, filename, line) }
67
67
  .join
68
68
  end
69
69
  end
@@ -81,15 +81,17 @@ module Defmastership
81
81
 
82
82
  # Modify line if it match
83
83
  #
84
+ # @param filename [String] the filename of the file beeing modified
85
+ # @param line [String] the current line
84
86
  # @return [String] the modified line
85
- def replace(line)
87
+ def replace(filename, line)
86
88
  match = matched?(line)
87
89
 
88
90
  return line unless match
89
91
 
90
92
  new_line = build_new_include_line(match, line)
91
93
 
92
- rename_file(line, new_line)
94
+ rename_file(Pathname(filename).dirname, line, new_line)
93
95
 
94
96
  new_line
95
97
  end
@@ -128,9 +130,9 @@ module Defmastership
128
130
  end
129
131
  end
130
132
 
131
- def rename_file(from, to)
132
- filename_from = Helper.extract_filename(from, @variables)
133
- filename_to = Helper.extract_filename(to, @variables)
133
+ def rename_file(dirname, from, to)
134
+ filename_from = "#{dirname}/#{Helper.extract_filename(from, @variables)}"
135
+ filename_to = "#{dirname}/#{Helper.extract_filename(to, @variables)}"
134
136
  changes << [filename_from, filename_to]
135
137
  File.rename(filename_from, filename_to)
136
138
  end
@@ -58,9 +58,10 @@ module Defmastership
58
58
 
59
59
  # Called on each line for an opportunity for text replacement
60
60
  #
61
+ # @param _filename [String] the filename of the file beeing modified
61
62
  # @param line [String] line from asciidoc sources files
62
63
  # @return [String] the modified line
63
- def replace_reference(line)
64
+ def replace_reference(_filename, line)
64
65
  match = line.match(Core::DMRegexp::DEFINITION)
65
66
 
66
67
  return line unless match
@@ -40,9 +40,10 @@ module Defmastership
40
40
 
41
41
  # Replace the definition's external ref in the line if relevant
42
42
  #
43
+ # @param _filename [String] the filename of the file beeing modified
43
44
  # @param line [String] the current line
44
45
  # @return [String] the modified line
45
- def replace_erefs(line)
46
+ def replace_erefs(_filename, line)
46
47
  match = line.match(Core::DMRegexp::EREF_DEF)
47
48
  # Return early if there's no match or the type is not valid
48
49
  return line unless match && eref_type_valid?(match[:reference])
@@ -20,9 +20,10 @@ module Defmastership
20
20
 
21
21
  # Replace the definition's internal ref in the line if relevant
22
22
  #
23
+ # @param _filename [String] the filename of the file beeing modified
23
24
  # @param line [String] the current line
24
25
  # @return [String] the modified line
25
- def replace_irefs(line)
26
+ def replace_irefs(_filename, line)
26
27
  line.gsub(Core::DMRegexp::IREF_DEF) do
27
28
  Helper::IrefReplacementFormatterChecksum.new(Regexp.last_match, document).to_s
28
29
  end
@@ -20,9 +20,10 @@ module Defmastership
20
20
 
21
21
  # Replace the definition's internal ref in the line if relevant
22
22
  #
23
+ # @param _filename [String] the filename of the file beeing modified
23
24
  # @param line [String] the current line
24
25
  # @return [String] the modified line
25
- def replace_irefs(line)
26
+ def replace_irefs(_filename, line)
26
27
  line.gsub(Core::DMRegexp::IREF_DEF) do
27
28
  Helper::IrefReplacementFormatterVersion.new(Regexp.last_match, document).to_s
28
29
  end
@@ -3,6 +3,6 @@
3
3
 
4
4
  module Defmastership
5
5
  # [String] Gem version
6
- VERSION = '1.3.3'
6
+ VERSION = '1.3.4'
7
7
  public_constant :VERSION
8
8
  end
@@ -32,7 +32,8 @@ RSpec.describe(Defmastership::App) do
32
32
  /--separator, --sep, -s arg.*CSV\s+separator\s+\(default: ,\)$/,
33
33
  /--\[no-\]no-fail.*Exit\s+success\s+even\s+in\s+
34
34
  case\s+of\s+wrong\s+explicit\s+checksum$/mx,
35
- /--output-file, -o arg.*CSV\s+output\s+filename\s+\(default:\s+none\)$/
35
+ /--output-file, -o arg.*CSV\s+output\s+filename\s+\(default:\s+none\)$/,
36
+ /--format, -f arg.*Output\s+format\s+\(default: csv\)$/
36
37
  ].each do |content|
37
38
  it do
38
39
  expect { described_class.run(['export', '--help']) }
@@ -76,7 +77,7 @@ RSpec.describe(Defmastership::App) do
76
77
 
77
78
  it { expect(Defmastership::Document).to(have_received(:new).with(no_args)) }
78
79
  it { expect(document).to(have_received(:parse_file_with_preprocessor).once.with('toto.adoc')) }
79
- it { expect(Defmastership::Export::CSV::Formatter).to(have_received(:new).with(document, ',')) }
80
+ it { expect(Defmastership::Export::CSV::Formatter).to(have_received(:new).with(document, separator: ',')) }
80
81
  it { expect(formatter).to(have_received(:export_to).once.with('toto.csv')) }
81
82
  it { expect(document).to(have_received(:wrong_explicit_checksum?)) }
82
83
 
@@ -100,6 +101,29 @@ RSpec.describe(Defmastership::App) do
100
101
  end
101
102
  end
102
103
 
104
+ context('when "export --format=xslx toto.adoc" subcommand') do
105
+ let(:document) { instance_double(Defmastership::Document, 'document') }
106
+ let(:formatter) { instance_double(Defmastership::Export::XLSX::Formatter, 'formatter') }
107
+ let(:defs) do
108
+ [
109
+ instance_double(Defmastership::Definition, 'def1'),
110
+ instance_double(Defmastership::Definition, 'def2')
111
+ ]
112
+ end
113
+
114
+ before do
115
+ allow(Defmastership::Document).to(receive(:new).and_return(document))
116
+ allow(Defmastership::Export::XLSX::Formatter).to(receive(:new).and_return(formatter))
117
+ allow(formatter).to(receive(:export_to).with(an_instance_of(String)))
118
+ allow(document).to(receive(:parse_file_with_preprocessor).with(an_instance_of(String)))
119
+ allow(document).to(receive_messages(definitions: defs, wrong_explicit_checksum?: nil))
120
+ described_class.run(['export', '--format=xlsx', 'toto.adoc'])
121
+ end
122
+
123
+ it { expect(Defmastership::Export::XLSX::Formatter).to(have_received(:new).with(document)) }
124
+ it { expect(formatter).to(have_received(:export_to).once.with('toto.xlsx')) }
125
+ end
126
+
103
127
  context('when "export" with more than one argument') do
104
128
  let(:document) { instance_double(Defmastership::Document, 'document') }
105
129
  let(:formatter) { instance_double(Defmastership::Export::CSV::Formatter, 'formatter') }
@@ -123,7 +147,7 @@ RSpec.describe(Defmastership::App) do
123
147
  it { expect(Defmastership::Document).to(have_received(:new).with(no_args)) }
124
148
  it { expect(document).to(have_received(:parse_file_with_preprocessor).once.with('toto.adoc')) }
125
149
  it { expect(document).to(have_received(:parse_file_with_preprocessor).once.with('tutu.adoc')) }
126
- it { expect(Defmastership::Export::CSV::Formatter).to(have_received(:new).with(document, ',')) }
150
+ it { expect(Defmastership::Export::CSV::Formatter).to(have_received(:new).with(document, separator: ',')) }
127
151
  it { expect(formatter).to(have_received(:export_to).once.with('pouet.csv')) }
128
152
  it { expect(described_class.run(['export', '--output-file=pouet.csv', 'toto.adoc', 'tutu.adoc'])).to(be(0)) }
129
153
  end
@@ -4,8 +4,10 @@
4
4
  require('defmastership/document')
5
5
  require('defmastership/export/csv/formatter')
6
6
 
7
+ COLUMN_METHODS = %i[type reference value checksum].freeze
8
+
7
9
  RSpec.describe(Defmastership::Export::CSV::Formatter) do
8
- subject(:formatter) { described_class.new(document, ';') }
10
+ subject(:formatter) { described_class.new(document, separator: ';') }
9
11
 
10
12
  let(:document) { instance_double(Defmastership::Document, 'document') }
11
13
 
@@ -21,6 +23,7 @@ RSpec.describe(Defmastership::Export::CSV::Formatter) do
21
23
  instance_double(Defmastership::Export::BodyFormatter, 'bodies[1]')
22
24
  ]
23
25
  end
26
+
24
27
  let(:csv) { instance_double(CSV, 'csv') }
25
28
 
26
29
  before do
@@ -46,10 +49,8 @@ RSpec.describe(Defmastership::Export::CSV::Formatter) do
46
49
  end
47
50
 
48
51
  context 'when no variable columns' do
49
- methods = %i[type reference value checksum]
50
-
51
52
  before do
52
- methods.each do |method|
53
+ COLUMN_METHODS.each do |method|
53
54
  allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
54
55
  bodies.each_with_index do |body, index|
55
56
  allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
@@ -60,88 +61,7 @@ RSpec.describe(Defmastership::Export::CSV::Formatter) do
60
61
 
61
62
  it { expect(CSV).to(have_received(:open).with('whatever', 'w:ISO-8859-1', col_sep: ';')) }
62
63
 
63
- methods.each do |method|
64
- it { expect(header).to(have_received(method).with(no_args)) }
65
-
66
- 2.times do |index|
67
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
68
- end
69
- end
70
-
71
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
72
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
73
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
74
- end
75
-
76
- context 'when summary' do
77
- methods = %i[type reference summary value checksum]
78
-
79
- before do
80
- methods.each do |method|
81
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
82
- bodies.each_with_index do |body, index|
83
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
84
- end
85
- end
86
- allow(document).to(receive(:summaries?).with(no_args).and_return([:whatever]))
87
- formatter.export_to('whatever')
88
- end
89
-
90
- methods.each do |method|
91
- it { expect(header).to(have_received(method).with(no_args)) }
92
-
93
- 2.times do |index|
94
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
95
- end
96
- end
97
-
98
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
99
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
100
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
101
- end
102
-
103
- context 'when wrong_explicit_checksum' do
104
- methods = %i[type reference value checksum wrong_explicit_checksum]
105
-
106
- before do
107
- methods.each do |method|
108
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
109
- bodies.each_with_index do |body, index|
110
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
111
- end
112
- end
113
- allow(document).to(receive(:wrong_explicit_checksum?).with(no_args).and_return(true))
114
- formatter.export_to('whatever')
115
- end
116
-
117
- methods.each do |method|
118
- it { expect(header).to(have_received(method).with(no_args)) }
119
-
120
- 2.times do |index|
121
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
122
- end
123
- end
124
-
125
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
126
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
127
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
128
- end
129
-
130
- context 'when explicit_version' do
131
- methods = %i[type reference value checksum explicit_version]
132
-
133
- before do
134
- methods.each do |method|
135
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
136
- bodies.each_with_index do |body, index|
137
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
138
- end
139
- end
140
- allow(document).to(receive(:explicit_version?).with(no_args).and_return(true))
141
- formatter.export_to('whatever')
142
- end
143
-
144
- methods.each do |method|
64
+ COLUMN_METHODS.each do |method|
145
65
  it { expect(header).to(have_received(method).with(no_args)) }
146
66
 
147
67
  2.times do |index|
@@ -149,162 +69,55 @@ RSpec.describe(Defmastership::Export::CSV::Formatter) do
149
69
  end
150
70
  end
151
71
 
152
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
153
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
154
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
72
+ it { expect(csv).to(have_received(:<<).with(COLUMN_METHODS.map { |method| "#{method} header" })) }
73
+ it { expect(csv).to(have_received(:<<).with(COLUMN_METHODS.map { |method| "#{method} def0 body" })) }
74
+ it { expect(csv).to(have_received(:<<).with(COLUMN_METHODS.map { |method| "#{method} def1 body" })) }
155
75
  end
76
+ end
156
77
 
157
- context 'when labels' do
158
- methods = %i[type reference value checksum labels]
159
-
160
- before do
161
- methods.each do |method|
162
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
163
- bodies.each_with_index do |body, index|
164
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
165
- end
166
- end
167
- allow(document).to(receive(:labels).with(no_args).and_return([:whatever]))
168
- formatter.export_to('whatever')
169
- end
170
-
171
- methods.each do |method|
172
- it { expect(header).to(have_received(method).with(no_args)) }
173
-
174
- 2.times do |index|
175
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
176
- end
177
- end
178
-
179
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
180
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
181
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
182
- end
183
-
184
- context 'when eref' do
185
- methods = %i[type reference value checksum eref]
186
-
187
- before do
188
- methods.each do |method|
189
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
190
- bodies.each_with_index do |body, index|
191
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
192
- end
193
- end
194
- allow(document).to(receive(:eref).with(no_args).and_return([:whatever]))
195
- formatter.export_to('whatever')
196
- end
197
-
198
- methods.each do |method|
199
- it { expect(header).to(have_received(method).with(no_args)) }
200
-
201
- 2.times do |index|
202
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
203
- end
204
- end
205
-
206
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
207
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
208
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
209
- end
210
-
211
- context 'when iref' do
212
- methods = %i[type reference value checksum iref]
213
-
214
- before do
215
- methods.each do |method|
216
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
217
- bodies.each_with_index do |body, index|
218
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
219
- end
220
- end
221
- allow(document).to(receive(:iref).with(no_args).and_return(true))
222
- formatter.export_to('whatever')
223
- end
224
-
225
- methods.each do |method|
226
- it { expect(header).to(have_received(method).with(no_args)) }
78
+ describe '#export_to with default separator' do
79
+ subject(:formatter) { described_class.new(document) }
227
80
 
228
- 2.times do |index|
229
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
230
- end
231
- end
232
-
233
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
234
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
235
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
81
+ let(:header) { instance_double(Defmastership::Export::HeaderFormatter, 'header') }
82
+ let(:bodies) do
83
+ [
84
+ instance_double(Defmastership::Export::BodyFormatter, 'bodies[0]'),
85
+ instance_double(Defmastership::Export::BodyFormatter, 'bodies[1]')
86
+ ]
236
87
  end
237
88
 
238
- context 'when attributes' do
239
- methods = %i[type reference value checksum attributes]
89
+ let(:csv) { instance_double(CSV, 'csv') }
240
90
 
241
- before do
242
- methods.each do |method|
243
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
244
- bodies.each_with_index do |body, index|
245
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
246
- end
247
- end
248
- allow(document).to(receive(:attributes).with(no_args).and_return([:whatever]))
249
- formatter.export_to('whatever')
91
+ before do
92
+ allow(CSV).to(receive(:open).with('whatever', 'w:ISO-8859-1', col_sep: ',').and_yield(csv))
93
+ allow(csv).to(receive(:<<))
94
+ allow(Defmastership::Export::HeaderFormatter).to(receive(:new).with(document).and_return(header))
95
+ bodies.each_with_index do |body, index|
96
+ allow(Defmastership::Export::BodyFormatter).to(
97
+ receive(:new).with(
98
+ document,
99
+ :"def#{index}"
100
+ ).and_return(body)
101
+ )
250
102
  end
103
+ allow(document).to(receive(:definitions).and_return(%i[def0 def1]))
104
+ allow(document).to(receive(:summaries?).with(no_args).and_return(false))
105
+ allow(document).to(receive(:wrong_explicit_checksum?).with(no_args).and_return(false))
106
+ allow(document).to(receive(:explicit_version?).with(no_args).and_return(false))
107
+ allow(document).to(receive(:labels).with(no_args).and_return([]))
108
+ allow(document).to(receive(:eref).with(no_args).and_return([]))
109
+ allow(document).to(receive(:iref).with(no_args).and_return(false))
110
+ allow(document).to(receive(:attributes).with(no_args).and_return([]))
251
111
 
252
- methods.each do |method|
253
- it { expect(header).to(have_received(method).with(no_args)) }
254
-
255
- 2.times do |index|
256
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
112
+ %i[type reference value checksum].each do |method|
113
+ allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
114
+ bodies.each_with_index do |body, index|
115
+ allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
257
116
  end
258
117
  end
259
-
260
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
261
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
262
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
118
+ formatter.export_to('whatever')
263
119
  end
264
120
 
265
- context 'when every colums' do
266
- methods = %i[
267
- type
268
- reference
269
- summary
270
- value
271
- checksum
272
- wrong_explicit_checksum
273
- explicit_version
274
- labels
275
- eref
276
- iref
277
- attributes
278
- ]
279
-
280
- before do
281
- methods.each do |method|
282
- allow(header).to(receive(method).with(no_args).and_return(["#{method} header"]))
283
- bodies.each_with_index do |body, index|
284
- allow(body).to(receive(method).with(no_args).and_return(["#{method} def#{index} body"]))
285
- end
286
- end
287
- allow(document).to(receive(:summaries?).with(no_args).and_return(true))
288
- allow(document).to(receive(:wrong_explicit_checksum?).with(no_args).and_return(true))
289
- allow(document).to(receive(:explicit_version?).with(no_args).and_return(true))
290
- allow(document).to(receive(:labels).with(no_args).and_return([:whatever]))
291
- allow(document).to(receive(:eref).with(no_args).and_return([:whatever]))
292
- allow(document).to(receive(:iref).with(no_args).and_return(true))
293
- allow(document).to(receive(:attributes).with(no_args).and_return([:whatever]))
294
- formatter.export_to('whatever')
295
- end
296
-
297
- methods.each do |method|
298
- it { expect(header).to(have_received(method).with(no_args)) }
299
-
300
- 2.times do |index|
301
- it { expect(bodies[index]).to(have_received(method).with(no_args)) }
302
- end
303
- end
304
-
305
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} header" })) }
306
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def0 body" })) }
307
- it { expect(csv).to(have_received(:<<).with(methods.map { |method| "#{method} def1 body" })) }
308
- end
121
+ it { expect(CSV).to(have_received(:open).with('whatever', 'w:ISO-8859-1', col_sep: ',')) }
309
122
  end
310
123
  end
@@ -0,0 +1,97 @@
1
+ # Copyright (c) 2020 Jerome Arbez-Gindre
2
+ # frozen_string_literal: true
3
+
4
+ require('defmastership/export/formatter')
5
+
6
+ # Defmastership::Export::Formatter is an abstract class and need to be derived for test
7
+ class ConcreteFormatter < Defmastership::Export::Formatter
8
+ def export_to(_filename)
9
+ # allow to indirectly test a private method
10
+ build_column_list
11
+ end
12
+ end
13
+
14
+ RSpec.describe(Defmastership::Export::Formatter) do
15
+ context('when class is not derived') do
16
+ subject(:formatter) { described_class.new(:whatever) }
17
+
18
+ describe '#export_to' do
19
+ it {
20
+ expect { formatter.export_to(:something) }
21
+ .to(raise_error(
22
+ NotImplementedError,
23
+ 'Defmastership::Export::Formatter has not implemented the \'export_to\' method'
24
+ ))
25
+ }
26
+ end
27
+ end
28
+
29
+ context('when class is derived') do
30
+ subject(:formatter) { ConcreteFormatter.new(document) }
31
+
32
+ let(:document) { instance_double(Defmastership::Document, 'document') }
33
+
34
+ describe '#export_to' do
35
+ it {
36
+ expect { formatter.export_to(:something) }
37
+ .not_to(raise_error(NotImplementedError))
38
+ }
39
+ end
40
+
41
+ describe '#header' do
42
+ let(:header_formatter) { instance_double(Defmastership::Export::HeaderFormatter, 'header_formatter') }
43
+
44
+ before do
45
+ allow(Defmastership::Export::HeaderFormatter).to(receive(:new).and_return(header_formatter))
46
+ allow(header_formatter).to(receive_messages(type: ['type value'], reference: ['reference value']))
47
+ formatter.header(%i[type reference])
48
+ end
49
+
50
+ it { expect(Defmastership::Export::HeaderFormatter).to(have_received(:new).with(document)) }
51
+ it { expect(header_formatter).to(have_received(:type)) }
52
+ it { expect(header_formatter).to(have_received(:reference)) }
53
+ it { expect(formatter.header(%i[type reference])).to(eq(['type value', 'reference value'])) }
54
+ end
55
+
56
+ describe '#body' do
57
+ let(:body_formatter) { instance_double(Defmastership::Export::BodyFormatter, 'body_formatter') }
58
+
59
+ before do
60
+ allow(Defmastership::Export::BodyFormatter).to(receive(:new).and_return(body_formatter))
61
+ allow(body_formatter).to(receive_messages(type: ['type value'], reference: ['reference value']))
62
+ formatter.body(:definition, %i[type reference])
63
+ end
64
+
65
+ it { expect(Defmastership::Export::BodyFormatter).to(have_received(:new).with(document, :definition)) }
66
+ it { expect(body_formatter).to(have_received(:type)) }
67
+ it { expect(body_formatter).to(have_received(:reference)) }
68
+ it { expect(formatter.body(:definition, %i[type reference])).to(eq(['type value', 'reference value'])) }
69
+ end
70
+
71
+ describe '#build_column_list' do
72
+ before do
73
+ allow(document).to(
74
+ receive_messages(
75
+ summaries?: true,
76
+ wrong_explicit_checksum?: false,
77
+ explicit_version?: false,
78
+ labels: ['toto'],
79
+ eref: [],
80
+ iref: false,
81
+ attributes: []
82
+ )
83
+ )
84
+ formatter.export_to(:whatever)
85
+ end
86
+
87
+ it { expect(document).to(have_received(:summaries?)) }
88
+ it { expect(document).to(have_received(:wrong_explicit_checksum?)) }
89
+ it { expect(document).to(have_received(:explicit_version?)) }
90
+ it { expect(document).to(have_received(:labels)) }
91
+ it { expect(document).to(have_received(:eref)) }
92
+ it { expect(document).to(have_received(:iref)) }
93
+ it { expect(document).to(have_received(:attributes)) }
94
+ it { expect(formatter.export_to(:whatever)).to(eq(%i[type reference summary value checksum labels])) }
95
+ end
96
+ end
97
+ end