|
require "pastel" |
|
require "tty-table" |
|
$pastel = Pastel.new(enabled: true) |
|
|
|
class Thing |
|
attr_reader :a, :b, :c |
|
|
|
def initialize(a, b, c) |
|
@a, @b, @c = a, b, c |
|
end |
|
|
|
def <=>(other) |
|
cursor <=> other.cursor |
|
end |
|
|
|
def cursor |
|
[a, b, c] |
|
end |
|
|
|
def after?(a, b, c, inclusive: false) |
|
(inclusive && [a, b, c] == cursor) || |
|
(self.a == a && self.b == b && self.c > c) || |
|
(self.a == a && self.b > b) || |
|
(self.a > a) |
|
end |
|
|
|
def before?(a, b, c, inclusive: false) |
|
(inclusive && [a, b, c] == cursor) || |
|
(self.a == a && self.b == b && self.c < c) || |
|
(self.a == a && self.b < b) || |
|
(self.a < a) |
|
end |
|
|
|
def inspect |
|
"<Thing #{self}>" |
|
end |
|
|
|
def to_s |
|
[a, b, c].join(".") |
|
end |
|
end |
|
|
|
things = 1.upto(3).flat_map do |a| |
|
1.upto(3).flat_map do |b| |
|
1.upto(3).map do |c| |
|
Thing.new(a, b, c) |
|
end |
|
end |
|
end |
|
|
|
def array_comparison(actual, expected, difference_limit: 3) |
|
if actual == expected |
|
$pastel.green(actual.size) |
|
else |
|
added = (actual - expected).map { "+#{_1}" } |
|
missing = (expected - actual).map { "-#{_1}" } |
|
|
|
results = added + missing |
|
results = results.first(difference_limit) if difference_limit && results.size > difference_limit |
|
$pastel.red(results.join(" ")) |
|
end |
|
end |
|
|
|
table = TTY::Table.new(header: ["", "after", "after(i)", "before", "before(i)"]) |
|
things.each.with_index do |thing, index| |
|
name = "#{index + 1}. #{$pastel.blue(thing.inspect)}" |
|
|
|
expected_after_things = things[(index + 1)..] |
|
after_things = things.select { _1.after?(*thing.cursor) } |
|
after_result = array_comparison(after_things, expected_after_things) |
|
|
|
expected_after_things_inclusive = things[index..] |
|
after_things_inclusive = things.select { _1.after?(*thing.cursor, inclusive: true) } |
|
after_inclusive_result = array_comparison(after_things_inclusive, expected_after_things_inclusive) |
|
|
|
expected_before_things = things[0, index] |
|
before_things = things.select { _1.before?(*thing.cursor) } |
|
before_result = array_comparison(before_things, expected_before_things) |
|
|
|
expected_before_things_inclusive = things[0, index + 1] |
|
before_things_inclusive = things.select { _1.before?(*thing.cursor, inclusive: true) } |
|
before_inclusive_result = array_comparison(before_things_inclusive, expected_before_things_inclusive) |
|
|
|
table << [name, after_result, after_inclusive_result, before_result, before_inclusive_result] |
|
end |
|
|
|
puts table.render(:unicode, padding: [0, 1], alignments: [:right] * 5) |