packages feed

abacate (empty) → 0.0.0.0

raw patch · 12 files changed

+1107/−0 lines, 12 filesdep +HUnitdep +abacatedep +basesetup-changed

Dependencies added: HUnit, abacate, base, parsec, text

Files

+ LICENSE view
@@ -0,0 +1,202 @@++                                 Apache License+                           Version 2.0, January 2004+                        http://www.apache.org/licenses/++   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION++   1. Definitions.++      "License" shall mean the terms and conditions for use, reproduction,+      and distribution as defined by Sections 1 through 9 of this document.++      "Licensor" shall mean the copyright owner or entity authorized by+      the copyright owner that is granting the License.++      "Legal Entity" shall mean the union of the acting entity and all+      other entities that control, are controlled by, or are under common+      control with that entity. For the purposes of this definition,+      "control" means (i) the power, direct or indirect, to cause the+      direction or management of such entity, whether by contract or+      otherwise, or (ii) ownership of fifty percent (50%) or more of the+      outstanding shares, or (iii) beneficial ownership of such entity.++      "You" (or "Your") shall mean an individual or Legal Entity+      exercising permissions granted by this License.++      "Source" form shall mean the preferred form for making modifications,+      including but not limited to software source code, documentation+      source, and configuration files.++      "Object" form shall mean any form resulting from mechanical+      transformation or translation of a Source form, including but+      not limited to compiled object code, generated documentation,+      and conversions to other media types.++      "Work" shall mean the work of authorship, whether in Source or+      Object form, made available under the License, as indicated by a+      copyright notice that is included in or attached to the work+      (an example is provided in the Appendix below).++      "Derivative Works" shall mean any work, whether in Source or Object+      form, that is based on (or derived from) the Work and for which the+      editorial revisions, annotations, elaborations, or other modifications+      represent, as a whole, an original work of authorship. For the purposes+      of this License, Derivative Works shall not include works that remain+      separable from, or merely link (or bind by name) to the interfaces of,+      the Work and Derivative Works thereof.++      "Contribution" shall mean any work of authorship, including+      the original version of the Work and any modifications or additions+      to that Work or Derivative Works thereof, that is intentionally+      submitted to Licensor for inclusion in the Work by the copyright owner+      or by an individual or Legal Entity authorized to submit on behalf of+      the copyright owner. For the purposes of this definition, "submitted"+      means any form of electronic, verbal, or written communication sent+      to the Licensor or its representatives, including but not limited to+      communication on electronic mailing lists, source code control systems,+      and issue tracking systems that are managed by, or on behalf of, the+      Licensor for the purpose of discussing and improving the Work, but+      excluding communication that is conspicuously marked or otherwise+      designated in writing by the copyright owner as "Not a Contribution."++      "Contributor" shall mean Licensor and any individual or Legal Entity+      on behalf of whom a Contribution has been received by Licensor and+      subsequently incorporated within the Work.++   2. Grant of Copyright License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      copyright license to reproduce, prepare Derivative Works of,+      publicly display, publicly perform, sublicense, and distribute the+      Work and such Derivative Works in Source or Object form.++   3. Grant of Patent License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      (except as stated in this section) patent license to make, have made,+      use, offer to sell, sell, import, and otherwise transfer the Work,+      where such license applies only to those patent claims licensable+      by such Contributor that are necessarily infringed by their+      Contribution(s) alone or by combination of their Contribution(s)+      with the Work to which such Contribution(s) was submitted. If You+      institute patent litigation against any entity (including a+      cross-claim or counterclaim in a lawsuit) alleging that the Work+      or a Contribution incorporated within the Work constitutes direct+      or contributory patent infringement, then any patent licenses+      granted to You under this License for that Work shall terminate+      as of the date such litigation is filed.++   4. Redistribution. You may reproduce and distribute copies of the+      Work or Derivative Works thereof in any medium, with or without+      modifications, and in Source or Object form, provided that You+      meet the following conditions:++      (a) You must give any other recipients of the Work or+          Derivative Works a copy of this License; and++      (b) You must cause any modified files to carry prominent notices+          stating that You changed the files; and++      (c) You must retain, in the Source form of any Derivative Works+          that You distribute, all copyright, patent, trademark, and+          attribution notices from the Source form of the Work,+          excluding those notices that do not pertain to any part of+          the Derivative Works; and++      (d) If the Work includes a "NOTICE" text file as part of its+          distribution, then any Derivative Works that You distribute must+          include a readable copy of the attribution notices contained+          within such NOTICE file, excluding those notices that do not+          pertain to any part of the Derivative Works, in at least one+          of the following places: within a NOTICE text file distributed+          as part of the Derivative Works; within the Source form or+          documentation, if provided along with the Derivative Works; or,+          within a display generated by the Derivative Works, if and+          wherever such third-party notices normally appear. The contents+          of the NOTICE file are for informational purposes only and+          do not modify the License. You may add Your own attribution+          notices within Derivative Works that You distribute, alongside+          or as an addendum to the NOTICE text from the Work, provided+          that such additional attribution notices cannot be construed+          as modifying the License.++      You may add Your own copyright statement to Your modifications and+      may provide additional or different license terms and conditions+      for use, reproduction, or distribution of Your modifications, or+      for any such Derivative Works as a whole, provided Your use,+      reproduction, and distribution of the Work otherwise complies with+      the conditions stated in this License.++   5. Submission of Contributions. Unless You explicitly state otherwise,+      any Contribution intentionally submitted for inclusion in the Work+      by You to the Licensor shall be under the terms and conditions of+      this License, without any additional terms or conditions.+      Notwithstanding the above, nothing herein shall supersede or modify+      the terms of any separate license agreement you may have executed+      with Licensor regarding such Contributions.++   6. Trademarks. This License does not grant permission to use the trade+      names, trademarks, service marks, or product names of the Licensor,+      except as required for reasonable and customary use in describing the+      origin of the Work and reproducing the content of the NOTICE file.++   7. Disclaimer of Warranty. Unless required by applicable law or+      agreed to in writing, Licensor provides the Work (and each+      Contributor provides its Contributions) on an "AS IS" BASIS,+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or+      implied, including, without limitation, any warranties or conditions+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A+      PARTICULAR PURPOSE. You are solely responsible for determining the+      appropriateness of using or redistributing the Work and assume any+      risks associated with Your exercise of permissions under this License.++   8. Limitation of Liability. In no event and under no legal theory,+      whether in tort (including negligence), contract, or otherwise,+      unless required by applicable law (such as deliberate and grossly+      negligent acts) or agreed to in writing, shall any Contributor be+      liable to You for damages, including any direct, indirect, special,+      incidental, or consequential damages of any character arising as a+      result of this License or out of the use or inability to use the+      Work (including but not limited to damages for loss of goodwill,+      work stoppage, computer failure or malfunction, or any and all+      other commercial damages or losses), even if such Contributor+      has been advised of the possibility of such damages.++   9. Accepting Warranty or Additional Liability. While redistributing+      the Work or Derivative Works thereof, You may choose to offer,+      and charge a fee for, acceptance of support, warranty, indemnity,+      or other liability obligations and/or rights consistent with this+      License. However, in accepting such obligations, You may act only+      on Your own behalf and on Your sole responsibility, not on behalf+      of any other Contributor, and only if You agree to indemnify,+      defend, and hold each Contributor harmless for any liability+      incurred by, or claims asserted against, such Contributor by reason+      of your accepting any such warranty or additional liability.++   END OF TERMS AND CONDITIONS++   APPENDIX: How to apply the Apache License to your work.++      To apply the Apache License to your work, attach the following+      boilerplate notice, with the fields enclosed by brackets "[]"+      replaced with your own identifying information. (Don't include+      the brackets!)  The text should be enclosed in the appropriate+      comment syntax for the file format. We also recommend that a+      file or class name and description of purpose be included on the+      same "printed page" as the copyright notice for easier+      identification within third-party archives.++   Copyright [yyyy] [name of copyright owner]++   Licensed under the Apache License, Version 2.0 (the "License");+   you may not use this file except in compliance with the License.+   You may obtain a copy of the License at++       http://www.apache.org/licenses/LICENSE-2.0++   Unless required by applicable law or agreed to in writing, software+   distributed under the License is distributed on an "AS IS" BASIS,+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+   See the License for the specific language governing permissions and+   limitations under the License.
+ Language/Abacate.hs view
@@ -0,0 +1,45 @@+-- |+-- Module      :  Language.Abacate+-- Copyright   :  (c) Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com> 2012+-- License     :  Apache 2.0 (see the file LICENSE)+--+-- Maintainer  :  Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+-- Stability   :  unstable+-- Portability :  portable+--+-- Gherkin is the language used by the Cucumber system for Behaviour Driven+-- Development.  This package contains a parser to it, based on its BNF with+-- minor changes.  For more information on Cucumber, check <http://cukes.info>.+--+-- According to+-- <https://github.com/cucumber/gherkin/wiki/BNF/cf8696092b0e6841ba0c3cf4e2f0d3c964b9c144>.+module+  Language.Abacate+  (module Language.Abacate.Types, parseFile,  parseAbacate)+  where++-- base+import Prelude hiding (readFile)+import Control.Applicative++-- text+import Data.Text+import Data.Text.IO++-- parsec+import Text.Parsec++-- abacate+import Language.Abacate.Types+import Language.Abacate.BNF++-- | Parses a file with 'Abacate' code.+parseFile :: FilePath -> IO (Either ParseError Abacate)+parseFile path = parseAbacateWithSource path <$> readFile path++-- | Parses a string with 'Abacate' code.+parseAbacate :: Text -> Either ParseError Abacate+parseAbacate = parseAbacateWithSource "parseAbacate"++parseAbacateWithSource :: FilePath -> Text -> Either ParseError Abacate+parseAbacateWithSource = parse abacate
+ Language/Abacate/BNF.hs view
@@ -0,0 +1,251 @@+-- |+-- Module      :  Language.Abacate.BNF+-- Copyright   :  (c) Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com> 2012+-- License     :  Apache 2.0 (see the file LICENSE)+--+-- Maintainer  :  Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+-- Stability   :  unstable+-- Portability :  portable+module Language.Abacate.BNF (abacate) where++-- base+import Prelude hiding (unlines)+import Control.Applicative hiding (many, (<|>), optional)+import Control.Monad++-- text+import Data.Text hiding (map)++-- parsec+import Text.Parsec+import Text.Parsec.Text++-- abacate+import Language.Abacate.Types++abacate :: Parser Abacate+abacate = feature++feature :: Parser Feature+feature+  = do+    white+    pBegComment <- comment+    pTags <- tags+    pHeader <- header+    pBackground <- option Nothing $ Just <$> try background+    pFeatureElements <- featureElements+    pEndComment <- comment+    return+      $ Feature+        pBegComment+        pTags+        pHeader+        pBackground+        pFeatureElements+        pEndComment++header :: Parser Header+header+  = strip+    <$> pack+    <$> manyTill anyChar+      (lookAhead+         $ choice+         $ map try [void scenarioOutline, void scenario, void background])++featureElements :: Parser FeatureElements+featureElements+  = many $ (FES <$> try scenario) <|> (FESO <$> try scenarioOutline)++scenario :: Parser Scenario+scenario+  = do+    pComment <- comment+    pTags <- tags+    scenarioKeyword+    (name, pSteps) <- scenarioCommon+    return $ Scenario pTags $ BasicScenario pComment name pSteps++scenarioOutline :: Parser ScenarioOutline+scenarioOutline+  = do+    pComment <- comment+    pTags <- tags+    scenarioOutlineKeyword+    (name, pSteps) <- scenarioCommon+    pExamplesSection <- examplesSection+    white+    return+      $ ScenarioOutline pExamplesSection+      $ Scenario pTags+      $ BasicScenario pComment name pSteps++background :: Parser Background+background+  = do+    pComment <- comment+    backgroundKeyword+    (name, pSteps) <- scenarioCommon+    return $ BasicScenario pComment name pSteps++tags :: Parser Tags+tags+  = white+    >> many+      (do+        pTag <- tag+        white1+        return pTag)++tag :: Parser Tag+tag = char '@' >> pack <$> many1 (noneOf "@\r\n\t ")++comment :: Parser Comment+comment+  = unlines+    <$> many+      (do+        pComment <- commentLine+        white+        return pComment)++commentLine :: Parser Comment+commentLine = gSpaces >> char '#' >> lineToEol++steps :: Parser Steps+steps = many $ try step++step :: Parser Step+step+ = do+   pComment <- comment+   gSpaces+   keyword <- stepKeyword+   keywordSpace+   body <- lineToEol+   void (many1 eol) <|> eof+   pMultilineArg <- option Nothing $ Just <$> try multilineArg+   white+   return $ Step pComment keyword body pMultilineArg++examplesSection :: Parser ExamplesSection+examplesSection = many $ try examples++examples :: Parser Examples+examples+  = do+    pComment <- comment+    gSpaces+    examplesKeyword+    gSpaces+    name <- linesToKeyword+    eol+    pTable <- table+    white+    return $ Examples pComment name pTable++multilineArg :: Parser MultilineArg+multilineArg = MAT <$> try table <|> MAPS <$> try pyString++pyString :: Parser PyString+pyString+  = openPyString >> strip <$> pack <$> manyTill anyChar (try closePyString)++openPyString :: Parser ()+openPyString = gSpaces >> string "\"\"\"" >> gSpaces >> eol++closePyString :: Parser ()+closePyString = eol >> gSpaces >> string "\"\"\"" >> white++cell :: Parser Cell+cell+  = do+    pCell <- many1 (noneOf "\r\n|")+    void (char '|')+    return $ strip $ pack pCell++row :: Parser Row+row+  = do+    white+    void $ char '|'+    pRow <- many1 $ try cell+    eol+    return pRow++table :: Parser Table+table = many1 $ try row++stepKeyword :: Parser StepKeyword+stepKeyword+  = read+    <$> choice+      (map (try . string . show) ([minBound .. maxBound] :: [StepKeyword]))++examplesKeyword :: Parser ()+examplesKeyword = void $ string "Examples:"++scenarioOutlineKeyword :: Parser ()+scenarioOutlineKeyword = void $ string "Scenario Outline:"++scenarioKeyword :: Parser ()+scenarioKeyword = void $ string "Scenario:"++backgroundKeyword :: Parser ()+backgroundKeyword = void $ string "Background:"++linesToKeyword :: Parser Text+linesToKeyword+  = strip+    <$> pack+    <$> manyTill+      anyChar+      (lookAhead $ try $ eol >> gSpaces >> reservedWordsAndSymbols)++reservedWordsAndSymbols :: Parser ()+reservedWordsAndSymbols+  = choice+    $ map+      try+      [stepKeyword >> keywordSpace,+        scenarioKeyword,+        scenarioOutlineKeyword,+        void table,+        void tag,+        void commentLine]++gSpace :: Parser ()+gSpace = void $ oneOf " \t"++eol :: Parser ()+eol = optional (char '\r') >> void (char '\n')++white :: Parser ()+white = skipMany oneWhite++lineToEol :: Parser Text+lineToEol = pack <$> many (noneOf "\r\n")++keywordSpace :: Parser ()+keywordSpace = void $ char ' '++-- Not defined in BNF++oneWhite :: Parser ()+oneWhite = gSpace <|> eol++white1 :: Parser ()+white1 = skipMany1 oneWhite++gSpaces :: Parser ()+gSpaces = skipMany gSpace++scenarioCommon :: Parser (Text, Steps)+scenarioCommon+  = do+    gSpaces+    name <- linesToKeyword+    white+    pSteps <- steps+    return (name, pSteps)
+ Language/Abacate/Types.hs view
@@ -0,0 +1,107 @@+-- |+-- Module      :  Language.Abacate.Types+-- Copyright   :  (c) Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com> 2012+-- License     :  Apache 2.0 (see the file LICENSE)+--+-- Maintainer  :  Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+-- Stability   :  unstable+-- Portability :  portable+module Language.Abacate.Types where++-- text+import Data.Text++-- | An Abacate file contains exactly one feature.+type Abacate = Feature++-- | For a more detailed description of features, check+-- <https://github.com/cucumber/cucumber/wiki/Feature-Introduction>.+data Feature+  = Feature+      {fBegComment :: Comment,+        fTags :: Tags,+        fHeader :: Header,+        fBackground :: Maybe Background,+        fFeatureElements :: FeatureElements,+        fEndComment :: Comment}+    deriving (Eq, Show)++-- | The 'Header' contains the title and description of the 'Feature'.  It is+-- usually on the format:+--+-- @+-- Feature: TITLE+--   DESCRIPTION LINE 1+--   DESCRIPTION LINE 2+-- @+type Header = Text++type FeatureElements = [FeatureElement]++-- | A 'FeatureElement' is simply a 'Scenario' or a 'ScenarioOutline'.+data FeatureElement+  = FES Scenario | FESO ScenarioOutline+    deriving (Eq, Show)++-- | The 'Scenario' contains a list of 'Steps'.+data Scenario+  = Scenario {scTags :: Tags, scBasicScenario :: BasicScenario}+    deriving (Eq, Show)++-- | The 'Steps' of the 'ScenarioOutline' can contain placeholders which are+-- substituted by the fields of the 'ExamplesSection'.  For more information on+-- the 'ScenarioOutline' check+-- <https://github.com/cucumber/cucumber/wiki/Scenario-outlines>.+data ScenarioOutline+  = ScenarioOutline+      {soExamplesSection :: ExamplesSection, soScenario :: Scenario}+    deriving (Eq, Show)++-- | The 'Background' is basically a 'Scenario' without 'Tags'.  It's used to+-- create a context for the other 'Scenario's to run, and a 'Feature' can only+-- have one 'Background'.  For more information on the 'Background' check+-- <https://github.com/cucumber/cucumber/wiki/Background>.+type Background = BasicScenario++-- | This is the basic type for 'Scenario', 'ScenarioOutline' and 'Background'.+data BasicScenario+  = BasicScenario {bsComment :: Comment, bsName :: Text, bsSteps :: Steps}+    deriving (Eq, Show)++type Tags = [Tag]++-- | A 'Tag' is a textual element started with \@.+type Tag = Text++type Comment = Text+type Steps = [Step]++-- | For more information on 'Steps' check+-- <https://github.com/cucumber/cucumber/wiki/Given-When-Then>.+data Step+  = Step+      {stComment :: Comment,+        stStepKeyword :: StepKeyword,+        stBody :: Text,+        stMultilineArg :: Maybe MultilineArg}+    deriving (Eq, Show)++type ExamplesSection = [Examples]++-- | The 'Examples' are used to fill the value of placeholders on+-- 'ScenarioOutline's.+data Examples+  = Examples {eComment :: Comment, eName :: Text, eTable :: Table}+    deriving (Eq, Show)++-- | 'Steps' can have multi-line arguments.  For more information check+-- <https://github.com/cucumber/cucumber/wiki/Multiline-Step-Arguments>.+data MultilineArg = MAT Table | MAPS PyString deriving (Eq, Show)++type PyString = Text+type Table = [Row]+type Row = [Cell]+type Cell = Text++data StepKeyword+  = Given | When | Then | And | But deriving (Eq, Bounded, Enum, Show, Read)
+ Setup.hs view
@@ -0,0 +1,4 @@+import Distribution.Simple++main :: IO ()+main = defaultMain
+ abacate.cabal view
@@ -0,0 +1,49 @@+name: abacate+version: 0.0.0.0+cabal-version: >= 1.8+build-type: Simple+license: OtherLicense+license-file: LICENSE+copyright: 2012 Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+author: Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+maintainer: Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+stability: experimental+homepage: http://github.com/marcotmarcot/abacate+bug-reports: http://github.com/marcotmarcot/abacate/issues+synopsis: Parser for a language similar to Cucumber's Gherkin+description:+  Gherkin is the language used by the Cucumber system for Behaviour Driven+  Development.  This package contains a parser to it, based on its BNF with+  minor changes.  For more information on Cucumber, check <http://cukes.info>.+category: Language+tested-with: GHC ==7.4.2+extra-source-files:+  tests/data/environment.feature,+  tests/data/givenWhenGivenWhen.feature,+  tests/data/calculator.feature,+  tests/data/wrongComment.feature,+  tests/data/complete.feature++library+  exposed-modules:+    Language.Abacate,+    Language.Abacate.Types+  other-modules:+    Language.Abacate.BNF+  build-depends:+    base >= 4 && < 5,+    text >= 0.11 && < 0.12,+    parsec >= 3.1 && < 3.2+  ghc-options: -Wall++Test-Suite abacate-test+  type: exitcode-stdio-1.0+  main-is: abacate.hs+  hs-source-dirs: tests+  build-depends:+    base >= 4 && < 5,+    text,+    text >= 0.11 && < 0.12,+    abacate >= 0.0 && <= 0.1,+    HUnit >= 1.2 && <= 1.3+  ghc-options: -Wall
+ tests/abacate.hs view
@@ -0,0 +1,345 @@+-- Copyright 2012 Marco Túlio Pimenta Gontijo <marcotmarcot@gmail.com>+--+-- Licensed under the Apache License, Version 2.0 (the "License");+-- you may not use this file except in compliance with the License.+-- You may obtain a copy of the License at+--+--     http://www.apache.org/licenses/LICENSE-2.0+--+-- Unless required by applicable law or agreed to in writing, software+-- distributed under the License is distributed on an "AS IS" BASIS,+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+-- See the License for the specific language governing permissions and+-- limitations under the License.++-- base+import System.Exit++-- text+import Data.Text hiding (map)++-- abacate+import Language.Abacate++-- HUnit+import Test.HUnit++main :: IO ()+main+  = do+    counts_ <- runTestTT tests+    if errors counts_ + failures counts_ > 0+      then exitFailure+      else exitSuccess++tests :: Test+tests+  = TestList+    [TestCase+        $ parseFile "tests/data/environment.feature"+          >>= (Feature+                empty+                []+                (pack+                  $ "Feature: Environment\n"+                    ++ "  In order to use the environment variables\n"+                    ++ "  Programmers must be able to write and read "+                    ++ "environment variables")+                Nothing+                [FES+                  $ Scenario []+                  $ BasicScenario+                    empty+                    (pack "Write then read")+                    [Step+                        empty+                        When+                        (pack "I set the variable as 3 into the environment")+                        Nothing,+                      Step+                        (pack " Comment! =)\n")+                        Then+                        (pack "the variable should have 3 on its content")+                        Nothing]]+                empty+              @=?)+            . fromRight,+      TestCase+        $ parseFile "tests/data/givenWhenGivenWhen.feature"+          >>= (Feature+                empty+                []+                (pack+                  $ "Feature: Given When Given When\n"+                    ++ "  In order to write more complicated test cases\n"+                    ++ "  Programmers must be able to write more than one "+                    ++ "Given When sequence")+                Nothing+                [FES+                  $ Scenario []+                  $ BasicScenario+                    empty+                    (pack "Given When Given When")+                    [Step+                        empty+                        Given+                        (pack "that A is logged in")+                        Nothing,+                      Step+                        empty+                        When+                        (pack "he goes to his user page")+                        Nothing,+                      Step+                        empty+                        Then+                        (pack "he sees his user name")+                        Nothing,+                      Step+                        empty+                        When+                        (pack "he clicks \"Premium\"")+                        Nothing,+                      Step+                        empty+                        Then+                        (pack "he sees that he is a premium user")+                        Nothing]]+                empty+              @=?)+            . fromRight,+      TestCase+        $ parseFile "tests/data/calculator.feature"+          >>= (Feature+                (pack " Of course it needs calc!\n")+                [pack "needs_calc", pack "nice_feature"]+                (pack+                  $ "Feature: Division\n"+                    ++ "  In order to avoid silly mistakes\n"+                    ++ "  Cashiers must be able to calculate a fraction")+                Nothing+                [FES+                  $ Scenario []+                  $ BasicScenario+                    empty+                    (pack "Regular numbers")+                    [Step+                        empty+                        Given+                        (pack "that I have entered 3 into the calculator")+                        Nothing,+                      Step+                        (pack " Comment! =)\n")+                        And+                        (pack "that I have entered 2 into the calculator")+                        Nothing,+                      Step+                        empty+                        When+                        (pack "I press divide")+                        Nothing,+                      Step+                        empty+                        Then+                        (pack "the result should be 1.5 on the screen")+                        Nothing]]+                empty+              @=?)+            . fromRight,+      TestCase+        $ parseFile "tests/data/wrongComment.feature"+          >>= (Feature+                empty+                []+                (pack+                  $ "Feature: Wrong Comment\n"+                    ++ "  In order to use # inside steps\n"+                    ++ "  Programmers must be able to write steps without "+                    ++ "being interpreted as comments")+                Nothing+                [FES+                  $ Scenario []+                  $ BasicScenario+                    empty+                    (pack "User logged in sees his page")+                    [Step+                        empty+                        Given+                        (pack "that #A is logged in")+                        Nothing,+                      Step+                        empty+                        When+                        (pack "he goes to his user page")+                        Nothing,+                      Step+                        empty+                        Then+                        (pack "he sees his user name")+                        Nothing]]+                empty+              @=?)+            . fromRight,+      TestCase+        $ parseFile "tests/data/complete.feature"+          >>= (Feature+                empty+                []+                (pack+                  $ "Feature: Complete\n"+                    ++ "  In order to use all the syntax\n"+                    ++ "  Users must be able to write all the syntax elements")+                (Just+                  $ BasicScenario+                    (pack " Background\n")+                    empty+                    [Step+                        empty+                        Given+                        (pack "a global administrator named \"Greg\"")+                        Nothing,+                      Step+                        empty+                        And+                        (pack "a blog named \"Greg's anti-tax rants\"")+                        Nothing,+                      Step+                        empty+                        And+                        (pack "a customer named \"Dr. Bill\"")+                        Nothing,+                      Step+                        empty+                        And+                        (pack+                          $ "a blog named \"Expensive Therapy\" owned by "+                            ++ "\"Dr. Bill\"")+                        Nothing])+                [FESO+                    $ ScenarioOutline+                      [Examples empty empty+                        $ map+                          (map pack)+                          [["start", "eat", "left"],+                            ["12", "5", "7"],+                            ["20", "5", "15"]]]+                    $ Scenario []+                    $ BasicScenario+                      (pack " Scenario outline\n")+                      (pack "eating")+                      [Step+                          empty+                          Given+                          (pack "there are <start> cucumbers")+                          Nothing,+                        Step+                          empty+                          When+                          (pack "I eat <eat> cucumbers")+                          Nothing,+                        Step+                          empty+                          Then+                          (pack "I should have <left> cucumbers")+                          Nothing],+                  FES+                    $ Scenario [pack "wip"]+                    $ BasicScenario+                      (pack " Scenario\n")+                      (pack+                        $ "Delete the blue lorry, which is magic and always "+                          ++ "raises an error")+                      [Step+                          empty+                          Given+                          (pack "the following lorries:")+                          (Just+                            $ MAT+                            $ map+                              (map pack)+                              [["name", "colour"],+                                ["name 1", "green"],+                                ["name 2", "yellow"],+                                ["name 3", "pink"],+                                ["name 4", "blue"]]),+                        Step+                          empty+                          But+                          (pack "I delete the 4th lorry")+                          Nothing,+                        Step+                          empty+                          Given+                          (pack+                             "a blog post named \"Random\" with Markdown body")+                          (Just+                            $ MAPS+                            $ pack+                            $ "Some Title, Eh?\n"+                              ++ "    ==============\n"+                              ++ "    Here is the first paragraph of my blog "+                              ++ "post. Lorem ipsum dolor sit amet,\n"+                              ++ "    consectetur adipiscing elit.")],+                  FESO+                    $ ScenarioOutline+                      [Examples empty empty+                        $ map+                          (map pack)+                          [["Role", "details"],+                            ["Manager",+                              "now able to manage your employee accounts"],+                            ["Admin",+                              "able to manage any user account on the system"]]]+                    $ Scenario []+                    $ BasicScenario+                      empty+                      (pack "Email confirmation")+                      [Step+                          empty+                          Given+                          (pack+                            $ "I have a user account with my name "+                              ++ "\"Jojo Binks\"")+                          Nothing,+                        Step+                          empty+                          When+                          (pack "an Admin grants me <Role> rights")+                          Nothing,+                        Step+                          empty+                          Then+                          (pack "I should receive an email with the body:")+                          (Just+                            $ MAPS+                            $ pack+                            $ "Dear Jojo Binks,\n"+                              ++ "      You have been granted <Role> rights.  "+                              ++ "You are <details>. Please be responsible.\n"+                              ++ "      -The Admins")],+                  FESO+                    $ ScenarioOutline+                      [Examples empty empty+                        $ map+                          (map pack)+                          [["x", "y"], ["2", "14"], ["10", "70"]]]+                    $ Scenario []+                    $ BasicScenario+                      empty+                      (pack "Multiplying with 7")+                      [Step+                          empty+                          Given+                          (pack "I have the numbers")+                          (Just+                            $ MAT+                            $ map+                              (map pack)+                              [["q1", "q2", "product"], ["<x>", "7", "<y>"]])]]+                (pack " Final comment\n")+              @=?)+            . fromRight]++fromRight :: Show a => Either a b -> b+fromRight (Right b) = b+fromRight (Left a) = error $ "fromRight (Left " ++ show a ++ ")"
+ tests/data/calculator.feature view
@@ -0,0 +1,13 @@+# Of course it needs calc!+@needs_calc+@nice_feature+Feature: Division+  In order to avoid silly mistakes+  Cashiers must be able to calculate a fraction++  Scenario: Regular numbers+    Given that I have entered 3 into the calculator+    # Comment! =)+    And that I have entered 2 into the calculator+    When I press divide+    Then the result should be 1.5 on the screen
+ tests/data/complete.feature view
@@ -0,0 +1,65 @@+Feature: Complete+  In order to use all the syntax+  Users must be able to write all the syntax elements++  # Background+  Background:+    Given a global administrator named "Greg"+    And a blog named "Greg's anti-tax rants"+    And a customer named "Dr. Bill"+    And a blog named "Expensive Therapy" owned by "Dr. Bill"++  # Scenario outline+  Scenario Outline: eating+    Given there are <start> cucumbers+    When I eat <eat> cucumbers+    Then I should have <left> cucumbers++    Examples:+      | start | eat | left |+      |  12   |  5  |  7   |+      |  20   |  5  |  15  |++  # Scenario+  @wip+  Scenario: Delete the blue lorry, which is magic and always raises an error+  Given the following lorries:+    | name | colour |+    | name 1 | green |+    | name 2 | yellow |+    | name 3 | pink |+    | name 4 | blue |+  But I delete the 4th lorry+  Given a blog post named "Random" with Markdown body+    """+    Some Title, Eh?+    ==============+    Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,+    consectetur adipiscing elit.+    """++  Scenario Outline: Email confirmation+    Given I have a user account with my name "Jojo Binks"+    When an Admin grants me <Role> rights+    Then I should receive an email with the body:+      """+      Dear Jojo Binks,+      You have been granted <Role> rights.  You are <details>. Please be responsible.+      -The Admins+      """+    Examples:+      |  Role     | details                                         |+      |  Manager  | now able to manage your employee accounts       |+      |  Admin    | able to manage any user account on the system   |++  Scenario Outline: Multiplying with 7+    Given I have the numbers+      | q1   | q2 | product |+      | <x>  |  7 | <y>     |+    Examples:+      |  x |  y |+      |  2 | 14 |+      | 10 | 70 |+++# Final comment
+ tests/data/environment.feature view
@@ -0,0 +1,8 @@+Feature: Environment+  In order to use the environment variables+  Programmers must be able to write and read environment variables++  Scenario: Write then read+    When I set the variable as 3 into the environment+    # Comment! =)+    Then the variable should have 3 on its content
+ tests/data/givenWhenGivenWhen.feature view
@@ -0,0 +1,10 @@+Feature: Given When Given When+  In order to write more complicated test cases+  Programmers must be able to write more than one Given When sequence++  Scenario: Given When Given When+    Given that A is logged in+    When he goes to his user page+    Then he sees his user name+    When he clicks "Premium"+    Then he sees that he is a premium user
+ tests/data/wrongComment.feature view
@@ -0,0 +1,8 @@+Feature: Wrong Comment+  In order to use # inside steps+  Programmers must be able to write steps without being interpreted as comments++  Scenario: User logged in sees his page+    Given that #A is logged in+    When he goes to his user page+    Then he sees his user name