1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
module UnitTests
module ModelCreationStrategies
class ActiveModel
def self.call(name, attribute_names = [], options = {}, &block)
new(name, attribute_names, options, &block).call
end
def initialize(name, attribute_names = [], options = {}, &block)
@name = name
@attribute_names =
if attribute_names.is_a?(Hash)
# mimicking columns
attribute_names.keys
else
attribute_names
end
@options = options
@model_customizers = []
if block
customize_model(&block)
end
end
def customize_model(&block)
model_customizers << block
end
def call
ClassBuilder.define_class(name, Model).tap do |model|
attribute_names.each do |attribute_name|
model.attribute(attribute_name)
end
model_customizers.each do |block|
run_block(model, block)
end
end
end
private
attr_reader :name, :attribute_names, :model_customizers, :options
def run_block(model, block)
if block
if block.arity == 0
model.class_eval(&block)
else
block.call(model)
end
end
end
module PoorMansAttributes
extend ActiveSupport::Concern
included do
class_attribute :attribute_names
self.attribute_names = Set.new
end
module ClassMethods
def attribute(name)
include attributes_module
name = name.to_sym
if
attribute_names.include?(name) &&
attributes_module.instance_methods.include?(name)
attributes_module.module_eval do
remove_method(name)
remove_method("#{name}=")
end
end
self.attribute_names += [name]
attributes_module.module_eval do
define_method(name) do
attributes[name]
end
define_method("#{name}=") do |value|
attributes[name] = value
end
end
end
private
def attributes_module
@_attributes_module ||= Module.new
end
end
attr_reader :attributes
def initialize(attributes = {})
@attributes = attributes.symbolize_keys
end
def inspect
middle = '%s:0x%014x%s' % [
self.class,
object_id * 2,
" #{inspected_attributes.join(' ')}",
]
"#<#{middle.strip}>"
end
private
def inspected_attributes
self.class.attribute_names.map do |name|
"#{name}: #{attributes[name].inspect}"
end
end
end
class Model
include ::ActiveModel::Model
if defined?(::ActiveModel::Attributes)
include ::ActiveModel::Attributes
else
include PoorMansAttributes
end
end
end
end
end
|