Skip to content
This repository has been archived by the owner on May 3, 2024. It is now read-only.

Commit

Permalink
Export package protections rspec support (#13)
Browse files Browse the repository at this point in the history
* move package protections rspec support into exported part of code

* fix ERB loading when getting rubocop

* bump version

* fix thing

* fix use of select
  • Loading branch information
Alex Evanczuk authored Jul 1, 2022
1 parent f892f88 commit 3e0333c
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 110 deletions.
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:
package_protections (1.1.1)
package_protections (1.2.0)
activesupport
parse_packwerk
rubocop
Expand Down
99 changes: 99 additions & 0 deletions lib/package_protections/rspec/matchers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
def offense(
package_name, message, file, violation_type
)

package = ParsePackwerk.all.find { |p| p.name == package_name }
PackageProtections::Offense.new(
package: package,
message: message,
file: file,
violation_type: violation_type
)
end

def serialize_offenses_diff(actual_offenses, expected_offense)
color_by_match = ->(actual, expected) { actual == expected ? Rainbow(actual).green : "#{Rainbow(actual).red} (expected: #{expected})" }

actual_offenses.map do |offense|
# We color each field red or green depending on if the attributes match our expected
<<~SERIALIZED_OFFENSE
File: #{color_by_match.call(offense.file, expected_offense.file)}
Message: #{color_by_match.call(offense.message, expected_offense.message)}
Violation Type: #{color_by_match.call(offense.violation_type, expected_offense.violation_type)}
Package: #{color_by_match.call(offense.package.name, expected_offense.package.name)}
SERIALIZED_OFFENSE
end
end

def serialize_offenses(actual_offenses)
actual_offenses.map do |offense|
<<~SERIALIZED_OFFENSE
File: #{offense.file}
Message: #{offense.message}
Violation Type: #{offense.violation_type}
Package: #{offense.package.name}
SERIALIZED_OFFENSE
end
end

RSpec::Matchers.define(:include_offense) do |expected_offense|
match do |actual_offenses|
@actual_offenses = actual_offenses
@expected_offense = expected_offense
if ENV['DEBUG']
PackageProtections.print_offenses(actual_offenses)
end
@matching_offense = actual_offenses.find do |actual_offense|
actual_offense.file == expected_offense.file &&
actual_offense.message == expected_offense.message &&
actual_offense.violation_type == expected_offense.violation_type &&
actual_offense.package.name == expected_offense.package.name
end
!@matching_offense.nil?
end

description do
"to have an offense with type `#{expected_offense.type}` tied to package `#{expected_offense.package_name}` with message `#{expected_offense.message}` and instances `#{expected_offense.submessages.join(', ')}`"
end

failure_message do
<<~MSG
Could not find offense! Here are the found offenses:
#{serialize_offenses_diff(@actual_offenses, expected_offense).join("\n\n")}
MSG
end
end

RSpec::Matchers.define(:contain_exactly) do |number_of_offenses|
match do |actual_offenses|
@actual_offenses = actual_offenses || []
@offenses = []
@actual_offenses.each do |offense|
@offenses << offense
end
@offenses.size == number_of_offenses
end

chain :offense, :number_of_offenses
chain :offenses, :number_of_offenses

description do
'to contain offenses'
end

failure_message_when_negated do
"Found the following offenses:\n#{@offenses.map { |r| "#{r.package_name}: #{r.message}" }}"
end

failure_message do
if @offenses.empty?
"Found #{@offenses.size} instead."
else
<<~MSG
Found #{@offenses.size} instead.
#{serialize_offenses(@offenses).join("\n")}
MSG
end
end
end
17 changes: 17 additions & 0 deletions lib/package_protections/rspec/support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

# Require this file to load code that supports testing using RSpec.

require_relative 'application_fixture_helper'
require_relative 'matchers'

def get_resulting_rubocop
write_file('config/default.yml', <<~YML.strip)
<%= PackageProtections.rubocop_yml %>
YML
YAML.safe_load(ERB.new(File.read('config/default.yml')).result(binding))
end

RSpec.configure do |config|
config.include ApplicationFixtureHelper
end
2 changes: 1 addition & 1 deletion package_protections.gemspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Gem::Specification.new do |spec|
spec.name = 'package_protections'
spec.version = '1.1.1'
spec.version = '1.2.0'
spec.authors = ['Gusto Engineers']
spec.email = ['[email protected]']
spec.summary = 'Package protections for Rails apps'
Expand Down
106 changes: 0 additions & 106 deletions spec/package_protections_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,93 +13,6 @@
allow(Bundler).to receive(:root).and_return(Pathname.new('.'))
end

RSpec::Matchers.define(:include_offense) do |expected_offense|
match do |actual_offenses|
@actual_offenses = actual_offenses
@expected_offense = expected_offense
if ENV['DEBUG']
PackageProtections.print_offenses(actual_offenses)
end
@matching_offense = actual_offenses.find do |actual_offense|
actual_offense.file == expected_offense.file &&
actual_offense.message == expected_offense.message &&
actual_offense.violation_type == expected_offense.violation_type &&
actual_offense.package.name == expected_offense.package.name
end
!@matching_offense.nil?
end

description do
"to have an offense with type `#{expected_offense.type}` tied to package `#{expected_offense.package_name}` with message `#{expected_offense.message}` and instances `#{expected_offense.submessages.join(', ')}`"
end

failure_message do
<<~MSG
Could not find offense! Here are the found offenses:
#{serialize_offenses_diff(@actual_offenses, expected_offense).join("\n\n")}
MSG
end
end

RSpec::Matchers.define(:contain_exactly) do |number_of_offenses|
match do |actual_offenses|
@actual_offenses = actual_offenses || []
@offenses = []
@actual_offenses.select do |offense|
@offenses << offense
end
@offenses.size == number_of_offenses
end

chain :offense, :number_of_offenses
chain :offenses, :number_of_offenses

description do
'to contain offenses'
end

failure_message_when_negated do
"Found the following offenses:\n#{@offenses.map { |r| "#{r.package_name}: #{r.message}" }}"
end

failure_message do
if @offenses.empty?
"Found #{@offenses.size} instead."
else
<<~MSG
Found #{@offenses.size} instead.
#{serialize_offenses(@offenses).join("\n")}
MSG
end
end
end

def serialize_offenses_diff(actual_offenses, expected_offense)
color_by_match = ->(actual, expected) { actual == expected ? Rainbow(actual).green : "#{Rainbow(actual).red} (expected: #{expected})" }

actual_offenses.map do |offense|
# We color each field red or green depending on if the attributes match our expected
<<~SERIALIZED_OFFENSE
File: #{color_by_match.call(offense.file, expected_offense.file)}
Message: #{color_by_match.call(offense.message, expected_offense.message)}
Violation Type: #{color_by_match.call(offense.violation_type, expected_offense.violation_type)}
Package: #{color_by_match.call(offense.package.name, expected_offense.package.name)}
SERIALIZED_OFFENSE
end
end

def serialize_offenses(actual_offenses)
actual_offenses.map do |offense|
<<~SERIALIZED_OFFENSE
File: #{offense.file}
Message: #{offense.message}
Violation Type: #{offense.violation_type}
Package: #{offense.package.name}
SERIALIZED_OFFENSE
end
end

def get_packages
ParsePackwerk.all
end
Expand All @@ -112,25 +25,6 @@ def get_new_violations
end
end

def get_resulting_rubocop
write_file('config/default.yml', <<~YML.strip)
<%= PackageProtections.rubocop_yml %>
YML
YAML.safe_load(ERB.new(YAML.load_file('config/default.yml')).result(binding))
end

def offense(
package_name, message, file, violation_type
)
package = get_packages.find { |p| p.name == package_name }
PackageProtections::Offense.new(
package: package,
message: message,
file: file,
violation_type: violation_type
)
end

describe 'get_offenses' do
describe 'general behavior' do
it 'raises on incorrect protection configuration keys' do
Expand Down
3 changes: 1 addition & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
require 'pry'
require 'package_protections'
require 'rubocop/rspec/support'

require_relative 'support/application_fixture_helper'
require 'package_protections/rspec/support'

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
Expand Down

0 comments on commit 3e0333c

Please sign in to comment.