1- # FileCheck
1+ # Oughta
22
33## Overview
44
5- FileCheck is a Haskell library inspired by the [ command-line tool of the same
6- name] [ llvm ] . It is used to test programs that output text. The testing paradigm
7- essentially combines golden testing with ` grep ` .
5+ Oughta is a Haskell library for testing programs that output text. The testing
6+ paradigm essentially combines golden testing with ` grep ` .
87
9- [ llvm ] : https://llvm.org/docs/CommandGuide/FileCheck.html
8+ Oughta draws inspiration from LLVM's [ FileCheck ] and Rust's [ compiletest ] .
109
11- More precisely, FileCheck allows you to build parsers for the output of your
12- program. The inputs to FileCheck are the output of the program under test and a
13- separate, generally quite short program written in the FileCheck parsing DSL.
10+ [ FileCheck ] : https://llvm.org/docs/CommandGuide/FileCheck.html
11+ [ compiletest] : https://rustc-dev-guide.rust-lang.org/tests/compiletest.html
12+
13+ More precisely, Oughta provides a DSL to build * recognizers* (i.e., parsers that
14+ simply accept or reject an string). The inputs to Oughta are a string (usually,
15+ the output of the program under test) and a separate, generally quite short
16+ program written in the Oughta DSL.
1417
1518The simplest DSL procedure is ` check ` , which checks that the output contains a
1619string. For example, the following test would pass:
@@ -28,10 +31,10 @@ check "world"
2831## Example
2932
3033Let's say that you have decided to write the first ever Haskell implementation
31- of a POSIX shell, ` hsh ` . Here's how to test it with FileCheck .
34+ of a POSIX shell, ` hsh ` . Here's how to test it with Oughta .
3235
3336If the input to the program under test is a file format that supports comments,
34- it is often convenient to embed FileCheck DSL programs in the input itself. For
37+ it is often convenient to embed Oughta DSL programs in the input itself. For
3538example, here's a test for ` echo ` :
3639
3740``` sh
@@ -48,7 +51,7 @@ module Main (main) where
4851
4952import Control.Monad (filterM , forM )
5053import Data.ByteString qualified as BS
51- import FileCheck qualified as FC
54+ import Oughta qualified
5255import System.Directory qualified as Dir
5356import Test.Tasty.HUnit qualified as TTH
5457import Test.Tasty qualified as TT
@@ -63,9 +66,9 @@ test sh = do
6366 content <- BS. readFile sh
6467 (stdout, _stderr) <- runScript content
6568 let comment = " # " -- shell script start-of-line comment
66- let prog = FC . fromLineComments sh comment content
67- result <- FC . check prog (FC . Output stdout)
68- TTH. assertBool (sh ++ " contained some assertions" ) (not (FC . resultNull result))
69+ let prog = Oughta . fromLineComments sh comment content
70+ result <- Oughta . check prog (Oughta . Output stdout)
71+ TTH. assertBool (sh ++ " contained some assertions" ) (not (Oughta . resultNull result))
6972
7073main :: IO ()
7174main = do
@@ -88,16 +91,16 @@ test :: FilePath -> IO ()
8891test sh = do
8992 -- snip --
9093 let stdoutComment = " # STDOUT: "
91- let prog = FC . fromLineComments sh stdoutComment content
92- stdoutResult <- FC . check prog (FC . Output stdout)
94+ let prog = Oughta . fromLineComments sh stdoutComment content
95+ stdoutResult <- Oughta . check prog (Oughta . Output stdout)
9396
9497 let stderrComment = " # STDERR: "
95- let prog' = FC . fromLineComments sh stderrComment content
96- stderrResult <- FC . check prog' (FC . Output stderr)
98+ let prog' = Oughta . fromLineComments sh stderrComment content
99+ stderrResult <- Oughta . check prog' (Oughta . Output stderr)
97100
98101 TTH. assertBool
99102 (sh ++ " contained some assertions" )
100- (not (FC . resultNull stdoutResult && FC . resultNull stderrResult))
103+ (not (Oughta . resultNull stdoutResult && Oughta . resultNull stderrResult))
101104```
102105
103106Test cases would then look like so:
@@ -111,8 +114,8 @@ echo 'Hello, stderr!' 1>&2
111114
112115## Cookbook
113116
114- This section demonstrates how to accomplish common tasks with the FileCheck DSL.
115- The FileCheck DSL is just [ Lua] [ lua ] , extended with an API for easy parsing.
117+ This section demonstrates how to accomplish common tasks with the Oughta DSL.
118+ The DSL is just [ Lua] [ lua ] , extended with an API for easy parsing.
116119
117120[ Lua] : https://www.lua.org/
118121
@@ -122,7 +125,7 @@ as simple as possible, and some repetition should be accepted for the sake of
122125readability. It is often appropriate to just make a sequence of API calls with
123126literal strings as arguments.
124127
125- FileCheck is used to test itself. See the test suite for additional examples.
128+ Oughta is used to test itself. See the test suite for additional examples.
126129
127130### Long matches
128131
@@ -156,7 +159,7 @@ check("I'm sorry, " .. name)
156159```
157160or with a ` for ` -loop:
158161```
159- Step 1: Learn about FileCheck
162+ Step 1: Learn about Oughta
160163Step 2: Use it to test your project
161164Step 3: Enjoy!
162165```
@@ -190,7 +193,7 @@ The Lua API is *stateful*. It keeps track of a global variable `text` that
190193is initialized to the output of the program under test. Various API functions
191194cause the API to seek forward in ` text ` . This is analogous to working file-like
192195objects in languages like C or Python. ` text ` should not be updated from Lua
193- code; such updates will be ignored by FileCheck .
196+ code; such updates will be ignored by Oughta .
194197
195198### High-level API
196199
@@ -219,24 +222,24 @@ Other utilities:
219222
220223## Motivation
221224
222- The overall FileCheck paradigm is a form of [ data driven testing] . See that blog
225+ The overall Oughta paradigm is a form of [ data driven testing] . See that blog
223226post for considerable motivation and discussion.
224227
225228[ data driven testing ] : https://matklad.github.io/2021/05/31/how-to-test.html#Data-Driven-Testing
226229
227- In comparison to golden testing, FileCheck -style tests are * coarser* . They only
230+ In comparison to golden testing, Oughta -style tests are * coarser* . They only
228231check particular parts of the program's output. This can cause less churn in
229232the test suite when the program output changes in ways that are not relevant
230233to the properties being tested. The fineness of golden testing can force
231234devlopers to adopt [ complex] [ workarounds] , these can sometimes be obviated by
232- FileCheck -style testing.
235+ Oughta -style testing.
233236
234237[ complex] : https://rustc-dev-guide.rust-lang.org/tests/ui.html#normalization
235238[ workarounds ] : https://github.com/GaloisInc/crucible/blob/dc0895f4435dc19a8cceee3272c9a508221bce51/crux-llvm/test/Test.hs#L226-L311
236239
237- However, it is more complex. For example, it requires learning the FileCheck
238- DSL. It can also cause unexpected successes, e.g., if the program output
239- contains the pattern being checked, but not in the proper place.
240+ However, it is more complex. For example, it requires learning the Oughta DSL.
241+ It can also cause unexpected successes, e.g., if the program output contains the
242+ pattern being checked, but not in the proper place.
240243
241244Why build a Haskell library when LLVM already provides their FileCheck tool?
242245There are a variety of reasons:
0 commit comments