Edited at

stack new叩いたらすぐhspecが使えるようにする


はじめに

最近趣味でHaskellを書いています。

新しい言語を勉強をする時に、TDDBCで使われるお題(セマンティック・バージョニングなど)を利用することが多いのですが、HaskellでもHspecを使って書いています。

ただ、毎回stack newをしてpackage.yamlなどを書き換えるのも若干面倒だったので、

stack newしたらHspecが設定済みのプロジェクトが作れるように、今回設定をしていきます。


2019/05/06追記

コメント欄でご指摘頂きましたが、

標準のテンプレート集hspecが用意されているようです。

hspecが設定済みのプロジェクトを使うのであれば、stack new のテンプレート名にhspecを指定して実行すれば使えます。

$ stack new プロジェクト名 hspec


前提


  • stackがインストールされていること


  • $ stack install hspec-discover で hspec-discover入れていること


手順

stack newのデフォルトテンプレートを開きます。

$ cd ~/.stack/templates/

$ vi new-template.hsfiles

テンプレートファイルを編集します。


new-template.hsfiles

tests:

{{name}}-test:
main: Spec.hs
source-dirs: test
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- {{name}}
+ - hspec

{-# START_FILE test/Spec.hs #-}
- main :: IO ()
- main = putStrLn "Test suite not yet implemented"
+ {-# OPTIONS_GHC -F -pgmF hspec-discover #-}

+ {-# START_FILE test/LibSpec.hs #-}
+ module LibSpec (spec) where

+ import Test.Hspec
+ import Lib

+ spec :: Spec
+ spec = do
+ describe "テストケース" $ do
+ it "somefuncが返ってくること" $ do
+ someFunc `shouldBe` "someFunc"

{-# START_FILE src/Lib.hs #-}
module Lib
( someFunc
) where

- someFunc :: String
+ someFunc :: IO ()
- someFunc = "someFunc"
+ someFunc = putStrLn "someFunc"

{-# START_FILE app/Main.hs #-}
module Main where

import Lib

main :: IO ()
- main = someFunc
+ main = return ()


{-# START_FILE ファイル名 #-}で、プロジェクトを作ったときのデフォルトで作られるファイルと、その中身を設定することができます。

新規作成したらすぐテストが試せるように、デフォルトのファイルの中身を書き換えています。

テンプレートファイルを書き換えたあとは、実際にそのとおりにプロジェクトが出来たか試してみます。

問題がなければ以下のようにデフォルトで作ったテストが通ると思います。

$ stack new example

$ cd example
$ stack test

Progress 1/2: example-0.1.0.0
Lib
テストケース
somefuncが返ってくること

Finished in 0.0002 seconds
1 example, 0 failures

これで次回から、すぐテストができるプロジェクトが作成できるようになりました。

上記の説明だと、デフォルトのテンプレートを変更しましたが、

デフォルトを変更するのに抵抗がある人は、~/.stack/templates/に新しいテンプレートを作成しておき、stack newするときに指定をすればテンプレートの使い分けができます。

$ cd ~/.stack/templates/

$ cp new-template.hsfiles my-template.hsfiles

# なにかしらテンプレート編集したあと、任意のフォルダで下記を実行
$ stack new exampleProject my-template.hsfiles


おまけ

stack newで作ったプロジェクトは当然ですがgitリポジトリではありません。

git管理する場合にはプロジェクト作成後に自分でgit initコマンドを叩く必要があります。

作ったプロジェクトを自動的にgitリポジトリにしたい場合は、config.yamlを設定します。

$ vi ~/.stack/config.yaml


config.yaml

templates:

scm-init: git # 追加

この設定をしておくと、次回からstack newしたときに、git initが自動的にされています。

以上です。