Last active
April 18, 2019 06:10
-
-
Save nerdinand/3ee85a3da5c8095a6333f05105fef772 to your computer and use it in GitHub Desktop.
Poor man's fixtures for hanami
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# A quick and dirty fixture implementation for use with Hanami, RSpec and PostgreSQL. | |
# Fixtures will be loaded when the suite starts and will be reset using transactions | |
# to the same state after each test case. | |
# | |
# Supports associations like so (author has many books): | |
# | |
# # authors.yml | |
# rowling: | |
# name: J.K. Rowling | |
# | |
# # books.yml | |
# hp1: | |
# name: Harry Potter and the Philosopher's stone | |
# author: rowling | |
# | |
# put this in spec/support/fixtures.rb | |
# put your fixtures in spec/fixtures | |
ENV['HANAMI_ENV'] = 'test' | |
require 'yaml' | |
fixtures_path = 'spec/fixtures' | |
@connection = Hanami::Model.configuration.connection | |
@fixture_landscape = {} | |
@execution_plan = {} | |
def foreign_key_columns(table_name) | |
@connection[table_name.to_sym].columns.select do |column| | |
column != :id && column.to_s.end_with?('id') | |
end | |
end | |
def add_timestamps_if_necessary(attributes) | |
['created_at', 'updated_at'].each do |timestamp_attribute| | |
if attributes[timestamp_attribute].nil? | |
attributes[timestamp_attribute] = DateTime.now | |
end | |
end | |
attributes | |
end | |
def record_name_to_id(record_name) | |
record_name.hash | |
end | |
def lookup_foreign_keys(table_name, attributes) | |
foreign_key_columns = foreign_key_columns(table_name) | |
foreign_key_columns.each do |foreign_key_column| | |
foreign_record_name = attributes.delete(foreign_key_column.to_s[0..-4]) | |
attributes[foreign_key_column.to_s] = record_name_to_id(foreign_record_name) | |
end | |
attributes | |
end | |
def add_id_column(record_name, attributes) | |
attributes['id'] = record_name_to_id(record_name) | |
attributes | |
end | |
def enrich_attributes(table_name, record_name, attributes) | |
add_id_column(record_name, add_timestamps_if_necessary(lookup_foreign_keys(table_name, attributes))) | |
end | |
def process_records(table_name, records) | |
records.each do |record_name, attributes| | |
@execution_plan[table_name] ||= [] | |
@execution_plan[table_name] << enrich_attributes(table_name, record_name, attributes) | |
end | |
end | |
def process_fixture(fixture_path) | |
fixture_hash = YAML.load(File.read(fixture_path)) | |
table_name = File.basename(fixture_path, '.*') | |
@fixture_landscape.merge!({table_name => fixture_hash}) | |
process_records(table_name, fixture_hash) | |
end | |
def insert_records | |
@execution_plan.each do |table_name, records| | |
records.each do |attributes| | |
puts "INSERT #{table_name}: #{attributes}" | |
@connection[table_name.to_sym].insert(attributes) | |
end | |
end | |
end | |
@connection.transaction do | |
puts "SET CONSTRAINTS ALL DEFERRED;" | |
@connection.run("SET CONSTRAINTS ALL DEFERRED;") | |
Dir.glob(fixtures_path + '/**/*.yml').each do |fixture_path| | |
process_fixture(fixture_path) | |
end | |
insert_records | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Add this stuff to your spec_helper.rb | |
config.around(:each) do |example| | |
Hanami::Model.configuration.connection.transaction(savepoint: true) do | |
example.run | |
raise Sequel::Rollback | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment