@@ -3,6 +3,7 @@ module Eucalypt.Core.ImportSpec
3
3
, spec
4
4
) where
5
5
6
+ import Data.Either (fromLeft , fromRight )
6
7
import qualified Data.Map as M
7
8
import Data.Maybe (fromJust )
8
9
import qualified Data.Set as S
@@ -103,16 +104,145 @@ unitsABC :: M.Map Input TranslationUnit
103
104
unitsABC =
104
105
M. fromList [(unitAInput, unitA), (unitBInput, unitB), (unitCInput, unitC)]
105
106
107
+ namedInput :: Input
108
+ namedInput = fromJust $ parseInputFromString " namedInput"
109
+
110
+ namedUnit :: TranslationUnit
111
+ namedUnit = applyName " name"
112
+ TranslationUnit
113
+ { truCore = unitACore
114
+ , truImports = mempty
115
+ , truTargets = mempty
116
+ }
117
+
118
+ unitDInput :: Input
119
+ unitDInput = fromJust $ parseInputFromString " unitD"
120
+
121
+ unitDCore :: CoreExpr
122
+ unitDCore =
123
+ letexp
124
+ [ ( " nest"
125
+ , withMeta (block [element " import" $ str " namedInput" ]) $
126
+ block [element " name" $ var " name" ])
127
+ ] $
128
+ block [element " quux" $ var " quux" ]
129
+
130
+ unitDCoreResult :: CoreExpr
131
+ unitDCoreResult =
132
+ letexp
133
+ [ ( " nest"
134
+ , withMeta (block [] ) $
135
+ letexp
136
+ [ ( " name"
137
+ , letexp [(" foo" , sym " foo" ), (" bar" , sym " bar" )] $
138
+ block [element " foo" $ var " foo" , element " bar" $ var " bar" ])
139
+ ] $
140
+ block [element " name" $ var " name" ])
141
+ ] $
142
+ block [element " quux" $ var " quux" ]
143
+
144
+ unitD :: TranslationUnit
145
+ unitD =
146
+ TranslationUnit
147
+ { truCore = unitDCore
148
+ , truImports = S. fromList [namedInput]
149
+ , truTargets = mempty
150
+ }
151
+
152
+ unitsNamedAndD :: M. Map Input TranslationUnit
153
+ unitsNamedAndD =
154
+ M. fromList [(namedInput, namedUnit), (unitDInput, unitD)]
155
+
156
+
157
+ importUnderImportInput :: Input
158
+ importUnderImportInput = fromJust $ parseInputFromString " importUnderImport"
159
+
160
+ importUnderImportCore :: CoreExpr
161
+ importUnderImportCore =
162
+ withMeta (block [element " import" $ str " unitA" ]) $
163
+ letexp
164
+ [ ( " nest"
165
+ , withMeta (block [element " import" $ str " unitA" ]) $
166
+ block [element " foo" $ var " foo" ])
167
+ ] $
168
+ block [element " foo" $ var " foo" ]
169
+
170
+ importUnderImportCoreResult :: CoreExpr
171
+ importUnderImportCoreResult =
172
+ withMeta (block [] ) $
173
+ letexp [(" foo" , sym " foo" ), (" bar" , sym " bar" )] $
174
+ letexp
175
+ [ ( " nest"
176
+ , withMeta (block [] ) $
177
+ letexp [(" foo" , sym " foo" ), (" bar" , sym " bar" )] $
178
+ block [element " foo" $ var " foo" ])
179
+ ] $
180
+ block [element " foo" $ var " foo" ]
181
+
182
+
183
+ importUnderImport :: TranslationUnit
184
+ importUnderImport =
185
+ TranslationUnit
186
+ { truCore = importUnderImportCore
187
+ , truImports = S. fromList [unitAInput]
188
+ , truTargets = mempty
189
+ }
190
+
191
+ unitsImportUnderImportAndA :: M. Map Input TranslationUnit
192
+ unitsImportUnderImportAndA =
193
+ M. fromList [(unitAInput, unitA), (importUnderImportInput, importUnderImport)]
194
+
195
+ circularImportInput :: Input
196
+ circularImportInput = fromJust $ parseInputFromString " circularImport"
197
+
198
+ circularImportCore :: CoreExpr
199
+ circularImportCore =
200
+ letexp
201
+ [ ( " z"
202
+ , withMeta (block [element " import" $ str " circularImport" ]) $
203
+ block [element " foo" $ var " foo" ])
204
+ ] $
205
+ block [element " z" $ var " z" ]
206
+
207
+ circularImport :: TranslationUnit
208
+ circularImport =
209
+ TranslationUnit
210
+ { truCore = circularImportCore
211
+ , truImports = S. fromList [circularImportInput]
212
+ , truTargets = mempty
213
+ }
214
+
215
+ unitsCircularImport :: M. Map Input TranslationUnit
216
+ unitsCircularImport =
217
+ M. fromList [(circularImportInput, circularImport)]
218
+
219
+ importAll :: M. Map Input TranslationUnit -> M. Map Input TranslationUnit
220
+ importAll = fromRight mempty . applyAllImports
221
+
106
222
spec :: Spec
107
223
spec =
108
224
describe " Import processing" $ do
109
225
context " single imports" $ do
110
226
it " processes a single import" $
111
227
processImports (const unitACore) unitBCore `shouldBe` unitBCoreResult
112
228
it " processes single import from unit map" $
113
- truCore <$> M. lookup unitBInput (applyAllImports unitsAB) `shouldBe` Just unitBCoreResult
229
+ truCore <$>
230
+ M. lookup unitBInput (importAll unitsAB) `shouldBe` Just unitBCoreResult
231
+ it " processes single named import from unit map" $
232
+ truCore <$>
233
+ M. lookup unitDInput (importAll unitsNamedAndD) `shouldBe`
234
+ Just unitDCoreResult
235
+ it " processes imports under imports" $
236
+ truCore <$>
237
+ M. lookup importUnderImportInput (importAll unitsImportUnderImportAndA) `shouldBe`
238
+ Just importUnderImportCoreResult
239
+ it " handles circular imports gracefully" $
240
+ fromLeft [] (applyAllImports unitsCircularImport) `shouldBe`
241
+ [circularImportInput]
114
242
context " transitive imports" $ do
115
243
it " intermediates are correct" $
116
- truCore <$> M. lookup unitBInput (applyAllImports unitsABC) `shouldBe` Just unitBCoreResult
244
+ truCore <$>
245
+ M. lookup unitBInput (importAll unitsABC) `shouldBe` Just unitBCoreResult
117
246
it " end result is correct" $
118
- truCore <$> M. lookup unitCInput (applyAllImports unitsABC) `shouldBe` Just unitCCoreResult
247
+ truCore <$>
248
+ M. lookup unitCInput (importAll unitsABC) `shouldBe` Just unitCCoreResult
0 commit comments