-
Notifications
You must be signed in to change notification settings - Fork 14
/
DotenvSpec.hs
184 lines (132 loc) · 6.41 KB
/
DotenvSpec.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Configuration.DotenvSpec (main, spec) where
import Configuration.Dotenv (Config (..), load, loadFile,
onMissingFile, parseFile)
import Configuration.Dotenv.Environment (getEnvironment, lookupEnv,
setEnv, unsetEnv)
import Test.Hspec
import Control.Monad (liftM)
import Data.Maybe (fromMaybe)
import System.Process (readCreateProcess, shell)
main :: IO ()
main = hspec spec
spec :: Spec
spec = do
describe "load" $ after_ clearEnvs $ do
it "loads the given list of configuration options to the environment" $ do
lookupEnv "foo" `shouldReturn` Nothing
load False [("foo", "bar")]
lookupEnv "foo" `shouldReturn` Just "bar"
it "preserves existing settings when overload is false" $ do
setEnv "foo" "preset"
load False [("foo", "new setting")]
lookupEnv "foo" `shouldReturn` Just "preset"
it "overrides existing settings when overload is true" $ do
setEnv "foo" "preset"
load True [("foo", "new setting")]
lookupEnv "foo" `shouldReturn` Just "new setting"
it "loads the last set value in config list with duplicates" $ do
lookupEnv "foo" `shouldReturn` Nothing
lookupEnv "bar" `shouldReturn` Nothing
load False [("foo", "first"), ("bar", "second"), ("foo", "third")]
lookupEnv "foo" `shouldReturn` Just "third"
lookupEnv "bar" `shouldReturn` Just "second"
describe "loadFile" $ before_ setupEnv $ after_ clearEnvs $ do
it "loads the configuration options to the environment from a file" $ do
lookupEnv "DOTENV" `shouldReturn` Nothing
loadFile sampleConfig
lookupEnv "DOTENV" `shouldReturn` Just "true"
it "respects predefined settings when overload is false" $ do
setEnv "DOTENV" "preset"
loadFile sampleConfig
lookupEnv "DOTENV" `shouldReturn` Just "preset"
it "overrides predefined settings when overload is true" $ do
setEnv "DOTENV" "preset"
loadFile sampleConfig { configOverride = True }
lookupEnv "DOTENV" `shouldReturn` Just "true"
it "loads the last set value in dotenv file with duplicates" $ do
lookupEnv "FOO" `shouldReturn` Nothing
lookupEnv "BAR" `shouldReturn` Nothing
loadFile (Config ["spec/fixtures/.dotenv.dup"] [] False False False True)
lookupEnv "FOO" `shouldReturn` Just "last"
lookupEnv "BAR" `shouldReturn` Just "tender"
context "when the .env.example is present" $ do
let config = sampleConfig { configExamplePath = ["spec/fixtures/.dotenv.example"]}
context "when the needed env vars are missing" $
it "should fail with an error call" $ do
unsetEnv "ANOTHER_ENV"
loadFile config `shouldThrow` anyErrorCall
context "when the needed env vars are not missing" $ do
it "should succeed when loading all of the needed env vars" $ do
-- Load extra information
me <- init <$> readCreateProcess (shell "whoami") ""
home <- fromMaybe "" <$> lookupEnv "HOME"
-- Load envs
loadFile config
-- Check existing envs
lookupEnv "ENVIRONMENT" `shouldReturn` Just home
lookupEnv "ME" `shouldReturn` Just me
lookupEnv "DOTENV" `shouldReturn` Just "true"
lookupEnv "UNICODE_TEST" `shouldReturn` Just "Manabí"
lookupEnv "ANOTHER_ENV" `shouldReturn` Just "hello"
it "succeeds when variable is preset" $ do
setEnv "DOTENV" "preset"
loadFile config
lookupEnv "DOTENV" `shouldReturn` Just "preset"
describe "parseFile" $ after_ clearEnvs $ do
it "returns variables from a file without changing the environment" $ do
lookupEnv "DOTENV" `shouldReturn` Nothing
liftM head (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("DOTENV", "true")
lookupEnv "DOTENV" `shouldReturn` Nothing
it "recognizes unicode characters" $
liftM (!! 1) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("UNICODE_TEST", "Manabí")
it "recognises environment variables" $ do
home <- fromMaybe "" <$> lookupEnv "HOME"
liftM (!! 2) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("ENVIRONMENT", home)
it "recognises previous variables" $
liftM (!! 3) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("PREVIOUS", "true")
it "recognises commands" $ do
me <- init <$> readCreateProcess (shell "whoami") ""
liftM (!! 4) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("ME", me)
#if MIN_VERSION_base(4,11,0)
it "recognizes blank variable" $
liftM (!! 5) (parseFile "spec/fixtures/.dotenv") `shouldReturn`
("BLANK", "")
#endif
describe "onMissingFile" $ after_ clearEnvs $ do
context "when target file is present" $
it "loading works as usual" $ do
onMissingFile (loadFile sampleConfig {configOverride = True}) (return ())
lookupEnv "DOTENV" `shouldReturn` Just "true"
context "when target file is missing" $
it "executes supplied handler instead" $
onMissingFile (True <$ loadFile sampleConfig {configPath= ["spec/fixtures/.foo"], configOverride = True}) (return False)
`shouldReturn` False
describe "onDuplicatedKeys" $ after_ clearEnvs $ do
context "when duplicates are forbidden" $ do
it "throws an error on duplicated keys" $
loadFile sampleConfig { configPath = ["spec/fixtures/.dotenv", "spec/fixtures/.dotenv"], allowDuplicates = False }
`shouldThrow` anyIOException
it "works as usual when there is no duplicated keys" $ do
loadFile sampleConfig { allowDuplicates = False }
lookupEnv "DOTENV" `shouldReturn` Just "true"
describe "onConfigDryRun" $ after_ clearEnvs $
context "when dry-run is enabled " $
it "loads the variables" $ do
loadFile sampleConfig { configPath = ["spec/fixtures/.dotenv"], configDryRun = True }
lookupEnv "DOTENV" `shouldReturn` Just "true"
sampleConfig :: Config
sampleConfig = Config ["spec/fixtures/.dotenv"] [] False False False True
clearEnvs :: IO ()
clearEnvs =
getEnvironment >>= mapM_ unsetEnv . fmap fst
setupEnv :: IO ()
setupEnv = do
setEnv "ANOTHER_ENV" "hello"
setEnv "HOME" "/home/me"