New Python implemented test script

This commit is contained in:
Tzu-ping Chung 2014-09-09 16:10:50 +08:00
parent 7e5ba30c23
commit 8cc788ec59
6 changed files with 192 additions and 51 deletions

View file

@ -46,7 +46,7 @@ src/html_blocks.c: html_block_names.gperf
# Testing
test: hoedown
test/runner.sh ./hoedown test/MarkdownTest_1.0.3/Tests
test/runner.py
test-pl: hoedown
perl test/MarkdownTest_1.0.3/MarkdownTest.pl \

97
test/config.json Normal file
View file

@ -0,0 +1,97 @@
{
"tests": [
{
"input": "MarkdownTest_1.0.3/Tests/Amps and angle encoding.text",
"output": "MarkdownTest_1.0.3/Tests/Amps and angle encoding.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Auto links.text",
"output": "MarkdownTest_1.0.3/Tests/Auto links.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Backslash escapes.text",
"output": "MarkdownTest_1.0.3/Tests/Backslash escapes.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.text",
"output": "MarkdownTest_1.0.3/Tests/Blockquotes with code blocks.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Code Blocks.text",
"output": "MarkdownTest_1.0.3/Tests/Code Blocks.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Code Spans.text",
"output": "MarkdownTest_1.0.3/Tests/Code Spans.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text",
"output": "MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Horizontal rules.text",
"output": "MarkdownTest_1.0.3/Tests/Horizontal rules.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).text",
"output": "MarkdownTest_1.0.3/Tests/Inline HTML (Advanced).html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Inline HTML (Simple).text",
"output": "MarkdownTest_1.0.3/Tests/Inline HTML (Simple).html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Inline HTML comments.text",
"output": "MarkdownTest_1.0.3/Tests/Inline HTML comments.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Links, inline style.text",
"output": "MarkdownTest_1.0.3/Tests/Links, inline style.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Links, reference style.text",
"output": "MarkdownTest_1.0.3/Tests/Links, reference style.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Links, shortcut references.text",
"output": "MarkdownTest_1.0.3/Tests/Links, shortcut references.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Literal quotes in titles.text",
"output": "MarkdownTest_1.0.3/Tests/Literal quotes in titles.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text",
"output": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text",
"output": "MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Nested blockquotes.text",
"output": "MarkdownTest_1.0.3/Tests/Nested blockquotes.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Ordered and unordered lists.text",
"output": "MarkdownTest_1.0.3/Tests/Ordered and unordered lists.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Strong and em together.text",
"output": "MarkdownTest_1.0.3/Tests/Strong and em together.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Tabs.text",
"output": "MarkdownTest_1.0.3/Tests/Tabs.html"
},
{
"input": "MarkdownTest_1.0.3/Tests/Tidyness.text",
"output": "MarkdownTest_1.0.3/Tests/Tidyness.html"
},
{
"input": "Tests/Escape character.text",
"output": "Tests/Escape character.html",
"skip": true
}
]
}

94
test/runner.py Executable file
View file

@ -0,0 +1,94 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function
import os
import sys
import copy
import json
import re
import subprocess
import unittest
DLN = '======================================================================'
SLN = '----------------------------------------------------------------------'
TEST_ROOT = os.path.dirname(__file__)
HOEDOWN = [os.path.join(os.path.dirname(TEST_ROOT), 'hoedown')]
TIDY = ['tidy', '--show-body-only', '1', '--show-warnings', '0',
'--quiet', '1']
CONFIG_PATH = os.path.join(TEST_ROOT, 'config.json')
SLUGIFY_PATTERN = re.compile(r'\W')
class TestFailed(AssertionError):
def __init__(self, name, expected, got):
super(TestFailed, self).__init__(self)
description_format = (
'{name}\nExpected\n{sln}\n{expected}\n\n'
'Got\n{sln}\n{got}\n\n'
)
self.description = description_format.format(
dln=DLN, sln=SLN, name=name,
expected=expected.strip(), got=got.strip(),
)
def __str__(self):
return self.description
def _test_func(test_case):
flags = test_case.get('flags') or []
hoedown_proc = subprocess.Popen(
HOEDOWN + flags + [os.path.join(TEST_ROOT, test_case['input'])],
stdout=subprocess.PIPE,
)
hoedown_proc.wait()
got_tidy_proc = subprocess.Popen(
TIDY, stdin=hoedown_proc.stdout, stdout=subprocess.PIPE,
)
got_tidy_proc.wait()
got = got_tidy_proc.stdout.read()
expected_tidy_proc = subprocess.Popen(
TIDY + [os.path.join(TEST_ROOT, test_case['output'])],
stdout=subprocess.PIPE,
)
expected_tidy_proc.wait()
expected = expected_tidy_proc.stdout.read()
try:
assert expected == got
except AssertionError:
raise TestFailed(test_case['input'], expected, got)
def _make_test(test_case):
return lambda self: _test_func(test_case)
class MarkdownTestCaseMeta(type):
"""Meta class for ``MarkdownTestCase`` to inject test cases on the fly.
"""
def __new__(meta, name, bases, attrs):
with open(CONFIG_PATH) as f:
config = json.load(f)
for test in config['tests']:
input_name = test['input']
attr_name = 'test_' + SLUGIFY_PATTERN.sub(
'_', os.path.splitext(input_name)[0].lower(),
)
func = _make_test(test)
func.__doc__ = input_name
if test.get('skip', False):
func = unittest.skip(input_name)(func)
attrs[attr_name] = func
return type.__new__(meta, name, bases, attrs)
class MarkdownTestCase(unittest.TestCase):
__metaclass__ = MarkdownTestCaseMeta
if __name__ == '__main__':
unittest.main()

View file

@ -1,50 +0,0 @@
#!/bin/sh
POSIXLY_CORRECT=1
export POSIXLY_CORRECT
TIDY='tidy --show-body-only 1 --quiet 1 --show-warnings 0'
SCRIPT="$1"
TESTDIR="$2"
PASSED=0
FAILED=0
abort() {
echo "Error: $*"
exit 1
}
test -f "$SCRIPT" || abort "argument #1 invalid; not a file"
test -x "$SCRIPT" || abort "argument #1 invalid; not executable"
echo "" | "$SCRIPT" || abort "argument #1 invalid; script failed to run"
test -d "$TESTDIR" || abort "argument #2 invalid; not a directory"
for TEXT in "$TESTDIR"/*.text; do
test -f "$TEXT" || abort "empty or invalid test directory"
printf "$(basename "$TEXT" .text) ... "
HTML=$(echo "$TEXT" | sed 's/\.text$/.html/')
# We use mktemp to create an unpredictable, temporary filename.
# The created file is immediately deleted, since we only want a
# name to pass to mkfifo and "mktemp -u" is not portable.
PIPE=$(mktemp .testpipe-XXXXXXXX)
test -f "$PIPE" -a -n "$PIPE" || abort "mktemp failed"
trap 'rm -f "$PIPE"' EXIT INT TERM HUP
rm -f "$PIPE"
mkfifo -m 0600 "$PIPE" || abort "unable to create named pipe"
$SCRIPT "$TEXT" | $TIDY > "$PIPE" &
DIFF=$($TIDY "$HTML" | diff "$PIPE" -)
if test "$?" = 0; then
PASSED=$(expr $PASSED + 1)
echo OK
else
FAILED=$(expr $FAILED + 1)
echo FAILED
printf "\n$DIFF\n\n"
fi
rm -f "$PIPE"
done
printf "\n\n$PASSED passed; $FAILED failed.\n"
test "$FAILED" = 0 || exit 1