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 +202/−0
- Language/Abacate.hs +45/−0
- Language/Abacate/BNF.hs +251/−0
- Language/Abacate/Types.hs +107/−0
- Setup.hs +4/−0
- abacate.cabal +49/−0
- tests/abacate.hs +345/−0
- tests/data/calculator.feature +13/−0
- tests/data/complete.feature +65/−0
- tests/data/environment.feature +8/−0
- tests/data/givenWhenGivenWhen.feature +10/−0
- tests/data/wrongComment.feature +8/−0
+ 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