- doc/handbuch.txt: OCR-Text des COHERENT-/rdb-Handbuchs - demo/handbuch/ und test/handbuch_test.rb: Beispiele aus dem Lehrbuchteil, mise run test führt sie mit aus - search/seek: Schlüsselspalten aus dem Kopf der Schlüsseltabelle - gregorian -u ohne führende Null im Monat, mean ganzzahlig ohne .00 - Mit justify aufgefüllte Spaltennamen werden wieder gefunden - coherent.pdf in .gitignore
80 lines
2.4 KiB
Ruby
80 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'minitest/autorun'
|
|
require 'open3'
|
|
require 'tmpdir'
|
|
require 'fileutils'
|
|
|
|
# Runs the examples from the printed handbook (demo/handbuch/beispiele.txt) and
|
|
# compares each output with the one printed in the book. Whitespace does not
|
|
# count: the book aligns columns with spaces, we write tabs.
|
|
class HandbuchTest < Minitest::Test
|
|
ROOT = File.expand_path('..', __dir__)
|
|
DIR = File.join(ROOT, 'demo', 'handbuch')
|
|
|
|
Example = Struct.new(:dir, :title, :cmd, :expected, :deviation)
|
|
|
|
def self.examples
|
|
list = []
|
|
dir = '.'
|
|
title = nil
|
|
deviation = nil
|
|
cur = nil
|
|
lines = File.readlines(File.join(DIR, 'beispiele.txt'), chomp: true)
|
|
until lines.empty?
|
|
line = lines.shift
|
|
if line.start_with?('$ ')
|
|
cmd = line[2..]
|
|
cmd += "\n" + lines.shift while cmd.match?(/[|\\]\s*\z/) && lines.any?
|
|
cur = Example.new(dir, title, cmd, [], deviation)
|
|
list << cur
|
|
elsif line.start_with?('@ ')
|
|
dir = line[2..].strip
|
|
cur = nil
|
|
elsif line.start_with?('## ')
|
|
title = line[3..]
|
|
deviation = nil
|
|
cur = nil
|
|
elsif line.start_with?('! ')
|
|
deviation = line[2..]
|
|
elsif line.start_with?('#')
|
|
next
|
|
elsif cur
|
|
cur.expected << line
|
|
end
|
|
end
|
|
list
|
|
end
|
|
|
|
# Cells without whitespace; dash runs count as one dash; blank lines drop out.
|
|
def self.normalize(lines)
|
|
lines.map { |l| l.split.map { |w| w.match?(/\A-+\z/) ? '-' : w }.join(' ') }.reject(&:empty?)
|
|
end
|
|
|
|
def run_example(ex, scratch)
|
|
env = { 'PATH' => "#{File.join(ROOT, 'bin')}:#{ENV['PATH']}" }
|
|
out, _st = Open3.capture2e(env, 'sh', '-c', ex.cmd, chdir: File.join(scratch, ex.dir), stdin_data: '')
|
|
out.lines(chomp: true)
|
|
end
|
|
|
|
def test_examples_from_the_book
|
|
failures = []
|
|
fixed = []
|
|
Dir.mktmpdir('rdb-handbuch') do |scratch|
|
|
FileUtils.cp_r(Dir[File.join(DIR, '*')], scratch)
|
|
self.class.examples.each do |ex|
|
|
got = self.class.normalize(run_example(ex, scratch))
|
|
next if ex.expected.empty?
|
|
|
|
want = self.class.normalize(ex.expected)
|
|
if ex.deviation
|
|
fixed << "#{ex.title}: stimmt jetzt mit dem Buch überein, '!' entfernen" if got == want
|
|
elsif got != want
|
|
failures << "#{ex.title}\n $ #{ex.cmd}\n Buch: #{want.inspect}\n erhalten: #{got.inspect}"
|
|
end
|
|
end
|
|
end
|
|
assert_empty failures + fixed, (failures + fixed).join("\n\n")
|
|
end
|
|
end
|