require 0.4.8 → 0.4.9
raw patch · 7 files changed
+259/−143 lines, 7 filesdep +ansi-terminaldep +dlistdep +mtldep −inliteratedep ~megaparsec
Dependencies added: ansi-terminal, dlist, mtl
Dependencies removed: inliterate
Dependency ranges changed: megaparsec
Files
- library/Require.hs +5/−3
- library/Require/Error.hs +41/−0
- library/Require/File.hs +7/−4
- library/Require/Transform.hs +90/−63
- package.yaml +5/−7
- require.cabal +30/−19
- test-suite/Main.hs +81/−47
library/Require.hs view
@@ -4,6 +4,7 @@ import Options.Generic import Relude import System.Directory+import qualified Require.Error as Error import qualified Require.File as File import Require.Transform import Require.Types@@ -33,12 +34,13 @@ CommandArguments inputFile _ outputFile <- getRecord "Require Haskell preprocessor" :: IO CommandArguments requiresFile <- findRequires case requiresFile of- Nothing -> die "There is no Requires file in the system"+ Nothing -> Error.die (File.Name inputFile) Error.MissingRequiresFile Just fn -> run (AutorequireEnabled fn) (File.Name inputFile) (File.Name outputFile) run :: AutorequireMode File.Name -> File.Name -> File.Name -> IO () run autoMode inputFile outputFile = do input <- File.read inputFile autoInput <- traverse File.read autoMode- let transformed = transform autoInput input- File.write outputFile transformed+ case transform autoInput input of+ Left err -> Error.die inputFile err+ Right ls -> File.writeLines outputFile ls
+ library/Require/Error.hs view
@@ -0,0 +1,41 @@+module Require.Error where++import Control.Exception+import Relude+import qualified Require.File as File+import System.Console.ANSI+import System.IO+++data Error+ = MissingRequiresFile+ | MissingOptionalRequiresFile+ | AutorequireImpossible+ deriving (Eq, Show)+++describe :: Error -> [String]+describe MissingRequiresFile =+ [ "`autorequirepp` couldn't find a `Requires` file in the system." ]+describe MissingOptionalRequiresFile =+ [ "Discovered an `autorequire` directive but no `Requires` file was found." ]+describe AutorequireImpossible =+ [ "Unable to determine where to insert the autorequire contents."+ , "Use the `autorequire` directive to specify a location yourself."+ ]+++die :: File.Name -> Error -> IO a+die (File.Name fn) e = do+ let outputHeaderColored = do+ hSetSGR stderr [SetConsoleIntensity BoldIntensity]+ hPutStr stderr (toString fn ++ ": ")+ hSetSGR stderr [SetColor Foreground Vivid Red]+ hPutStr stderr "error:\n"++ -- Don't mess up the terminal if there is an exception half-way through.+ outputHeaderColored `finally` hSetSGR stderr []++ let indent s = replicate 4 ' ' ++ s+ traverse_ (hPutStrLn stderr . indent) (describe e)+ exitFailure
library/Require/File.hs view
@@ -9,6 +9,7 @@ module Require.File where import Relude+import qualified Data.Text.IO as TIO -- | Wraps the name of a file as given by the user. Usually this corresponds to -- the file's path.@@ -30,7 +31,7 @@ -- | Returns the 'LineTag' referencing the first line in a given 'FileInput'. -- -- Note that the tag's line number is 1-based, which fits well with how GHC--- understands @{-# LINE ... #-}@ pragmas.+-- understands @{-\# LINE ... #-}@ pragmas. initialLineTag :: Input -> LineTag initialLineTag inp = LineTag (inputName inp) (LineNumber 1) @@ -42,9 +43,11 @@ read :: Name -> IO Input read f = Input f <$> readFileText (nameToPath f) --- | @write name content@ writes @content@ to the file identified by @name@.-write :: Name -> Text -> IO ()-write = writeFileText . nameToPath+-- | @write name lines@ writes all every line in @lines@ to the file identified+-- by @name@ and appends a newline.+writeLines :: Name -> [Text] -> IO ()+writeLines name theLines = withFile (nameToPath name) WriteMode $ \h ->+ traverse_ (TIO.hPutStrLn h) theLines -- | Splits the input into lines and annotates each with a 'LineTag'. inputLines :: Input -> [(LineTag, Text)]
library/Require/Transform.hs view
@@ -1,79 +1,110 @@ {-# LANGUAGE FlexibleContexts #-} module Require.Transform where +import Control.Monad.Except+import Control.Monad.Writer.Strict+import Data.DList (DList) import qualified Data.Text as Text import Relude+import Require.Error (Error(..)) import qualified Require.File as File import qualified Require.Parser as Parser import Require.Types -type LineTagPrepend = File.LineTag -> Text -> Text+-- | The monad stack used during transformation:+--+-- * @'StateT' 'TransformState'@ to keep track of whether to render the next+-- line tag, the module's name etc.+-- * @'WriterT' ('DList' 'Text')@ to collect the output lines. Instead of+-- haskell's built-in list type we use 'DList' because of it's /O(1)/ append+-- operation.+-- * @'Either' 'Error'@ to return errors.+type TransformM =+ StateT TransformState+ (WriterT (DList Text)+ (Either Error)) + data TransformState = TransformState- { tstLineTagPrepend :: !LineTagPrepend+ { tstLineTagOutput :: File.LineTag -> TransformM () , tstHostModule :: !(Maybe ModuleName) , tstAutorequire :: !(AutorequireMode File.Input) } -renderLineTag :: File.LineTag -> Text-renderLineTag (File.LineTag (File.Name fn) (File.LineNumber ln)) =- "{-# LINE " <> show ln <> " \"" <> fn <> "\" #-}\n"-+-- | Outputs a single line.+output :: Text -> TransformM ()+output = tell . pure -prependLineTag :: LineTagPrepend-prependLineTag = (<>) . renderLineTag+-- | Outputs the pragma representation of the given line tag.+renderLineTag :: File.LineTag -> TransformM ()+renderLineTag (File.LineTag (File.Name fn) (File.LineNumber ln)) =+ output $ "{-# LINE " <> show ln <> " \"" <> fn <> "\" #-}" -ignoreLineTag :: LineTagPrepend-ignoreLineTag = const id+-- | Ignore the given line tag, specifically don't render it.+ignoreLineTag :: File.LineTag -> TransformM ()+ignoreLineTag = const (pure ()) -transform :: AutorequireMode File.Input -> File.Input -> Text+transform :: AutorequireMode File.Input -> File.Input -> Either Error [Text] transform autorequire input =- -- TODO:- -- * if the mapM overhead is too much maybe use a streaming library- -- * there is no need to concatenate the whole output in memory, a lazy text would be fine- -- * maybe we should check if tstAutorequired is set after processing File.inputLines input- & mapM (process (pure Nothing))- & flip evalState initialState- & mconcat+ & traverse_ (process False)+ & flip execStateT initialState+ & chainedTo checkDidAutorequire+ & execWriterT+ & fmap toList where initialState = TransformState- { tstLineTagPrepend = prependLineTag+ { tstLineTagOutput = renderLineTag , tstHostModule = Nothing , tstAutorequire = autorequire } -process- :: State TransformState (Maybe ModuleName)- -> (File.LineTag, Text)- -> State TransformState Text-process getHostModule (tag, line) = do- let useTagPrep text = do- prep <- gets tstLineTagPrepend- modify $ \s -> s { tstLineTagPrepend = ignoreLineTag }- pure $ prep tag text+ unableToAutorequire resultState+ -- If the autorequire mode was `enabled` initially and still is+ -- afterwards, we were unable to find where to place the Require contents.+ | AutorequireEnabled _ <- autorequire+ , AutorequireEnabled _ <- tstAutorequire resultState+ = True+ -- In any other case this either wasn't goal or it was done successfully.+ | otherwise+ = False + checkDidAutorequire resultState+ | unableToAutorequire resultState = throwError AutorequireImpossible+ | otherwise = pure ()+++process :: Bool -> (File.LineTag, Text) -> TransformM ()+process filterImports (tag, line) = do+ -- Uses 'tstLineTagOutput' to render the current lines tag if necessary.+ let useTagPrep = do+ tst <- get+ tstLineTagOutput tst tag+ put (tst { tstLineTagOutput = ignoreLineTag })+ let lineWithAutorequire isDirective autoCondition = do autoMode <- gets tstAutorequire case autoMode of AutorequireEnabled autoContent | isDirective || autoCondition -> do- line' <- if isDirective then pure "" else useTagPrep (line <> "\n")- auto <- processAutorequireContent autoContent- pure $ line' <> auto- AutorequireOnDirective (Just autoContent)- | isDirective -> do+ -- If this is an `autorequire` directive, ignore it. Otherwise+ -- output the line tag if necessary (useTagPrep) and then the+ -- line itself.+ unless isDirective (useTagPrep >> output line) processAutorequireContent autoContent++ AutorequireOnDirective (Just autoContent)+ | isDirective -> processAutorequireContent autoContent+ AutorequireOnDirective Nothing- | isDirective ->- -- TODO: Better error reporting.- error "Found an `autorequire` directive but no `Requires` file was found."- _ | isDirective -> pure ""- | otherwise -> useTagPrep $ line <> "\n"+ | isDirective -> throwError MissingOptionalRequiresFile + _ | isDirective -> pure ()+ | otherwise -> useTagPrep >> output line+ let hasWhere = -- TODO: This assumes that comments have whitespace before them and -- that `where` has whitespace before it. But@@ -95,51 +126,47 @@ Just (RequireDirective ri) -> -- renderImport already prepends the line tag if necessary.- renderImport getHostModule tag ri+ renderImport filterImports tag ri Just AutorequireDirective -> lineWithAutorequire True False -processAutorequireContent :: File.Input -> State TransformState Text+processAutorequireContent :: File.Input -> TransformM () processAutorequireContent autorequireContent = do modify $ \s -> s- { tstLineTagPrepend = prependLineTag+ { tstLineTagOutput = renderLineTag , tstAutorequire = AutorequireDisabled } - processed <- File.inputLines autorequireContent- & mapM (process (gets tstHostModule))- & fmap mconcat+ traverse_ (process True) (File.inputLines autorequireContent)+ modify $ \s -> s { tstLineTagOutput = renderLineTag } - modify $ \s -> s { tstLineTagPrepend = prependLineTag }- pure processed +renderImport :: Bool -> File.LineTag -> RequireInfo -> TransformM ()+renderImport filterImports line RequireInfo {..} = do+ tst <- get+ if filterImports && tstHostModule tst == Just riFullModuleName+ then+ -- We skipped a line, therefore we need a line tag before outputting+ -- the next one.+ put (tst { tstLineTagOutput = renderLineTag }) -renderImport- :: MonadState TransformState m- => m (Maybe ModuleName)- -> File.LineTag- -> RequireInfo- -> m Text-renderImport getHostModule line RequireInfo {..} = do- mhostModule <- getHostModule- lineTagPrep <- gets tstLineTagPrepend- let (res, prep) =- if mhostModule == Just riFullModuleName- then ("", prependLineTag)- else (typesImport <> renderLineTag line <> qualifiedImport, ignoreLineTag)- modify $ \s -> s { tstLineTagPrepend = prep }- pure $ lineTagPrep line res+ else do+ tstLineTagOutput tst line+ output typesImport+ renderLineTag line+ output qualifiedImport+ put (tst { tstLineTagOutput = ignoreLineTag }) where typesImport = unwords [ "import" , unModuleName riFullModuleName , "(" <> riImportedTypes <> ")"- ] <> "\n"+ ] qualifiedImport = unwords [ "import qualified" , unModuleName riFullModuleName , "as" , riModuleAlias- ] <> "\n"+ ]
package.yaml view
@@ -1,5 +1,5 @@ name: require-version: "0.4.8"+version: "0.4.9" github: "theam/require" license: Apache-2.0 author: "The Agile Monkeys"@@ -32,10 +32,12 @@ - relude - bytestring >= 0.10 && < 0.11 - text >= 1.2.3.0 && < 2- - megaparsec >= 7 && < 8+ - megaparsec >= 7 && < 9+ - mtl >= 2.2.1 - directory- - inliterate - optparse-generic+ - dlist+ - ansi-terminal library: source-dirs: library@@ -48,8 +50,6 @@ - require ghc-options: - -rtsopts- - -threaded- - -with-rtsopts=-N autorequirepp: source-dirs: executable/AutoRequire/ main: Main.hs@@ -57,8 +57,6 @@ - require ghc-options: - -rtsopts- - -threaded- - -with-rtsopts=-N benchmarks: require-benchmarks:
require.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: ceeb2f9c5a160393a1fd86ca01c63c4d957d256ae92501abfd87e3d415f5c686+-- hash: 17d63ecaad4aef59bc1c65336dd500edd837396b8e80b9609aacca8fed98e770 name: require-version: 0.4.8+version: 0.4.9 synopsis: Scrap your qualified import clutter description: See <https://theam.github.io/require> category: Other@@ -34,6 +34,7 @@ library exposed-modules: Require+ Require.Error Require.File Require.Parser Require.Transform@@ -45,11 +46,13 @@ default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric ghc-options: -Wall build-depends:- base >=4.9 && <5+ ansi-terminal+ , base >=4.9 && <5 , bytestring >=0.10 && <0.11 , directory- , inliterate- , megaparsec >=7 && <8+ , dlist+ , megaparsec >=7 && <9+ , mtl >=2.2.1 , optparse-generic , relude , text >=1.2.3.0 && <2@@ -62,13 +65,15 @@ hs-source-dirs: executable/AutoRequire/ default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric- ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N+ ghc-options: -Wall -rtsopts build-depends:- base >=4.9 && <5+ ansi-terminal+ , base >=4.9 && <5 , bytestring >=0.10 && <0.11 , directory- , inliterate- , megaparsec >=7 && <8+ , dlist+ , megaparsec >=7 && <9+ , mtl >=2.2.1 , optparse-generic , relude , require@@ -82,13 +87,15 @@ hs-source-dirs: executable/Require/ default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric- ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N+ ghc-options: -Wall -rtsopts build-depends:- base >=4.9 && <5+ ansi-terminal+ , base >=4.9 && <5 , bytestring >=0.10 && <0.11 , directory- , inliterate- , megaparsec >=7 && <8+ , dlist+ , megaparsec >=7 && <9+ , mtl >=2.2.1 , optparse-generic , relude , require@@ -105,11 +112,13 @@ default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N build-depends:- base >=4.9 && <5+ ansi-terminal+ , base >=4.9 && <5 , bytestring >=0.10 && <0.11 , directory- , inliterate- , megaparsec >=7 && <8+ , dlist+ , megaparsec >=7 && <9+ , mtl >=2.2.1 , optparse-generic , relude , require@@ -128,12 +137,14 @@ default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N build-depends:- base >=4.9 && <5+ ansi-terminal+ , base >=4.9 && <5 , bytestring >=0.10 && <0.11 , criterion , directory- , inliterate- , megaparsec >=7 && <8+ , dlist+ , megaparsec >=7 && <9+ , mtl >=2.2.1 , optparse-generic , relude , require
test-suite/Main.hs view
@@ -1,5 +1,6 @@ import qualified Data.Text as Text import Relude+import qualified Require.Error as Error import qualified Require.File as File import qualified Require.Transform as Require import Require.Types@@ -13,21 +14,36 @@ spec :: Spec spec = parallel $ do+ let transformLines autoMode fileInput =+ case Require.transform autoMode fileInput of+ Left err -> do+ -- sadly expectationFailure is not polymorphic in its return type+ expectationFailure $ "Tranform failed: " ++ show err+ pure $ error "expectationFailure should have thrown"+ Right tr ->+ pure tr++ transformString autoMode =+ fmap toString . transform autoMode++ transform autoMode =+ fmap unlines . transformLines autoMode+ describe "the transformation" $ do it "transforms the 'require' keyword into a properly qualified import" $ do let input = "require Data.Text" let expected = "import qualified Data.Text as Text"- let actual = Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input)- expected `Text.isInfixOf` actual+ actual `shouldContain` expected it "imports the type based on the module" $ do let input = "require Data.Text" let expected = "import Data.Text (Text)"- let actual = Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input)- expected `Text.isInfixOf` actual+ actual `shouldContain` expected it "keeps the rest of the content intact" $ do let input = "module Foo where\nrequire Data.Text\nfoo = 42" let expectedStart = "{-# LINE 1"@@ -35,7 +51,7 @@ let expectedTypeImport = "import Data.Text (Text)" let expectedQualifiedImport = "import qualified Data.Text as Text" let expectedContent = "foo = 42\n"- let actual = toString $ Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input) actual `shouldStartWith` expectedStart@@ -47,7 +63,7 @@ let input = "require Data.Text as Foo" let expectedTypeImport = "import Data.Text (Text)" let expectedQualifiedImport = "import qualified Data.Text as Foo"- let actual = toString $ Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input) actual `shouldContain` expectedTypeImport@@ -56,7 +72,7 @@ let input = "require Data.Text (Foo)" let expectedTypeImport = "import Data.Text (Foo)" let expectedQualifiedImport = "import qualified Data.Text as Text"- let actual = toString $ Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input) actual `shouldContain` expectedTypeImport@@ -65,7 +81,7 @@ let input = "require Data.Text as Quux (Foo)" let expectedTypeImport = "import Data.Text (Foo)" let expectedQualifiedImport = "import qualified Data.Text as Quux"- let actual = toString $ Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input) actual `shouldContain` expectedTypeImport@@ -73,55 +89,63 @@ it "skips comments" $ do let input = "require Data.Text -- test of comments" let expected = "import Data.Text (Text)"- let actual = Require.transform+ actual <- transformString AutorequireDisabled (File.Input (File.Name "Foo.hs") input)- expected `Text.isInfixOf` actual+ actual `shouldContain` expected it "allows empty parentheses" $ do let input = "require Data.Text ()" let expected1 = "import Data.Text ()" let expected2 = "import qualified Data.Text as Text"- let actual = lines $ Require.transform+ actual <- transformLines AutorequireDisabled (File.Input (File.Name "Foo.hs") input) actual `shouldSatisfy` elem expected1 actual `shouldSatisfy` elem expected2 describe "require-mode" $ do- it "respects autorequire directives" $ do- let fileInput = Text.unlines [ "module Main where", "autorequire", "import B" ]- let requireInput = Text.unlines [ "import A" ]- let actual = Text.lines $ Require.transform- (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)- (File.Input (File.Name "src/Foo/Bar.hs") fileInput)- actual `shouldSatisfy` elem "module Main where"- actual `shouldSatisfy` elem "import A"- actual `shouldSatisfy` elem "import B"- actual `shouldSatisfy` elemN 0 "autorequire"- it "ignores a second autorequire directive" $ do- let fileInput = Text.unlines [ "autorequire", "autorequire" ]- let requireInput = Text.unlines [ "import A" ]- let actual = Text.lines $ Require.transform- (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)- (File.Input (File.Name "src/Foo/Bar.hs") fileInput)- actual `shouldSatisfy` elemN 1 "import A"- actual `shouldSatisfy` elemN 0 "autorequire" it "keeps requires where the module is a substring of the filename" $ do -- Test case for https://github.com/theam/require/issues/20 let fileInput = Text.unlines [ "module FooTest where", "require Foo" ] let expected1 = "import Foo (Foo)" let expected2 = "import qualified Foo as Foo"- let actual = lines $ Require.transform+ actual <- transformLines AutorequireDisabled (File.Input (File.Name "FooTests.hs") fileInput) actual `shouldSatisfy` elem expected1 actual `shouldSatisfy` elem expected2 + describe "autorequire directive" $ do+ it "respects them" $ do+ let fileInput = Text.unlines [ "module Main where", "autorequire", "import B" ]+ let requireInput = Text.unlines [ "import A" ]+ actual <- transformLines+ (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)+ (File.Input (File.Name "src/Foo/Bar.hs") fileInput)+ actual `shouldSatisfy` elem "module Main where"+ actual `shouldSatisfy` elem "import A"+ actual `shouldSatisfy` elem "import B"+ actual `shouldSatisfy` elemN 0 "autorequire"+ it "ignores them after the first one" $ do+ let fileInput = Text.unlines [ "autorequire", "autorequire" ]+ let requireInput = Text.unlines [ "import A" ]+ actual <- transformLines+ (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)+ (File.Input (File.Name "src/Foo/Bar.hs") fileInput)+ actual `shouldSatisfy` elemN 1 "import A"+ actual `shouldSatisfy` elemN 0 "autorequire"+ it "throws an error if no requires file is provided" $ do+ let fileInput = "autorequire"+ let actual = Require.transform+ (AutorequireOnDirective Nothing)+ (File.Input (File.Name "Foo.hs") fileInput)+ actual `shouldBe` Left Error.MissingOptionalRequiresFile+ describe "autorequire-mode" $ do describe "inclusion after module directive" $ do let checkInclusion n fileInput = do let requireInput = "import A"- let actual = Text.lines $ Require.transform+ actual <- transformLines (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "src/Foo/Bar.hs") fileInput) actual `shouldSatisfy` elemN n requireInput@@ -141,18 +165,28 @@ , " ) where" ] it "doesn't add after data/class/instance declarations" $ do- checkInclusion 0 $ Text.unlines- [ "class Foo a where"- , "instance Foo x => Bar (Baz x) where"- , "data Vec n a where"- , " Nil :: Vec 0 a"- , " Cons :: a -> Vec n a -> Vec (n + 1) a"- ]+ let fileInput = unlines+ [ "class Foo a where"+ , "instance Foo x => Bar (Baz x) where"+ , "data Vec n a where"+ , " Nil :: Vec 0 a"+ , " Cons :: a -> Vec n a -> Vec (n + 1) a"+ ]+ let requireInput = unlines [ "import A" ]+ let actual = Require.transform+ (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)+ (File.Input (File.Name "Foo.hs") fileInput)+ actual `shouldBe` Left Error.AutorequireImpossible it "doesn't add after data/class/instance declarations split to multiple lines" $ do- checkInclusion 0 $ Text.unlines- [ "class Foo a -- some explanation here"- , " where"- ]+ let fileInput = unlines+ [ "class Foo a -- some explanation here"+ , " where"+ ]+ let requireInput = unlines [ "import A" ]+ let actual = Require.transform+ (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)+ (File.Input (File.Name "Foo.hs") fileInput)+ actual `shouldBe` Left Error.AutorequireImpossible describe "triggered using the autorequire directive" $ do it "can be triggered before without a module directive" $ do@@ -164,7 +198,7 @@ , "{-# LINE 2 \"Foo.hs\" #-}" , "main = return ()" ]- let actual = Require.transform+ actual <- transform (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "Foo.hs") fileInput) actual `shouldBe` expected@@ -177,7 +211,7 @@ , "{-# LINE 1 \"Requires\" #-}" , "import A" ]- let actual = Require.transform+ actual <- transform (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "Foo.hs") fileInput) actual `shouldBe` expected@@ -190,7 +224,7 @@ , "{-# LINE 2 \"Foo.hs\" #-}" , "module Main where" ]- let actual = Require.transform+ actual <- transform (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "Foo.hs") fileInput) actual `shouldBe` expected@@ -199,7 +233,7 @@ let fileInput = "module Foo.Bar where" let requireInput = "require Foo.Bar" let notExpected = "import Foo.Bar"- let actual = Require.transform+ actual <- transform (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "src/Foo/Bar.hs") fileInput) toString actual `shouldNotContain` notExpected@@ -214,7 +248,7 @@ , "{-# LINE 2 \"Foo.hs\" #-}" , "import B" ]- let actual = Require.transform+ actual <- transform (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput) (File.Input (File.Name "Foo.hs") fileInput) actual `shouldBe` expected