Skip to content

Commit 943a27c

Browse files
committed
Add current formatter with license
1 parent 53c4b6e commit 943a27c

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Qualified Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Test.Hspec.Formatters.Codewars
2+
3+
Hspec formatter for [Qualified](https://www.qualified.io/) and [Codewars](https://www.codewars.com).
4+
5+
## Usage
6+
7+
Specify `codewars` formatter:
8+
9+
```haskell
10+
-- test/Main.hs
11+
module Main where
12+
13+
import Test.Hspec.Runner
14+
import Test.Hspec.Formatters.Codewars (codewars)
15+
16+
import qualified Spec
17+
18+
main :: IO ()
19+
main = hspecWith defaultConfig {configFormatter = Just codewars} Spec.spec
20+
```
21+
22+
```haskell
23+
-- test/Spec.hs
24+
{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}
25+
```
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
module Test.Hspec.Formatters.Codewars
2+
(
3+
codewars
4+
) where
5+
6+
import System.IO (Handle)
7+
import Control.Exception (SomeException)
8+
import Control.Monad (unless, join, forM_)
9+
import Text.Printf (printf)
10+
import Data.List (intercalate)
11+
12+
import Data.List.Split (splitOn)
13+
14+
import Test.Hspec.Core.Spec (Progress)
15+
import Test.Hspec.Runner (Path)
16+
import Test.Hspec.Formatters (Formatter (..), FormatM,
17+
FailureRecord (..), FailureReason (..),
18+
getRealTime,
19+
formatException,
20+
write, writeLine)
21+
22+
codewars :: Formatter
23+
codewars = Formatter
24+
{ headerFormatter = headerFormatter'
25+
, footerFormatter = footerFormatter'
26+
, exampleGroupStarted = exampleGroupStarted'
27+
, exampleGroupDone = exampleGroupDone'
28+
, examplePending = examplePending'
29+
, exampleSucceeded = exampleSucceeded'
30+
, exampleFailed = exampleFailed'
31+
, exampleProgress = exampleProgress'
32+
, failedFormatter = failedFormatter'
33+
}
34+
35+
-- https://hackage.haskell.org/package/hspec-core-2.4.4/docs/Test-Hspec-Core-Formatters.html
36+
37+
headerFormatter' :: FormatM ()
38+
headerFormatter' = return ()
39+
40+
footerFormatter' :: FormatM ()
41+
footerFormatter' = return ()
42+
43+
-- evaluated before each test group
44+
exampleGroupStarted' :: [String] -> String -> FormatM ()
45+
exampleGroupStarted' = \nesting name -> do
46+
writeLine ""
47+
writeLine' $ join $ ["<DESCRIBE::>", name]
48+
49+
-- evaluated after each test group
50+
exampleGroupDone' :: FormatM ()
51+
exampleGroupDone' = writeLine "\n<COMPLETEDIN::>"
52+
53+
-- evaluated after each successful example
54+
exampleSucceeded' :: Path -> FormatM ()
55+
exampleSucceeded' = \(_, requirement) -> do
56+
writeLine ""
57+
writeLine' $ join ["<IT::>", requirement]
58+
writeLine "\n<PASSED::>Test Passed"
59+
writeLine "\n<COMPLETEDIN::>"
60+
61+
-- evaluated after each failed example
62+
exampleFailed' :: Path -> Either SomeException FailureReason -> FormatM ()
63+
exampleFailed' = \(_, requirement) reason -> do
64+
writeLine ""
65+
writeLine' $ join ["<IT::>", requirement]
66+
writeLine ""
67+
formatFailure reason
68+
writeLine "\n<COMPLETEDIN::>"
69+
70+
-- evaluated after each pending example
71+
examplePending' :: Path -> Maybe String -> FormatM ()
72+
examplePending' = \_ _ -> return ()
73+
74+
-- Failed test summary
75+
-- evaluated after a test run
76+
failedFormatter' :: FormatM ()
77+
failedFormatter' = return ()
78+
79+
-- used to notify the progress of the currently evaluated example
80+
-- Only called when interactive/color mode.
81+
exampleProgress' :: Handle -> Path -> Progress -> IO ()
82+
exampleProgress' = \_ _ _ -> return ()
83+
84+
writeLine' :: String -> FormatM ()
85+
writeLine' s = writeLine $ intercalate "<:LF:>" $ splitOn "\n" s
86+
87+
formatFailure :: Either SomeException FailureReason -> FormatM ()
88+
formatFailure (Left e) = do
89+
writeLine ""
90+
writeLine' $ ((printf "<ERROR::>%s") . formatException) e
91+
formatFailure (Right NoReason) = do
92+
writeLine ""
93+
writeLine "<FAILED::>Test Failed"
94+
formatFailure (Right (Reason err)) = do
95+
writeLine ""
96+
writeLine' $ (printf "<FAILED::>%s" err)
97+
formatFailure (Right (ExpectedButGot preface expected actual)) = do
98+
writeLine ""
99+
mapM_ writeLine preface
100+
writeLine' $ "<FAILED::>Test Failed\nexpected: " ++ expected ++ "\n but got: " ++ actual

0 commit comments

Comments
 (0)