Skip to content

Commit 1cc3d2f

Browse files
committed
Add generic test plugin recorder initialisation
1 parent 6dd5a3b commit 1cc3d2f

File tree

1 file changed

+79
-9
lines changed

1 file changed

+79
-9
lines changed

hls-test-utils/src/Test/Hls.hs

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ module Test.Hls
1616
defaultTestRunner,
1717
goldenGitDiff,
1818
goldenWithHaskellDoc,
19+
goldenWithHaskellDocAndRecorder,
1920
goldenWithHaskellDocFormatter,
2021
goldenWithCabalDocFormatter,
2122
def,
23+
pluginTestRecorder,
2224
runSessionWithServer,
25+
runSessionWithServerAndRecorder,
2326
runSessionWithServerFormatter,
2427
runSessionWithCabalServerFormatter,
2528
runSessionWithServer',
@@ -34,6 +37,11 @@ module Test.Hls
3437
getLastBuildKeys,
3538
waitForKickDone,
3639
waitForKickStart,
40+
-- * Re-export logger types
41+
-- Avoids slightly annoying ghcide imports when they are unnecessary.
42+
WithPriority(..),
43+
Recorder,
44+
Priority(..),
3745
)
3846
where
3947

@@ -98,6 +106,8 @@ import Test.Tasty.Golden
98106
import Test.Tasty.HUnit
99107
import Test.Tasty.Ingredients.Rerun
100108
import Test.Tasty.Runners (NumThreads (..))
109+
import Control.Monad.Extra (forM)
110+
import Development.IDE.Types.Logger (Doc)
101111

102112
newtype Log = LogIDEMain IDEMain.Log
103113

@@ -134,10 +144,34 @@ goldenWithHaskellDoc plugin title testDataDir path desc ext act =
134144
act doc
135145
documentContents doc
136146

147+
goldenWithHaskellDocAndRecorder
148+
:: Pretty a
149+
=> (Recorder (WithPriority a) -> PluginDescriptor IdeState)
150+
-> TestName
151+
-> FilePath
152+
-> FilePath
153+
-> FilePath
154+
-> FilePath
155+
-> (TextDocumentIdentifier -> Session ())
156+
-> TestTree
157+
goldenWithHaskellDocAndRecorder plugin title testDataDir path desc ext act =
158+
goldenGitDiff title (testDataDir </> path <.> desc <.> ext)
159+
$ runSessionWithServerAndRecorder plugin testDataDir
160+
$ TL.encodeUtf8 . TL.fromStrict
161+
<$> do
162+
doc <- openDoc (path <.> ext) "haskell"
163+
void waitForBuildQueue
164+
act doc
165+
documentContents doc
137166

138167
runSessionWithServer :: PluginDescriptor IdeState -> FilePath -> Session a -> IO a
139168
runSessionWithServer plugin = runSessionWithServer' [plugin] def def fullCaps
140169

170+
runSessionWithServerAndRecorder :: Pretty b => (Recorder (WithPriority b) -> PluginDescriptor IdeState) -> FilePath -> Session a -> IO a
171+
runSessionWithServerAndRecorder pluginF fp act = do
172+
recorder <- pluginTestRecorder
173+
runSessionWithServer' [pluginF recorder] def def fullCaps fp act
174+
141175
runSessionWithServerFormatter :: PluginDescriptor IdeState -> String -> PluginConfig -> FilePath -> Session a -> IO a
142176
runSessionWithServerFormatter plugin formatter conf =
143177
runSessionWithServer'
@@ -211,6 +245,46 @@ keepCurrentDirectory = bracket getCurrentDirectory setCurrentDirectory . const
211245
lock :: Lock
212246
lock = unsafePerformIO newLock
213247

248+
-- | Initialise a recorder that can be instructed to write to stderr by
249+
-- setting the environment variable "HLS_TEST_PLUGIN_LOG_STDERR=1" before
250+
-- running the tests.
251+
--
252+
-- On the cli, use for example:
253+
--
254+
-- @
255+
-- HLS_TEST_PLUGIN_LOG_STDERR=1 cabal test <test-suite-of-plugin>
256+
-- @
257+
--
258+
-- to write all logs to stderr.
259+
pluginTestRecorder :: Pretty a => IO (Recorder (WithPriority a))
260+
pluginTestRecorder = do
261+
(recorder, _) <- initialiseTestRecorder ["HLS_TEST_PLUGIN_LOG_STDERR"]
262+
pure recorder
263+
264+
-- | Generic recorder initialisation for plugins and the HLS server for test-cases.
265+
--
266+
-- The created recorder writes to stderr if any of the given environment variables
267+
-- have been set to a value different to @0@.
268+
-- We allow multiple values, to make it possible to define a single environment variable
269+
-- that instructs all recorders in the test-suite to write to stderr.
270+
--
271+
-- We have to return the base logger function for HLS server logging initialisation.
272+
-- See 'runSessionWithServer'' for details.
273+
initialiseTestRecorder :: Pretty a => [String] -> IO (Recorder (WithPriority a), WithPriority (Doc ann) -> IO ())
274+
initialiseTestRecorder envVars = do
275+
docWithPriorityRecorder <- makeDefaultStderrRecorder Nothing Debug
276+
-- There are potentially multiple environment variables that enable this logger
277+
definedEnvVars <- forM envVars (\var -> fromMaybe "0" <$> lookupEnv var)
278+
let logStdErr = any (/= "0") definedEnvVars
279+
280+
docWithFilteredPriorityRecorder =
281+
if logStdErr then mempty
282+
else cfilter (\WithPriority{ priority } -> priority >= Debug) docWithPriorityRecorder
283+
284+
Recorder {logger_} = docWithFilteredPriorityRecorder
285+
286+
pure (cmapWithPrio pretty docWithFilteredPriorityRecorder, logger_)
287+
214288

215289
-- | Host a server, and run a test session on it
216290
-- Note: cwd will be shifted into @root@ in @Session a@
@@ -229,20 +303,16 @@ runSessionWithServer' plugins conf sconf caps root s = withLock lock $ keepCurre
229303
(inR, inW) <- createPipe
230304
(outR, outW) <- createPipe
231305

232-
docWithPriorityRecorder <- makeDefaultStderrRecorder Nothing Debug
233-
234-
logStdErr <- fromMaybe "0" <$> lookupEnv "LSP_TEST_LOG_STDERR"
306+
-- Allow two environment variables, because "LSP_TEST_LOG_STDERR" has been used before,
307+
-- (thus, backwards compatibility) and "HLS_TEST_SERVER_LOG_STDERR" because it
308+
-- uses a more descriptive name.
309+
-- It is also in better accordance with 'pluginTestRecorder' which uses "HLS_TEST_PLUGIN_LOG_STDERR"
310+
(recorder, logger_) <- initialiseTestRecorder ["LSP_TEST_LOG_STDERR", "HLS_TEST_SERVER_LOG_STDERR"]
235311

236312
let
237-
docWithFilteredPriorityRecorder@Recorder{ logger_ } =
238-
if logStdErr == "0" then mempty
239-
else cfilter (\WithPriority{ priority } -> priority >= Debug) docWithPriorityRecorder
240-
241313
-- exists until old logging style is phased out
242314
logger = Logger $ \p m -> logger_ (WithPriority p emptyCallStack (pretty m))
243315

244-
recorder = cmapWithPrio pretty docWithFilteredPriorityRecorder
245-
246316
arguments@Arguments{ argsHlsPlugins, argsIdeOptions, argsLogger } = defaultArguments (cmapWithPrio LogIDEMain recorder) logger
247317

248318
hlsPlugins =

0 commit comments

Comments
 (0)