Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
schema-test (0.2.0)
schema-test (0.3.0)
json
json_schemer

Expand Down
37 changes: 26 additions & 11 deletions lib/schema_test/minitest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,20 @@ def install_assert_api_expansion_hook
end

def expand_assert_api_calls
@@__api_schema_calls_for_expansion.each do |file, line_indexes_with_schemas|
original_contents = File.read(file)
rewriter_options = { disable_rubocop: SchemaTest.configuration.disable_rubocop }
rewriter = SchemaTest::Rewriter.new(original_contents, line_indexes_with_schemas, options: rewriter_options)
new_contents = rewriter.output
raise "Error rewriting file" if new_contents.blank?
File.open(file, 'w') { |f| f.puts new_contents }
end
@@__api_schema_calls_for_expansion.each do |file, line_indexes_with_schemas|
rewrite_file_safely(file) do |original_contents|
rewriter_options = { disable_rubocop: SchemaTest.configuration.disable_rubocop }
rewriter = SchemaTest::Rewriter.new(original_contents, line_indexes_with_schemas, options: rewriter_options)
new_contents = rewriter.output
raise "Error rewriting file" if new_contents.blank?
new_contents
end
end
end

@@__schema_fingerprints = {}
@@__schema_fingerprint_hook_installed = false
@@__rewrite_mutex = Mutex.new

def queue_write_schema_fingerprint(call_site, fingerprint)
file, line = call_site.split(':')
Expand All @@ -97,9 +99,22 @@ def install_fingerprint_rewrite_hook

def write_schema_fingerprints
@@__schema_fingerprints.each do |file, line_indexes_with_fingerprints|
original_contents = File.read(file)
rewriter = SchemaTest::FingerprintRewriter.new(original_contents, line_indexes_with_fingerprints)
File.open(file, 'w') { |f| f.print rewriter.output }
rewrite_file_safely(file) do |original_contents|
rewriter = SchemaTest::FingerprintRewriter.new(original_contents, line_indexes_with_fingerprints)
rewriter.output
end
end
end

def rewrite_file_safely(file)
@@__rewrite_mutex.synchronize do
File.open(file, File::RDWR) do |source|
source.flock(File::LOCK_EX)
rewritten_contents = yield source.read
source.rewind
source.write(rewritten_contents)
source.truncate(source.pos)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/schema_test/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module SchemaTest
VERSION = "0.2.0"
VERSION = "0.3.0"
end
49 changes: 49 additions & 0 deletions spec/schema_test/minitest_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'spec_helper'
require 'schema_test/minitest'
require 'tempfile'

RSpec.describe SchemaTest::Minitest do
let(:harness) do
Class.new do
include SchemaTest::Minitest
end.new
end

it 'serializes concurrent rewrites of the same file' do
file = Tempfile.new
file.write("original\n")
file.close

first_started = Queue.new
release_first = Queue.new
second_started = Queue.new
second_contents = Queue.new

first = Thread.new do
harness.send(:rewrite_file_safely, file.path) do
first_started << true
release_first.pop
"first\n"
end
end
first_started.pop

second = Thread.new do
second_started << true
harness.send(:rewrite_file_safely, file.path) do |contents|
second_contents << contents
"second\n"
end
end
second_started.pop

expect(second_contents).to be_empty
release_first << true

[first, second].each(&:value)
expect(second_contents.pop).to eq("first\n")
expect(File.read(file.path)).to eq("second\n")
ensure
file&.unlink
end
end
Loading