class AssertGenerator::Klass

Attributes

numeric_precision[RW]
relative_date_today[RW]
relative_dates[RW]

Public Instance Methods

drillable_object(v) click to toggle source
# File lib/assert_generator.rb, line 142
def drillable_object(v)
  v.is_a?(Enumerable) || v.respond_to?(:attributes)
end
generate_assert_drillable_item(v, make_accessor, *accessor_params) click to toggle source
# File lib/assert_generator.rb, line 113
def generate_assert_drillable_item(v, make_accessor, *accessor_params)
  accessor = make_accessor.call(*accessor_params)

  if drillable_object(v)
    return generate_asserts(v, accessor, relative_dates, numeric_precision, nil)
  end

  if v.nil?
    out "assert_nil #{accessor}"
  elsif v.is_a?(true.class)
    out "assert #{accessor}"
  elsif v.is_a?(false.class)
    out "refute #{accessor}"

  elsif is_timey?(v)
    generate_date_time_assert(v, accessor)
  elsif v.is_a?(Date)
    generate_date_assert(v, accessor)
  elsif v.is_a?(Float) || v.is_a?(BigDecimal)
    generate_numeric_assert(v, accessor)
  else
    out "assert_equal #{v.inspect}, #{make_accessor.call(*accessor_params)}"
  end
end
generate_asserts(source, source_expr, relative_dates, numeric_precision, block) click to toggle source
# File lib/assert_generator.rb, line 34
def generate_asserts(source, source_expr, relative_dates, numeric_precision, block)
  if block
    unless !defined?(Rails) || Rails.env.test?
      raise 'AssertGenerator must only be used in the test context'
    end

    source_expr = block.call.to_s
    # rubocop:disable Security/Eval
    source ||= eval(source_expr, block.binding)
    # rubocop:enable Security/Eval
  end

  unless source_expr
    raise 'generate_asserts wants a source expression or a block'
  end

  if relative_dates
    self.relative_dates = relative_dates
    # rubocop:disable Security/Eval
    self.relative_date_today = eval(relative_dates, block&.binding ||  binding.of_caller(1))
    # rubocop:enable Security/Eval
  end

  self.numeric_precision = numeric_precision

  if source.is_a?(Hash)
    generate_asserts_hash(source, source_expr)
    return self
  end

  if source.respond_to?(:attributes)
    # AR or something that quacks like it
    generate_asserts_attributes(source, source_expr)
    return self
  end

  if source.is_a?(Range)
    generate_asserts_range(source, source_expr)
    return self
  end

  if source.is_a?(Enumerable)
    generate_asserts_enum(source, source_expr)
    return self
  end

  generate_assert_drillable_item(source, ->(_c) { source_expr }, source)
  self
end
generate_asserts_attributes(h, p) click to toggle source

Active Record, or anything else with an attributes hash

# File lib/assert_generator.rb, line 85
def generate_asserts_attributes(h, p)
  h.attributes.each do |k, v|
    generate_assert_drillable_item(v, ->(meth) { "#{p}.#{meth}" }, k)
  end
end
generate_asserts_enum(a, p) click to toggle source
# File lib/assert_generator.rb, line 100
def generate_asserts_enum(a, p)
  generate_assert_drillable_item(a.count, ->(_c) { "#{p}.count" }, p)

  a.each_with_index do |v, idx|
    generate_assert_drillable_item(v, ->(index) { "#{p}[#{index}]" }, idx)
  end
end
generate_asserts_hash(h, p) click to toggle source
# File lib/assert_generator.rb, line 91
def generate_asserts_hash(h, p)
  h.each do |k, v|
    generate_assert_drillable_item(v, ->(key) do
      key_literal = key.is_a?(Symbol) ? ":#{key}" : "'#{key}'"
      "#{p}[#{key_literal}]"
    end, k)
  end
end
generate_asserts_range(a, p) click to toggle source
# File lib/assert_generator.rb, line 108
def generate_asserts_range(a, p)
  generate_assert_drillable_item(a.first, ->(_x) { "#{p}.first" }, p)
  generate_assert_drillable_item(a.last, ->(_x) { "#{p}.last" }, p)
end
generate_date_assert(v, accessor) click to toggle source
# File lib/assert_generator.rb, line 146
def generate_date_assert(v, accessor)
  if relative_dates
    date_diff = v - relative_date_today
    if date_diff.to_i == 0
      out "assert_equal #{relative_dates}, #{accessor}"
    else
      out "assert_equal #{relative_dates} #{date_diff.to_i < 0 ? '-' : '+'} #{date_diff.to_i.abs}.days, #{accessor}"
    end
  else
    out "assert_equal Date.new(#{v.year}, #{v.month}, #{v.day}), #{accessor}"
  end
end
generate_date_time_assert(v, accessor) click to toggle source
# File lib/assert_generator.rb, line 159
def generate_date_time_assert(v, accessor)
  out "assert_equal DateTime.new(#{v.year}, #{v.month}, #{v.day}, " \
         + "#{v.hour}, #{v.min}, #{v.sec}, '#{v.zone}'), #{accessor}"
end
generate_numeric_assert(v, accessor) click to toggle source
# File lib/assert_generator.rb, line 164
def generate_numeric_assert(v, accessor)
  if numeric_precision
    delta = 10.0 ** -numeric_precision
    assert_code = "assert_in_delta #{v.to_f.round(numeric_precision)}, #{accessor}, #{delta}"
  else
    assert_code = "assert_equal #{v}, #{accessor}"
  end

  out assert_code
end
out(s) click to toggle source
# File lib/assert_generator.rb, line 138
def out(s)
  puts(s)
end

Private Instance Methods

is_timey?(v) click to toggle source
# File lib/assert_generator.rb, line 177
def is_timey?(v)
  v.is_a?(DateTime) || (defined?(ActiveSupport::TimeWithZone) && v.is_a?(ActiveSupport::TimeWithZone))
end