# inspection-testing: GHC plugin to do inspection testing

[ compiler-plugin, library, mit, testing ] [ Propose Tags ]

Some carefully crafted libraries make promises to their users beyond functionality and performance.

Examples are: Fusion libraries promise intermediate data structures to be eliminated. Generic programming libraries promise that the generic implementation is identical to the hand-written one. Some libraries may promise allocation-free or branch-free code.

Conventionally, the modus operandi in all these cases is that the library author manually inspects the (intermediate or final) code produced by the compiler. This is not only tedious, but makes it very likely that some change, either in the library itself or the surrounding eco-system, breaks the library’s promised without anyone noticing.

This package provides a disciplined way of specifying such properties, and have them checked by the compiler. This way, this checking can be part of the ususal development cycle and regressions caught early.

See the documentation in Test.Inspection or the project webpage for more examples and more information.

Versions 0.1, 0.1.1, 0.1.1.1, 0.1.1.2, 0.1.2, 0.2, 0.2.0.1, 0.3 ChangeLog.md base (>=4.9 && <4.13), containers, ghc (>=8.0.2 && <8.6), mtl, template-haskell, transformers [details] MIT 2017 Joachim Breitner Joachim Breitner mail@joachim-breitner.de Testing, Compiler Plugin https://github.com/nomeata/inspection-testing head: git clone git://github.com/nomeata/inspection-testing.git by JoachimBreitner at Sat Jul 7 13:27:55 UTC 2018 LTSHaskell:0.2.0.1, NixOS:0.3, Stackage:0.3 1222 total (38 in the last 30 days) 2.5 (votes: 3) [estimated by rule of succession] λ λ λ Docs available Last success reported on 2018-07-07 Hackage Matrix CI

[Index]

## Flags

NameDescriptionDefaultType
more-tests

Run tests that pull in specific versions of other packages

DisabledAutomatic

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

#### Maintainer's Corner

For package maintainers and hackage trustees

[back to package description]

This GHC plugin allows you to embed assertions about the intermediate code into your Haskell code, and have them checked by GHC. This is called inspection testing (as it automates what you do when you manually inspect the intermediate code).

## Synopsis

See the Test.Inspection module for the documentation, but there really isn't much more to it than:

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -O -fplugin Test.Inspection.Plugin #-}
module Simple where

import Test.Inspection
import Data.Maybe

lhs, rhs :: (a -> b) -> Maybe a -> Bool
lhs f x = isNothing (fmap f x)
rhs f Nothing = True
rhs f (Just _) = False

inspect $'lhs === 'rhs  If you compile this, you will reassurringly read: $ ghc Simple.hs
[1 of 1] Compiling Simple           ( Simple.hs, Simple.o )
examples/Simple.hs:14:1: lhs === rhs passed.
inspection testing successful
expected successes: 1


See the examples/ directory for more examples of working proofs.

If an assertion fails, for example

bad1, bad2 :: Int

inspect $'bad1 === 'bad2  then the compiler will tell you so, and abort the compilation: $ ghc Simple.hs -dsuppress-idinfo
[5 of 5] Compiling Simple           ( examples/Simple.hs, examples/Simple.o )
examples/Simple.hs:14:1: lhs === rhs passed.
LHS:

RHS:

examples/Simple.hs: error:
inspection testing unsuccessful
expected successes: 1
unexpected failures: 1


## What can I check for?

Currently, inspection-testing supports

• checking two definitions to be equal (useful in the context of generic programming)
• checking the absence of a certain type (useful in the context of list or stream fusion)
• checking the absence of allocation (generally useful)

In general, the checks need to be placed in the same module as the checked-definition.

Possible further applications includes

• checking that all recursive functions are (efficiently called) join-points
• asserting strictness properties (e.g. in Data.Map.Strict)
• peforming some of these checks only within recursive loops

Let me know if you need any of these, or have further ideas.

## Help, I am drowning in Core!

inspection-testing prints the Core more or less like GHC would, and the same flags can be used to control the level of detail. In particular, you might want to pass to GHC a selection of the following flags:

-dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications
-dsuppress-module-prefixes -dsuppress-type-signatures -dsuppress-uniques


## Can I comment or help?

Sure! We can use the GitHub issue tracker for discussions, and obviously contributions are welcome.