Files
rdb/test/handbuch_test.rb
T
wkh df8bcdfaf1 Handbuch-Beispiele als Test, search/seek mit Schlüsseltabelle
- 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
2026-10-14 21:48:46 +02:00

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