lib/render/generator.rb in render-0.0.8 vs lib/render/generator.rb in render-0.0.9
- old
+ new
@@ -1,15 +1,17 @@
# Generators make fake data in non-live mode.
# They are used for attributes of a specified type, and whose name matches its defined matcher.
require "uuid"
require "render/errors"
+require "render/type"
require "date"
module Render
class Generator
@instances = []
+ FAUX_DATA_MAX = 1_000_000.freeze
class << self
attr_accessor :instances
# When in non-live mode, e.g. testing, you can use custom generators to make fake data for a given attribute type
@@ -23,16 +25,21 @@
generator
end
def trigger(type, to_match, algorithm_argument = nil)
generator = find(type, to_match)
- generator.trigger(algorithm_argument)
+ if generator
+ generator.trigger(algorithm_argument)
+ else
+ Render.logger.warn("Could not find generator for type #{type} with matcher for #{to_match}, using nil")
+ nil
+ end
end
def find(type, to_match)
instances.detect do |generator|
- generator.type.to_s.match(/#{type}/i) && to_match.match(generator.matcher)
+ (type == generator.type) && to_match.to_s.match(generator.matcher)
end
end
end
attr_accessor :type, :matcher, :algorithm
@@ -55,16 +62,68 @@
else
raise Errors::Generator::MalformedAlgorithm.new(algorithm)
end
end
- # Default set to ensure each type can generate fake data.
- Generator.create!(String, /.*/, proc { |attribute| "#{attribute.name} (generated)" })
- Generator.create!(Integer, /.*/, proc { rand(100) })
- Generator.create!(Float, /.*/, proc { rand(0.1..99).round(2) })
- Generator.create!(UUID, /.*/, proc { UUID.generate })
- Generator.create!(Time, /.*/, proc { |attribute| time = Time.now; (attribute.type == String) ? time.to_s : time })
+
+ def self.least_multiple(multiple_of, min)
+ lowest_multiple = multiple_of
+ until (lowest_multiple > min)
+ lowest_multiple += multiple_of
+ end
+ lowest_multiple
+ end
+
+ # Ensure each type can generate fake data.
+ # Standard JSON types
+ Generator.create!(String, /.*/, proc { |attribute|
+ min_length = attribute.min_length || -1
+ max_length = (attribute.max_length.to_i - 1)
+ "#{attribute.name} (generated)".ljust(min_length, "~")[0..max_length]
+ })
+
+ Generator.create!(Integer, /.*/, proc { |attribute|
+ min = attribute.minimum.to_i
+ max = attribute.maximum || FAUX_DATA_MAX
+ min += 1 if attribute.exclusive_minimum
+ max -= 1 if attribute.exclusive_maximum
+
+ if attribute.multiple_of
+ least_multiple(attribute.multiple_of, min)
+ else
+ rand(min..max)
+ end
+ })
+
+ # parsed from number
+ Generator.create!(Float, /.*/, proc { |attribute|
+ rounding_factor = 2
+ least_significant_number = 10 ** -rounding_factor
+
+ min = attribute.minimum.to_f
+ max = attribute.maximum || FAUX_DATA_MAX
+ min += least_significant_number if attribute.exclusive_minimum
+ max -= least_significant_number if attribute.exclusive_maximum
+
+ if attribute.multiple_of
+ least_multiple(attribute.multiple_of, min)
+ else
+ rand(min..max).round(rounding_factor)
+ end
+ })
+
Generator.create!(Type::Boolean, /.*/, proc { [true, false].sample })
+ Generator.create!(NilClass, /.*/, proc {}) # parsed from null
+ # Standard JSON formats
+ Generator.create!(DateTime, /.*/, proc { DateTime.now.to_s })
+ Generator.create!(URI, /.*/, proc { "http://localhost" })
+ Generator.create!(Type::Hostname, /.*/, proc { "localhost" })
+ Generator.create!(Type::Email, /.*/, proc { "you@localhost" })
+ Generator.create!(Type::IPv4, /.*/, proc { "127.0.0.1" })
+ Generator.create!(Type::IPv6, /.*/, proc { "::1" })
Generator.create!(Type::Enum, /.*/, proc { |attribute| attribute.enums.sample })
+ # Extended
+ Generator.create!(UUID, /.*/, proc { UUID.generate })
+ Generator.create!(Time, /.*/, proc { |attribute| time = Time.now; (attribute.type == String) ? time.to_s : time })
Generator.create!(Type::Date, /.*/, proc { Time.now.to_date })
end
end