Skip to content
Open
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
89 changes: 89 additions & 0 deletions lib/erd/factory_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
require 'open3'

class FactoryHelper
# [str]
attr_accessor :schema_content

# corresponding initial values (checked & grouped by regex) in factory file, using lambda to take in
# column name and returns the string with the right type of initial value
DEFAULT_VALUES = {
/string|text/ => lambda { |n| "#{n} \{ \'MyString\' \}" },
/integer|bigint|float|decimal/ => lambda { |n| "#{n} \{ 1 \}" },
/boolean/ => lambda { |n| "#{n} \{ true \}" },
/datetime|timestamp/ => lambda { |n| "#{n} \{ Time.now \}" },
/date/ => lambda { |n| "#{n} \{ Date.today \}" }
}

# Adapter Pattern
# Formats column contents from schema into array
def format_content(str)
str.split("create_table")
end

def create_factories
schema_content.each { |block|
# Create factory file if block is not empty
create_factory_file(block) if !block.strip.empty?
}
end

private
def create_factory_file(block)
# Prunes all leading and trailing spaces
cols = block.split("\n", -1)

file_content = ""
# Parses the table name of the first column
factory_name = parse_table_name(cols[0]).strip
file_content += "FactoryBot.define do\n\tfactory \:#{factory_name} do\n\t\t"

# Parses all lines matching the template of schema columns, excluding trailing (end)
cols = cols.filter!{ |col| col.match?(/^\s*t\./) }
if !cols.nil?
parsed_columns = cols.map { |col| parse_line(col) }
file_content += parsed_columns.filter{ |pc| !pc.empty? }.join("\n\t\t")
end

file_content += "\n\tend\nend"

# Writes to the corresponding factory file
Open3.popen2e("echo \"#{file_content}\" > test/factories/#{factory_name}.rb") {|i, oe, t|
puts oe.read()
puts "test/factories/#{factory_name}.rb created!"
}
end

def parse_table_name(create_table_line)
# Extracts table name that is followed, pruning surrounding quotes
create_table_line.split(",", 2).first.gsub("\"", "")
end

def parse_line(column_line)
# Column name enclosed around the quotation marks
column_type = column_line.scan(/\..*\s/).first
# Ignore indexes that are not used on the application level
return "" if column_type.match?(/index/)
column_name = column_line.scan(/\".*\"/).first
parse_column(column_name, column_type)
end

def parse_column(column_name, type)
# Ignores "created_at" and "updated_at"
return "" if column_name.match?(/^\"(created_at|updated_at)\"$/)
# Processes FK fields that ends with "_id", there should be another way to handle FK columns with aliases
return parse_references(column_name.gsub(/([\"\[\]]|_id\"$)/, "")) if column_name.match?(/_id\"$/)


# value_type is of type [string -> string]
value_type = DEFAULT_VALUES.find { |pattern, _| type.match?(pattern) }
if !value_type.nil?
# Calls the lambda that is mapped to by the corresponding pattern
return DEFAULT_VALUES[value_type.first].call(column_name.gsub(/\"/, ""))
end
""
end

def parse_references(referenced_table_name)
"association :#{referenced_table_name.strip}"
end
end
19 changes: 19 additions & 0 deletions lib/erd/make_factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env ruby
require 'open3'
require './lib/erd/factory_helper'

def main()
# Removes previous factory files
Open3.popen2e("rm -rf test/factories/*"){ |i, oe, t| puts oe.read() }

helper = FactoryHelper.new()

# Reads all table names and columns in the db/schema file
Open3.popen2e("awk '/create_table/,/end/' \"db/schema.rb\"") { |i, oe, t|
helper.schema_content = helper.format_content(oe.read())
}

helper.create_factories()
end

main()
141 changes: 141 additions & 0 deletions test/contexts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
require "test/sets/certification_types"
require "test/sets/certifications"
require "test/sets/charge_types"
require "test/sets/charges"
require "test/sets/checkouts"
require "test/sets/delayed_jobs"
require "test/sets/event_types"
require "test/sets/events"
require "test/sets/faq"
require "test/sets/memberships"
require "test/sets/notes"
require "test/sets/organization_aliases"
require "test/sets/organization_build_statuses"
require "test/sets/organization_build_steps"
require "test/sets/organization_categories"
require "test/sets/organization_status_types"
require "test/sets/organization_timeline_entries"
require "test/sets/organization_timeline_entry_types"
require "test/sets/organizations"
require "test/sets/participants"
require "test/sets/scissor_lift_checkouts"
require "test/sets/scissor_lifts"
require "test/sets/shift_participants"
require "test/sets/shift_types"
require "test/sets/shifts"
require "test/sets/store_items"
require "test/sets/store_purchases"
require "test/sets/tasks"
require "test/sets/tool_inventories"
require "test/sets/tool_inventory_tools"
require "test/sets/tool_type_certifications"
require "test/sets/tool_types"
require "test/sets/tools"

module Contexts
include Contexts::CertificationTypes
include Contexts::Certifications
include Contexts::ChargeTypes
include Contexts::Charges
include Contexts::Checkouts
include Contexts::DelayedJobs
include Contexts::EventTypes
include Contexts::Events
include Contexts::Faq
include Contexts::Memberships
include Contexts::Notes
include Contexts::OrganizationAliases
include Contexts::OrganizationBuildStatuses
include Contexts::OrganizationBuildSteps
include Contexts::OrganizationCategories
include Contexts::OrganizationStatusTypes
include Contexts::OrganizationTimelineEntries
include Contexts::OrganizationTimelineEntryTypes
include Contexts::Organizations
include Contexts::Participants
include Contexts::ScissorLiftCheckouts
include Contexts::ScissorLifts
include Contexts::ShiftParticipants
include Contexts::ShiftTypes
include Contexts::Shifts
include Contexts::StoreItems
include Contexts::StorePurchases
include Contexts::Tasks
include Contexts::ToolInventories
include Contexts::ToolInventoryTools
include Contexts::ToolTypeCertifications
include Contexts::ToolTypes
include Contexts::Tools

def create_all
create_certification_types
create_certifications
create_charge_types
create_charges
create_checkouts
create_delayed_jobs
create_event_types
create_events
create_faq
create_memberships
create_notes
create_organization_aliases
create_organization_build_statuses
create_organization_build_steps
create_organization_categories
create_organization_status_types
create_organization_timeline_entries
create_organization_timeline_entry_types
create_organizations
create_participants
create_scissor_lift_checkouts
create_scissor_lifts
create_shift_participants
create_shift_types
create_shifts
create_store_items
create_store_purchases
create_tasks
create_tool_inventories
create_tool_inventory_tools
create_tool_type_certifications
create_tool_types
create_tools
end

def destroy_all
destroy_certification_types
destroy_certifications
destroy_charge_types
destroy_charges
destroy_checkouts
destroy_delayed_jobs
destroy_event_types
destroy_events
destroy_faq
destroy_memberships
destroy_notes
destroy_organization_aliases
destroy_organization_build_statuses
destroy_organization_build_steps
destroy_organization_categories
destroy_organization_status_types
destroy_organization_timeline_entries
destroy_organization_timeline_entry_types
destroy_organizations
destroy_participants
destroy_scissor_lift_checkouts
destroy_scissor_lifts
destroy_shift_participants
destroy_shift_types
destroy_shifts
destroy_store_items
destroy_store_purchases
destroy_tasks
destroy_tool_inventories
destroy_tool_inventory_tools
destroy_tool_type_certifications
destroy_tool_types
destroy_tools
end
end
5 changes: 5 additions & 0 deletions test/factories/certification_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FactoryBot.define do
factory :certification_types do
name { 'MyString' }
end
end
6 changes: 6 additions & 0 deletions test/factories/certifications.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FactoryBot.define do
factory :certifications do
association :participant
association :certification_type
end
end
8 changes: 8 additions & 0 deletions test/factories/charge_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FactoryBot.define do
factory :charge_types do
name { 'MyString' }
requires_booth_chair_approval { true }
default_amount { 1 }
description { 'MyString' }
end
end
13 changes: 13 additions & 0 deletions test/factories/charges.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FactoryBot.define do
factory :charges do
association :organization
association :charge_type
amount { 1 }
description { 'MyString' }
association :issuing_participant
association :receiving_participant
charged_at { Time.now }
is_approved { true }
association :creating_participant
end
end
9 changes: 9 additions & 0 deletions test/factories/checkouts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FactoryBot.define do
factory :checkouts do
association :tool
checked_out_at { Time.now }
checked_in_at { Time.now }
association :participant
association :organization
end
end
13 changes: 13 additions & 0 deletions test/factories/delayed_jobs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FactoryBot.define do
factory :delayed_jobs do
priority { 1 }
attempts { 1 }
handler { 'MyString' }
last_error { 'MyString' }
run_at { Time.now }
locked_at { Time.now }
failed_at { Time.now }
locked_by { 'MyString' }
queue { 'MyString' }
end
end
6 changes: 6 additions & 0 deletions test/factories/event_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FactoryBot.define do
factory :event_types do
display { true }
name { 'MyString' }
end
end
8 changes: 8 additions & 0 deletions test/factories/events.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FactoryBot.define do
factory :events do
is_done { true }
association :event_type
description { 'MyString' }
association :participant
end
end
7 changes: 7 additions & 0 deletions test/factories/faq.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FactoryBot.define do
factory :faq do
question { 'MyString' }
answer { 'MyString' }
association :organization_category
end
end
11 changes: 11 additions & 0 deletions test/factories/memberships.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FactoryBot.define do
factory :memberships do
association :organization
association :participant
is_booth_chair { true }
title { 'MyString' }
booth_chair_order { 1 }
is_in_csv { true }
is_added_by_csv { true }
end
end
10 changes: 10 additions & 0 deletions test/factories/notes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FactoryBot.define do
factory :notes do
association :participant
association :organization
hidden { true }
title { 'MyString' }
value { 'MyString' }
color { 'MyString' }
end
end
6 changes: 6 additions & 0 deletions test/factories/organization_aliases.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FactoryBot.define do
factory :organization_aliases do
name { 'MyString' }
association :organization
end
end
6 changes: 6 additions & 0 deletions test/factories/organization_build_statuses.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FactoryBot.define do
factory :organization_build_statuses do
association :organization
status_type { 'MyString' }
end
end
9 changes: 9 additions & 0 deletions test/factories/organization_build_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FactoryBot.define do
factory :organization_build_steps do
title { 'MyString' }
requirements { 'MyString' }
step { 1 }
completed { true }
association :organization_build_status
end
end
7 changes: 7 additions & 0 deletions test/factories/organization_categories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FactoryBot.define do
factory :organization_categories do
name { 'MyString' }
building { true }
lookup_key { 'MyString' }
end
end
6 changes: 6 additions & 0 deletions test/factories/organization_status_types.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FactoryBot.define do
factory :organization_status_types do
name { 'MyString' }
display { true }
end
end
Loading