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
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user