diff --git a/spec/tooling/lib/tooling/find_tests_spec.rb b/spec/tooling/lib/tooling/find_tests_spec.rb index 997d9d9a746dd6bac36e08cd372abebffb8e0471..e531fb9548e791d71ed6c447129e296ed6abd563 100644 --- a/spec/tooling/lib/tooling/find_tests_spec.rb +++ b/spec/tooling/lib/tooling/find_tests_spec.rb @@ -50,15 +50,17 @@ subject { instance.execute } context 'when the matching_tests_paths file does not exist' do - before do - allow(File).to receive(:exist?).and_return(false) - allow(File).to receive(:write).with(matching_tests_paths, any_args) - end + let(:instance) { described_class.new(non_existing_output_file, matching_tests_paths) } + let(:non_existing_output_file) { 'tmp/another_file.out' } - it 'creates an empty file' do - expect(File).to receive(:write).with(matching_tests_paths, '') + around do |example| + example.run + ensure + FileUtils.rm_rf(non_existing_output_file) + end - subject + it 'creates the file' do + expect { subject }.to change { File.exist?(non_existing_output_file) }.from(false).to(true) end end diff --git a/spec/tooling/lib/tooling/helpers/file_handler_spec.rb b/spec/tooling/lib/tooling/helpers/file_handler_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..7c8310c4bd958e52cfc98564721e0e0a2bf25b3e --- /dev/null +++ b/spec/tooling/lib/tooling/helpers/file_handler_spec.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require 'tempfile' +require_relative '../../../../../tooling/lib/tooling/helpers/file_handler' + +class MockClass # rubocop:disable Gitlab/NamespacedClass + include Tooling::Helpers::FileHandler +end + +RSpec.describe Tooling::Helpers::FileHandler, feature_category: :tooling do + attr_accessor :input_file_path, :output_file_path + + around do |example| + input_file = Tempfile.new('input') + output_file = Tempfile.new('output') + + self.input_file_path = input_file.path + self.output_file_path = output_file.path + + # See https://ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/ + # Tempfile.html#class-Tempfile-label-Explicit+close + begin + example.run + ensure + output_file.close + input_file.close + output_file.unlink + input_file.unlink + end + end + + let(:instance) { MockClass.new } + let(:initial_content) { 'previous_content1 previous_content2' } + + before do + # We write into the temp files initially, to later check how the code modified those files + File.write(input_file_path, initial_content) + File.write(output_file_path, initial_content) + end + + describe '#read_array_from_file' do + subject { instance.read_array_from_file(input_file_path) } + + context 'when the input file does not exist' do + let(:non_existing_input_file) { 'tmp/another_file.out' } + + subject { instance.read_array_from_file(non_existing_input_file) } + + around do |example| + example.run + ensure + FileUtils.rm_rf(non_existing_input_file) + end + + it 'creates the file' do + expect { subject }.to change { File.exist?(non_existing_input_file) }.from(false).to(true) + end + end + + context 'when the input file is not empty' do + let(:initial_content) { 'previous_content1 previous_content2' } + + it 'returns the content of the file in an array' do + expect(subject).to eq(initial_content.split(' ')) + end + end + end + + describe '#write_array_to_file' do + let(:content_array) { %w[new_entry] } + + subject { instance.write_array_to_file(output_file_path, content_array) } + + context 'when the output file does not exist' do + let(:non_existing_output_file) { 'tmp/another_file.out' } + + subject { instance.write_array_to_file(non_existing_output_file, content_array) } + + around do |example| + example.run + ensure + FileUtils.rm_rf(non_existing_output_file) + end + + it 'creates the file' do + expect { subject }.to change { File.exist?(non_existing_output_file) }.from(false).to(true) + end + end + + context 'when the output file is empty' do + let(:initial_content) { '' } + + it 'writes the correct content to the file' do + expect { subject }.to change { File.read(output_file_path) }.from('').to(content_array.join(' ')) + end + end + + context 'when the output file is not empty' do + let(:initial_content) { 'previous_content1 previous_content2' } + + it 'appends the correct content to the file' do + expect { subject }.to change { File.read(output_file_path) } + .from(initial_content) + .to((initial_content.split(' ') + content_array).join(' ')) + end + end + end +end diff --git a/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb b/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb index 375be001bd1885551883e3739425edb853f31794..30965ed985da6382c0b5d166bc92b949aefef82b 100644 --- a/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb +++ b/spec/tooling/lib/tooling/mappings/partial_to_views_mappings_spec.rb @@ -52,8 +52,8 @@ end context 'when no partials were modified' do - it 'empties the output file' do - expect { subject }.to change { File.read(output_file) }.from(output_file_content).to('') + it 'does not change the output file' do + expect { subject }.not_to change { File.read(output_file) } end end @@ -76,8 +76,8 @@ File.write("#{view_base_folder}/my_view.html.haml", "render 'another_partial'") end - it 'empties the output file' do - expect { subject }.to change { File.read(output_file) }.from(output_file_content).to('') + it 'does not change the output file' do + expect { subject }.not_to change { File.read(output_file) } end end @@ -89,7 +89,7 @@ it 'writes the view including the partial to the output' do expect { subject }.to change { File.read(output_file) } .from(output_file_content) - .to("#{view_base_folder}/my_view.html.haml") + .to(output_file_content + " #{view_base_folder}/my_view.html.haml") end end end diff --git a/tooling/lib/tooling/find_tests.rb b/tooling/lib/tooling/find_tests.rb index 4acbb5fcd6aea5a4e5f6da336f02aa4340ade011..b63b207c58bb081bba60850eee7ed4233fd6dca6 100644 --- a/tooling/lib/tooling/find_tests.rb +++ b/tooling/lib/tooling/find_tests.rb @@ -1,16 +1,15 @@ # frozen_string_literal: true require 'test_file_finder' +require_relative 'helpers/file_handler' module Tooling class FindTests + include Helpers::FileHandler + def initialize(changes_file, matching_tests_paths) @matching_tests_paths = matching_tests_paths - @changed_files = File.read(changes_file).split(' ') - - File.write(matching_tests_paths, '') unless File.exist?(matching_tests_paths) - - @matching_tests = File.read(matching_tests_paths).split(' ') + @changed_files = read_array_from_file(changes_file) end def execute @@ -22,8 +21,7 @@ def execute end end - new_matching_tests = tff.test_files.uniq - File.write(matching_tests_paths, (matching_tests + new_matching_tests).join(' ')) + write_array_to_file(matching_tests_paths, tff.test_files.uniq) end private diff --git a/tooling/lib/tooling/helpers/file_handler.rb b/tooling/lib/tooling/helpers/file_handler.rb new file mode 100644 index 0000000000000000000000000000000000000000..ec4f42ea3637a9e031ffee26b119db9ea5edf305 --- /dev/null +++ b/tooling/lib/tooling/helpers/file_handler.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'fileutils' + +module Tooling + module Helpers + module FileHandler + def read_array_from_file(file) + FileUtils.touch file + + File.read(file).split(' ') + end + + def write_array_to_file(file, content_array) + FileUtils.touch file + + output_content = (File.read(file).split(' ') + content_array).join(' ') + + File.write(file, output_content) + end + end + end +end diff --git a/tooling/lib/tooling/mappings/base.rb b/tooling/lib/tooling/mappings/base.rb index 93d3a967114fe3cc23432845e989479a2e7a06d7..3db4d1dbb9dfcb78d45d77cb99a271eddf676cf9 100644 --- a/tooling/lib/tooling/mappings/base.rb +++ b/tooling/lib/tooling/mappings/base.rb @@ -1,11 +1,14 @@ # frozen_string_literal: true require_relative '../../../../lib/gitlab_edition' +require_relative '../helpers/file_handler' # Returns system specs files that are related to the JS files that were changed in the MR. module Tooling module Mappings class Base + include Helpers::FileHandler + # Input: A list of space-separated files # Output: A list of space-separated specs files (JS, Ruby, ...) def execute(changed_files) diff --git a/tooling/lib/tooling/mappings/partial_to_views_mappings.rb b/tooling/lib/tooling/mappings/partial_to_views_mappings.rb index c0cf378b53b0bee88f2c4202c23172e0169c2303..3109da685f1f0cb9c6a44d98128d473b5a555409 100644 --- a/tooling/lib/tooling/mappings/partial_to_views_mappings.rb +++ b/tooling/lib/tooling/mappings/partial_to_views_mappings.rb @@ -9,7 +9,7 @@ module Mappings class PartialToViewsMappings < Base def initialize(changes_file, output_file, view_base_folder: 'app/views') @output_file = output_file - @changed_files = File.read(changes_file).split(' ') + @changed_files = read_array_from_file(changes_file) @view_base_folders = folders_for_available_editions(view_base_folder) end @@ -28,7 +28,7 @@ def execute end end - File.write(output_file, views_including_modified_partials.join(' ')) + write_array_to_file(output_file, views_including_modified_partials) end def filter_files