git @ Cat's Eye Technologies Falderal / c00bced
Use LFs instead of CRLFs for EOLs everywhere. Cat's Eye Technologies 6 years ago
21 changed file(s) with 627 addition(s) and 627 deletion(s). Raw diff Collapse all Expand all
0 `py-falderal`
1 =============
2
3 `py-falderal` is an implementation of Falderal in Python 2.5.x.
4
5 Motivation
6 ----------
7
8 There are a few reasons I had for re-implementing Falderal in Python:
9
10 * The original Falderal implementation grew out of a Haskell-specific hack,
11 and it shows in how it's written.
12
13 * Fewer discrepancies between platforms. In particular, `ghc` for Windows
14 likes to operate in terms of MS-DOS end-of-lines (`CR`, `LF`), but I tend
15 to use it under Cygwin using Unix end-of-lines (`LF`).
16
17 * Smaller install burden: Python sometimes comes bundled with the operating
18 system; Haskell rarely does.
19
20 * Haskell, being lazy, makes it harder to deal with exceptions; unless the
21 Haskell expression is being evaluated both strictly and deeply, exceptions
22 can slip by. For Falderal's purposes, this seems artificial, at best.
23
24 * Relatedly, Python (or CPython, anyway) has better error behavior than
25 Haskell (or `ghc`, anyway); when it crashes, it dumps a backtrace (which I
26 can then analyze), instead of just saying something pithy like `Prelude:
27 empty list` (which I can't.)
28
29 * Any standard worth its salt should probably have more than one
30 implementation, anyway.
31
32 Features
33 --------
34
35 That last point notwithstanding, `py-falderal` implements a slightly different
36 subset of the Falderal test file format than the Haskell implementation does.
37
38 In particular,
39
40 * It mainly implements `shell command` implementations. In practice, partly
41 due to the "strict & deep" evaluation problem mentioned above, that's how
42 I've been using Falderal anyway; also, its approach makes it somewhat more
43 useful for "end-to-end" testing of compilers and interpreters, than for
44 unit-testing individual text-processing functions inside a program.
45 (Technically, it implements `Haskell function` implementations too, but it's
46 something of a hack that uses `ghc -e`.)
47
48 * I plan for it to *only* understand indented Falderal blocks. The idea is
49 that the Falderal tests will almost certainly be embedded in a Markdown
50 document (possibly with Bird-style literate code also embedded therein,)
51 and no extra processing should be required to format something readable
52 from that Markdown. The four-space-indented Falderal blocks come out as
53 preformatted blocks, which is quite good enough. Relatedly,
54
55 * It does no formatting. There are a set of classes for parsing Falderal
56 files (`Document`s) into blocks (`Block`s), and methods for formatting
57 blocks into text. But aside from reporting the results of a test run,
58 they're not used by the utility to format Falderal files. If you want to
59 do extra processing on your Falderal/Markdown file so that Falderal
60 blocks are prettier, you certainly can do that, but you'll need to write
61 your own script which uses these classes, for it is outside the scope of
62 `py-falderal`.
63
64 * I'm not so sure about `-> Functionality "blah" is implemented by shell
65 command "flargh"` anymore. I mean, it should certainly be the case that
66 functionalities can have multiple implementations, but
67 * Perhaps implementations should not be specified in Falderal documents
68 at all -- that approach is more abstract. But it requires them to be
69 specified on the tool's command line, which in practice requires there
70 to be a driver script to run the tests, for a particular implementation;
71 but this is not necessarily a bad thing.
72 * When `falderal` is run on more than one input file, what is the scope
73 of a functionality, and what is the scope of the implementations of a
74 functionality? Currently, in the Falderal semantics, that scope is
75 global, and maybe that is appropriate; but maybe finer-grained control
76 would be nice.
77
78 * `py-falderal` also does not try to optimize the test runs into a block of
79 test runs (which didn't work out so well in the Haskell implementation,
80 for `shell command`s, anyway.)
0 `py-falderal`
1 =============
2
3 `py-falderal` is an implementation of Falderal in Python 2.5.x.
4
5 Motivation
6 ----------
7
8 There are a few reasons I had for re-implementing Falderal in Python:
9
10 * The original Falderal implementation grew out of a Haskell-specific hack,
11 and it shows in how it's written.
12
13 * Fewer discrepancies between platforms. In particular, `ghc` for Windows
14 likes to operate in terms of MS-DOS end-of-lines (`CR`, `LF`), but I tend
15 to use it under Cygwin using Unix end-of-lines (`LF`).
16
17 * Smaller install burden: Python sometimes comes bundled with the operating
18 system; Haskell rarely does.
19
20 * Haskell, being lazy, makes it harder to deal with exceptions; unless the
21 Haskell expression is being evaluated both strictly and deeply, exceptions
22 can slip by. For Falderal's purposes, this seems artificial, at best.
23
24 * Relatedly, Python (or CPython, anyway) has better error behavior than
25 Haskell (or `ghc`, anyway); when it crashes, it dumps a backtrace (which I
26 can then analyze), instead of just saying something pithy like `Prelude:
27 empty list` (which I can't.)
28
29 * Any standard worth its salt should probably have more than one
30 implementation, anyway.
31
32 Features
33 --------
34
35 That last point notwithstanding, `py-falderal` implements a slightly different
36 subset of the Falderal test file format than the Haskell implementation does.
37
38 In particular,
39
40 * It mainly implements `shell command` implementations. In practice, partly
41 due to the "strict & deep" evaluation problem mentioned above, that's how
42 I've been using Falderal anyway; also, its approach makes it somewhat more
43 useful for "end-to-end" testing of compilers and interpreters, than for
44 unit-testing individual text-processing functions inside a program.
45 (Technically, it implements `Haskell function` implementations too, but it's
46 something of a hack that uses `ghc -e`.)
47
48 * I plan for it to *only* understand indented Falderal blocks. The idea is
49 that the Falderal tests will almost certainly be embedded in a Markdown
50 document (possibly with Bird-style literate code also embedded therein,)
51 and no extra processing should be required to format something readable
52 from that Markdown. The four-space-indented Falderal blocks come out as
53 preformatted blocks, which is quite good enough. Relatedly,
54
55 * It does no formatting. There are a set of classes for parsing Falderal
56 files (`Document`s) into blocks (`Block`s), and methods for formatting
57 blocks into text. But aside from reporting the results of a test run,
58 they're not used by the utility to format Falderal files. If you want to
59 do extra processing on your Falderal/Markdown file so that Falderal
60 blocks are prettier, you certainly can do that, but you'll need to write
61 your own script which uses these classes, for it is outside the scope of
62 `py-falderal`.
63
64 * I'm not so sure about `-> Functionality "blah" is implemented by shell
65 command "flargh"` anymore. I mean, it should certainly be the case that
66 functionalities can have multiple implementations, but
67 * Perhaps implementations should not be specified in Falderal documents
68 at all -- that approach is more abstract. But it requires them to be
69 specified on the tool's command line, which in practice requires there
70 to be a driver script to run the tests, for a particular implementation;
71 but this is not necessarily a bad thing.
72 * When `falderal` is run on more than one input file, what is the scope
73 of a functionality, and what is the scope of the implementations of a
74 functionality? Currently, in the Falderal semantics, that scope is
75 global, and maybe that is appropriate; but maybe finer-grained control
76 would be nice.
77
78 * `py-falderal` also does not try to optimize the test runs into a block of
79 test runs (which didn't work out so well in the Haskell implementation,
80 for `shell command`s, anyway.)
0 """"\
1 Usage: falderal [<option>...] <filename.markdown>...
2 """
3
4 from optparse import OptionParser
5 import sys
6
7 from falderal.objects import Document, FalderalSyntaxError
8
9
10 def main(args):
11 parser = OptionParser()
12
13 parser.add_option("-b", "--substring-error",
14 action="store_true", default=False,
15 help="match expected errors as substrings")
16 parser.add_option("-c", "--clear-functionalities",
17 metavar="NAMES", default=None,
18 help="clear all implementations of the specified "
19 "functionalities that were specified in pragmas "
20 "in documents; useful in conjunction with -f. "
21 "Format of the argument is a colon-seperated "
22 "list of functionality names.")
23 parser.add_option("-d", "--dump",
24 action="store_true", default=False)
25 parser.add_option("-f", "--functionalities",
26 metavar="SPEC",
27 help="specify implementations of functionalies, "
28 "over and above what are specified in pragmas "
29 "in documents (not yet implemented)")
30 parser.add_option("-t", "--test",
31 action="store_true", default=False,
32 help="run internal tests and exit")
33 parser.add_option("-v", "--verbose",
34 action="store_true", default=False,
0 """"\
1 Usage: falderal [<option>...] <filename.markdown>...
2 """
3
4 from optparse import OptionParser
5 import sys
6
7 from falderal.objects import Document, FalderalSyntaxError
8
9
10 def main(args):
11 parser = OptionParser()
12
13 parser.add_option("-b", "--substring-error",
14 action="store_true", default=False,
15 help="match expected errors as substrings")
16 parser.add_option("-c", "--clear-functionalities",
17 metavar="NAMES", default=None,
18 help="clear all implementations of the specified "
19 "functionalities that were specified in pragmas "
20 "in documents; useful in conjunction with -f. "
21 "Format of the argument is a colon-seperated "
22 "list of functionality names.")
23 parser.add_option("-d", "--dump",
24 action="store_true", default=False)
25 parser.add_option("-f", "--functionalities",
26 metavar="SPEC",
27 help="specify implementations of functionalies, "
28 "over and above what are specified in pragmas "
29 "in documents (not yet implemented)")
30 parser.add_option("-t", "--test",
31 action="store_true", default=False,
32 help="run internal tests and exit")
33 parser.add_option("-v", "--verbose",
34 action="store_true", default=False,
3535 help="run verbosely (currently only affects internal "
36 "tests)")
37
38 (options, args) = parser.parse_args(args[1:])
39
40 # for compatibility with previous versions of falderal
41 if args and args[0] == 'test':
42 args = args[1:]
43
44 if options.test:
45 import doctest
46 import falderal.objects
47 (failure_count, test_count) = \
48 doctest.testmod(falderal.objects,
49 optionflags=doctest.NORMALIZE_WHITESPACE)
50 if failure_count > 0:
51 return 1
52 else:
53 return 0
54
55 try:
56 return test_documents(options, args)
57 except FalderalSyntaxError as e:
58 # if options.show_full_exception: do that, else
59 sys.stderr.write('%s: %s\n' % (e.__class__.__name__, str(e)))
60 return 1
61
62
63 def test_documents(options, args):
64 # load Falderal documents
65 documents = []
66 for filename in args:
67 documents.append(Document.load(filename))
68
69 # collect functionalities
70 # XXX if any implementations are given in the command line,
71 # we can put them in here.
72 functionalities = {}
73
74 # create Falderal Tests
75 tests = []
76 for document in documents:
77 tests += document.parse_blocks_to_tests(functionalities)
78
79 if options.clear_functionalities:
80 for name in options.clear_functionalities.split(':'):
81 n = name.strip()
82 if n in functionalities:
83 functionalities[n].implementations = []
84
85 # XXX lint: check for no tests, or no implementations of a functionality
86 # that is being tested, or a functionality that is not being tested, and
87 # break with an error unless some option to suppress this is present
88
89 if options.dump:
90 print "Functionalities:"
91 for name in functionalities:
92 print " " + name
93 for implementation in functionalities[name].implementations:
94 print " +-" + str(implementation)
95 print "Tests:"
96 for test in tests:
97 print " " + str(test)
98
99 # run tests
100 results = []
101 for test in tests:
102 results += test.run(options=options)
103
104 # report on results
105 for result in results:
106 result.report()
107 num_results = len(results)
108 num_failures = len([x for x in results if not x.is_successful()])
109 print '--------------------------------'
110 print 'Total test runs: %d, failures: %d' % (num_results, num_failures)
111 print '--------------------------------'
112
113 if num_failures == 0:
114 return 0
115 else:
116 return 1
36 "tests)")
37
38 (options, args) = parser.parse_args(args[1:])
39
40 # for compatibility with previous versions of falderal
41 if args and args[0] == 'test':
42 args = args[1:]
43
44 if options.test:
45 import doctest
46 import falderal.objects
47 (failure_count, test_count) = \
48 doctest.testmod(falderal.objects,
49 optionflags=doctest.NORMALIZE_WHITESPACE)
50 if failure_count > 0:
51 return 1
52 else:
53 return 0
54
55 try:
56 return test_documents(options, args)
57 except FalderalSyntaxError as e:
58 # if options.show_full_exception: do that, else
59 sys.stderr.write('%s: %s\n' % (e.__class__.__name__, str(e)))
60 return 1
61
62
63 def test_documents(options, args):
64 # load Falderal documents
65 documents = []
66 for filename in args:
67 documents.append(Document.load(filename))
68
69 # collect functionalities
70 # XXX if any implementations are given in the command line,
71 # we can put them in here.
72 functionalities = {}
73
74 # create Falderal Tests
75 tests = []
76 for document in documents:
77 tests += document.parse_blocks_to_tests(functionalities)
78
79 if options.clear_functionalities:
80 for name in options.clear_functionalities.split(':'):
81 n = name.strip()
82 if n in functionalities:
83 functionalities[n].implementations = []
84
85 # XXX lint: check for no tests, or no implementations of a functionality
86 # that is being tested, or a functionality that is not being tested, and
87 # break with an error unless some option to suppress this is present
88
89 if options.dump:
90 print "Functionalities:"
91 for name in functionalities:
92 print " " + name
93 for implementation in functionalities[name].implementations:
94 print " +-" + str(implementation)
95 print "Tests:"
96 for test in tests:
97 print " " + str(test)
98
99 # run tests
100 results = []
101 for test in tests:
102 results += test.run(options=options)
103
104 # report on results
105 for result in results:
106 result.report()
107 num_results = len(results)
108 num_failures = len([x for x in results if not x.is_successful()])
109 print '--------------------------------'
110 print 'Total test runs: %d, failures: %d' % (num_results, num_failures)
111 print '--------------------------------'
112
113 if num_failures == 0:
114 return 0
115 else:
116 return 1
0 import sys
1
2 input = sys.stdin
3 output = sys.stdout
4
5 if len(sys.argv) > 1 and sys.argv[1] == '-f':
6 input = open(sys.argv[2], 'r')
7 sys.argv = sys.argv[2:]
8
9 if len(sys.argv) > 1 and sys.argv[1] == '-o':
10 output = open(sys.argv[2], 'w')
11 sys.argv = sys.argv[2:]
12
13 output.write(input.read())
0 import sys
1
2 input = sys.stdin
3 output = sys.stdout
4
5 if len(sys.argv) > 1 and sys.argv[1] == '-f':
6 input = open(sys.argv[2], 'r')
7 sys.argv = sys.argv[2:]
8
9 if len(sys.argv) > 1 and sys.argv[1] == '-o':
10 output = open(sys.argv[2], 'w')
11 sys.argv = sys.argv[2:]
12
13 output.write(input.read())
0 import sys
1
2 for line in sys.stdin:
3 sys.stdout.write(line.strip() + '\r\n')
0 import sys
1
2 for line in sys.stdin:
3 sys.stdout.write(line.strip() + '\r\n')
0 import sys
1
2 if sys.argv[1] == '-n':
3 sys.stdout.write(sys.argv[2])
4 else:
5 sys.stdout.write(sys.argv[1] + '\n')
0 import sys
1
2 if sys.argv[1] == '-n':
3 sys.stdout.write(sys.argv[2])
4 else:
5 sys.stdout.write(sys.argv[1] + '\n')
0 import sys
1
2 sys.stdout.write(sys.argv[1] + '\n')
3 sys.stdout.flush()
4 sys.stderr.write(sys.argv[2] + '\n')
5 sys.exit(int(sys.argv[3]))
0 import sys
1
2 sys.stdout.write(sys.argv[1] + '\n')
3 sys.stdout.flush()
4 sys.stderr.write(sys.argv[2] + '\n')
5 sys.exit(int(sys.argv[3]))
0 Falderal Test: CRLF
1 -------------------
2
3 These Falderal tests aim to show that the implementation
4 can compare the result with the expected text, regardless
5 of end-of-line convention (LF or CRLF).
6
7 -> Functionality "CRLF" is implemented by
8 -> shell command "python crlf.py"
9
10 -> Tests for functionality "CRLF"
11
12 Cat CRLFs.
13
14 | my kitty, 'tis of thee
15 | feline felicity
16 | something something
17 = my kitty, 'tis of thee
18 = feline felicity
19 = something something
20
21 No CRLFs in test report (Intentional fail.)
22
23 | one
24 | two
25 = three
0 Falderal Test: CRLF
1 -------------------
2
3 These Falderal tests aim to show that the implementation
4 can compare the result with the expected text, regardless
5 of end-of-line convention (LF or CRLF).
6
7 -> Functionality "CRLF" is implemented by
8 -> shell command "python crlf.py"
9
10 -> Tests for functionality "CRLF"
11
12 Cat CRLFs.
13
14 | my kitty, 'tis of thee
15 | feline felicity
16 | something something
17 = my kitty, 'tis of thee
18 = feline felicity
19 = something something
20
21 No CRLFs in test report (Intentional fail.)
22
23 | one
24 | two
25 = three
0 Falderal Test: substring-error
1 ------------------------------
2
3 When the `-b` option is passed to `falderal`, it considers
4 an error-expecting test successful if the error text which
5 was produced simply contains (rather than totally equals)
6 the expected error text.
7
8 -> Functionality "Fail" is implemented by shell command
9 -> "python fail.py foo '%(test-text)' 1"
10
11 -> Tests for functionality "Fail"
12
13 | this is the error message
14 ? this is the error message
15
16 | (file tmpgZ5W7e3, line 123): this is the error message
17 ? this is the error message
18
19 | (file tmpgZ5W7e3, line 123): an error occurred on this line.
20 | It is a very pretty error, consisting of several nested
21 | sub-errors, of which I know very little. (ref #371282)
22 ? an error occurred on this line.
23 ? It is a very pretty error, consisting of several nested
24 ? sub-errors, of which I know very little.
0 Falderal Test: substring-error
1 ------------------------------
2
3 When the `-b` option is passed to `falderal`, it considers
4 an error-expecting test successful if the error text which
5 was produced simply contains (rather than totally equals)
6 the expected error text.
7
8 -> Functionality "Fail" is implemented by shell command
9 -> "python fail.py foo '%(test-text)' 1"
10
11 -> Tests for functionality "Fail"
12
13 | this is the error message
14 ? this is the error message
15
16 | (file tmpgZ5W7e3, line 123): this is the error message
17 ? this is the error message
18
19 | (file tmpgZ5W7e3, line 123): an error occurred on this line.
20 | It is a very pretty error, consisting of several nested
21 | sub-errors, of which I know very little. (ref #371282)
22 ? an error occurred on this line.
23 ? It is a very pretty error, consisting of several nested
24 ? sub-errors, of which I know very little.
0 -> encoding: UTF-8
1
2 Falderal Test: UTF-8
3 --------------------
4
5 This is an example Falderal document which contains Unicode
6 characters, encoded in UTF-8 (this is the assumed encoding
7 of all Falderal documents which go beyond mere ASCII.)
8
9 -> Functionality "Cat" is implemented by
10 -> shell command "python cat.py"
11
12 -> Tests for functionality "Cat"
13
14 Cat cats.
15
16 | n ← ★
17 = n ← ★
18
19 Cat dogs, too. (Intentional fail.)
20
21 | n ← ★
22 = m ← ★
23
24 -> Functionality "Cat (file)" is implemented by
25 -> shell command "python cat.py -f %(test-file) -o %(output-file)"
26
27 -> Tests for functionality "Cat (file)"
28
29 Cat (file) cats.
30
31 | n ← ★
32 = n ← ★
33
34 Cat (file) dogs, too. (Intentional fail.)
35
36 | n ← ★
37 = m ← ★
0 -> encoding: UTF-8
1
2 Falderal Test: UTF-8
3 --------------------
4
5 This is an example Falderal document which contains Unicode
6 characters, encoded in UTF-8 (this is the assumed encoding
7 of all Falderal documents which go beyond mere ASCII.)
8
9 -> Functionality "Cat" is implemented by
10 -> shell command "python cat.py"
11
12 -> Tests for functionality "Cat"
13
14 Cat cats.
15
16 | n ← ★
17 = n ← ★
18
19 Cat dogs, too. (Intentional fail.)
20
21 | n ← ★
22 = m ← ★
23
24 -> Functionality "Cat (file)" is implemented by
25 -> shell command "python cat.py -f %(test-file) -o %(output-file)"
26
27 -> Tests for functionality "Cat (file)"
28
29 Cat (file) cats.
30
31 | n ← ★
32 = n ← ★
33
34 Cat (file) dogs, too. (Intentional fail.)
35
36 | n ← ★
37 = m ← ★
0 Falderal Test 1
1 ---------------
2
3 This is an example Falderal document which contains some
4 intentionally failing tests. It is intended to test that
5 your Falderal implementation is, itself, not producing
6 incorrect output.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
17
18 | purr
19 | prrr
20 | prreow
21 = purr
22 = prrr
23 = prreow
24
25 Cat dogs, too. (Intentional fail.)
26
27 | meow
28 = woof
29
30 | purr
31 | prrr
32 | prreow
33 = woof
34 = woof
35 = awoooo
0 Falderal Test 1
1 ---------------
2
3 This is an example Falderal document which contains some
4 intentionally failing tests. It is intended to test that
5 your Falderal implementation is, itself, not producing
6 incorrect output.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
17
18 | purr
19 | prrr
20 | prreow
21 = purr
22 = prrr
23 = prreow
24
25 Cat dogs, too. (Intentional fail.)
26
27 | meow
28 = woof
29
30 | purr
31 | prrr
32 | prreow
33 = woof
34 = woof
35 = awoooo
0 Falderal Test 2
1 ---------------
2
3 Since no functionality is specified for these tests,
4 `py-falderal` should exit with an exception.
5
6 -> Functionality "Cat" is implemented by
7 -> shell command "python cat.py"
8
9 Cat cats.
10
11 | meow
12 = meow
13
14 | purr
15 | prrr
16 | prreow
17 = purr
18 = prrr
19 = prreow
0 Falderal Test 2
1 ---------------
2
3 Since no functionality is specified for these tests,
4 `py-falderal` should exit with an exception.
5
6 -> Functionality "Cat" is implemented by
7 -> shell command "python cat.py"
8
9 Cat cats.
10
11 | meow
12 = meow
13
14 | purr
15 | prrr
16 | prreow
17 = purr
18 = prrr
19 = prreow
0 Falderal Test 3
1 ---------------
2
3 A Falderal document which is ill-formed.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Tests for functionality "Cat"
9
10 Cat cats.
11
12 | meow
13
14 Oops, I didn't include an expectation.
0 Falderal Test 3
1 ---------------
2
3 A Falderal document which is ill-formed.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Tests for functionality "Cat"
9
10 Cat cats.
11
12 | meow
13
14 Oops, I didn't include an expectation.
0 Falderal Test 4
1 ---------------
2
3 Another Falderal document which is ill-formed.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Tests for functionality "Cat"
9
10 Cat cats.
11
12 = meow
13
14 Oops, I didn't include a test body.
0 Falderal Test 4
1 ---------------
2
3 Another Falderal document which is ill-formed.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Tests for functionality "Cat"
9
10 Cat cats.
11
12 = meow
13
14 Oops, I didn't include a test body.
0 Falderal Test 5
1 ---------------
2
3 Tests for variable substitution, and missing EOL at end
4 of output.
5
6 Note the use of single quotes around the `%(test-text)` variable;
7 without these, shell chaos is likely to result.
8
9 -> Functionality "Echo" is implemented by
10 -> shell command "python echo.py '%(test-text)'"
11
12 -> Tests for functionality "Echo"
13
14 | hello
15 = hello
16
17 | hi
18 | hi
19 = hi
20 = hi
21
22 -> Functionality "Echo, no newline" is implemented by
23 -> shell command "python echo.py -n '%(test-text)'"
24
25 -> Tests for functionality "Echo, no newline"
26
27 | hello
28 = hello
29
30 | hi
31 | hi
32 = hi
33 = hi
34
35 Note that single quotes needn't be supplied around `%(test-file)`
36 or `%(output-file)`.
37
38 -> Functionality "Cat, from file" is implemented by
39 -> shell command "python cat.py -f %(test-file)"
40
41 -> Tests for functionality "Cat, from file"
42
43 | hello
44 = hello
45
46 | hi
47 | hi
48 = hi
49 = hi
50
51 -> Functionality "Cat, to file" is implemented by
52 -> shell command "python cat.py -o %(output-file)"
53
54 -> Tests for functionality "Cat, to file"
55
56 | hello
57 = hello
58
59 | hi
60 | hi
61 = hi
62 = hi
63
64 -> Functionality "Cat, to and from file" is implemented by
65 -> shell command "python cat.py -f %(test-file) -o %(output-file)"
66
67 -> Tests for functionality "Cat, to and from file"
68
69 | hello
70 = hello
71
72 | hi
73 | hi
74 = hi
75 = hi
0 Falderal Test 5
1 ---------------
2
3 Tests for variable substitution, and missing EOL at end
4 of output.
5
6 Note the use of single quotes around the `%(test-text)` variable;
7 without these, shell chaos is likely to result.
8
9 -> Functionality "Echo" is implemented by
10 -> shell command "python echo.py '%(test-text)'"
11
12 -> Tests for functionality "Echo"
13
14 | hello
15 = hello
16
17 | hi
18 | hi
19 = hi
20 = hi
21
22 -> Functionality "Echo, no newline" is implemented by
23 -> shell command "python echo.py -n '%(test-text)'"
24
25 -> Tests for functionality "Echo, no newline"
26
27 | hello
28 = hello
29
30 | hi
31 | hi
32 = hi
33 = hi
34
35 Note that single quotes needn't be supplied around `%(test-file)`
36 or `%(output-file)`.
37
38 -> Functionality "Cat, from file" is implemented by
39 -> shell command "python cat.py -f %(test-file)"
40
41 -> Tests for functionality "Cat, from file"
42
43 | hello
44 = hello
45
46 | hi
47 | hi
48 = hi
49 = hi
50
51 -> Functionality "Cat, to file" is implemented by
52 -> shell command "python cat.py -o %(output-file)"
53
54 -> Tests for functionality "Cat, to file"
55
56 | hello
57 = hello
58
59 | hi
60 | hi
61 = hi
62 = hi
63
64 -> Functionality "Cat, to and from file" is implemented by
65 -> shell command "python cat.py -f %(test-file) -o %(output-file)"
66
67 -> Tests for functionality "Cat, to and from file"
68
69 | hello
70 = hello
71
72 | hi
73 | hi
74 = hi
75 = hi
0 Falderal Test 6a
1 ----------------
2
3 This is a two-file test (the other file is 6b) which shows
4 that even if you says "Tests for functionality x" in this
5 file, that tests-for meaning does not "leak" into the next
6 file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
0 Falderal Test 6a
1 ----------------
2
3 This is a two-file test (the other file is 6b) which shows
4 that even if you says "Tests for functionality x" in this
5 file, that tests-for meaning does not "leak" into the next
6 file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
0 Falderal Test 6b
1 ----------------
2
3 This is a two-file test (the other file is 6a) which shows
4 that even if you says "Tests for functionality x" in the other
5 file, that tests-for meaning does not "leak" into this file.
6
7 Cat cats.
8
9 | purr
10 | prrr
11 | prreow
12 = purr
13 = prrr
14 = prreow
0 Falderal Test 6b
1 ----------------
2
3 This is a two-file test (the other file is 6a) which shows
4 that even if you says "Tests for functionality x" in the other
5 file, that tests-for meaning does not "leak" into this file.
6
7 Cat cats.
8
9 | purr
10 | prrr
11 | prreow
12 = purr
13 = prrr
14 = prreow
0 Falderal Test 7a
1 ----------------
2
3 This is a two-file test (the other file is 7b) which shows
4 that all implementations of a functionality apply to all
5 tests for that functionality, even when they're not in
6 the same file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
0 Falderal Test 7a
1 ----------------
2
3 This is a two-file test (the other file is 7b) which shows
4 that all implementations of a functionality apply to all
5 tests for that functionality, even when they're not in
6 the same file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py"
10
11 -> Tests for functionality "Cat"
12
13 Cat cats.
14
15 | meow
16 = meow
0 Falderal Test 7b
1 ----------------
2
3 This is a two-file test (the other file is 7a) which shows
4 that all implementations of a functionality apply to all
5 tests for that functionality, even when they're not in
6 the same file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py -f %(test-file)"
10
11 -> Tests for functionality "Cat"
12
13 Cat totally, like, cats.
14
15 | purr
16 | prrr
17 | prreow
18 = purr
19 = prrr
20 = prreow
0 Falderal Test 7b
1 ----------------
2
3 This is a two-file test (the other file is 7a) which shows
4 that all implementations of a functionality apply to all
5 tests for that functionality, even when they're not in
6 the same file.
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py -f %(test-file)"
10
11 -> Tests for functionality "Cat"
12
13 Cat totally, like, cats.
14
15 | purr
16 | prrr
17 | prreow
18 = purr
19 = prrr
20 = prreow
0 Falderal Test 8a
1 ----------------
2
3 This is really just a more lopsided version of test 7.
4
5 -> Tests for functionality "Cat"
6
7 Cat totally, like, cats.
8
9 | purr
10 | prrr
11 | prreow
12 = purr
13 = prrr
14 = prreow
0 Falderal Test 8a
1 ----------------
2
3 This is really just a more lopsided version of test 7.
4
5 -> Tests for functionality "Cat"
6
7 Cat totally, like, cats.
8
9 | purr
10 | prrr
11 | prreow
12 = purr
13 = prrr
14 = prreow
0 Falderal Test 8b
1 ----------------
2
3 This is really just a more lopsided version of test 7.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py -f %(test-file)"
10
11 -> Functionality "Cat" is implemented by
12 -> shell command "python cat.py -o %(output-file)"
13
14 -> Functionality "Cat" is implemented by
15 -> shell command "python echo.py '%(test-text)'"
0 Falderal Test 8b
1 ----------------
2
3 This is really just a more lopsided version of test 7.
4
5 -> Functionality "Cat" is implemented by
6 -> shell command "python cat.py"
7
8 -> Functionality "Cat" is implemented by
9 -> shell command "python cat.py -f %(test-file)"
10
11 -> Functionality "Cat" is implemented by
12 -> shell command "python cat.py -o %(output-file)"
13
14 -> Functionality "Cat" is implemented by
15 -> shell command "python echo.py '%(test-text)'"
0 Falderal Test 9
1 ---------------
2
3 When we have a test that expects a successful result, the
4 expected text is matched against standard output.
5
6 -> Functionality "Succeed" is implemented by shell command
7 -> "python fail.py '%(test-text)' bar 0"
8
9 -> Tests for functionality "Succeed"
10
11 | foo
12 = foo
13
14 If you wish to match the expected result against both standard
15 output and standard error, it's up to you to redirect them.
16
17 -> Functionality "Succeed/All" is implemented by shell command
18 -> "python fail.py '%(test-text)' bar 0 2>&1"
19
20 -> Tests for functionality "Succeed/All"
21
22 | foo
23 = foo
24 = bar
25
26 When we have a test that expects an error result, the
27 expected text is matched against standard error.
28
29 -> Functionality "Fail" is implemented by shell command
30 -> "python fail.py foo '%(test-text)' 1"
31
32 -> Tests for functionality "Fail"
33
34 | bar
35 ? bar
36
37 If you wish to match the expected error against both standard
38 output and standard error, it's up to you to redirect them.
39
40 -> Functionality "Fail/All" is implemented by shell command
41 -> "python fail.py foo '%(test-text)' 1 1>&2"
42
43 -> Tests for functionality "Fail/All"
44
45 | bar
46 ? foo
47 ? bar
0 Falderal Test 9
1 ---------------
2
3 When we have a test that expects a successful result, the
4 expected text is matched against standard output.
5
6 -> Functionality "Succeed" is implemented by shell command
7 -> "python fail.py '%(test-text)' bar 0"
8
9 -> Tests for functionality "Succeed"
10
11 | foo
12 = foo
13
14 If you wish to match the expected result against both standard
15 output and standard error, it's up to you to redirect them.
16
17 -> Functionality "Succeed/All" is implemented by shell command
18 -> "python fail.py '%(test-text)' bar 0 2>&1"
19
20 -> Tests for functionality "Succeed/All"
21
22 | foo
23 = foo
24 = bar
25
26 When we have a test that expects an error result, the
27 expected text is matched against standard error.
28
29 -> Functionality "Fail" is implemented by shell command
30 -> "python fail.py foo '%(test-text)' 1"
31
32 -> Tests for functionality "Fail"
33
34 | bar
35 ? bar
36
37 If you wish to match the expected error against both standard
38 output and standard error, it's up to you to redirect them.
39
40 -> Functionality "Fail/All" is implemented by shell command
41 -> "python fail.py foo '%(test-text)' 1 1>&2"
42
43 -> Tests for functionality "Fail/All"
44
45 | bar
46 ? foo
47 ? bar