consumer_effect_files.tri (8593B)
1 -- The Python runner supplies probeRoot as fixture data. 2 !import "prelude" !Local 3 !import "io" !Local 4 !import "consumers.structural" S 5 !import "consumers.lexical-worker" L 6 !import "consumers.unit-compile" U 7 !import "consumers.effect-compose" E 8 !import "consumers.effect" Registry 9 !import "consumers.file-effects" Files 10 !import "consumers.copy-bytes" Copy 11 !import "consumers.effect-packages" Packages 12 13 record name argument = bind get (trace : put (pair (pair name argument) trace)) 14 readBytes path = bind (record "ReadBytes" path) (_ : Files.readBytes path) 15 writeBytesHandler argument = bind (record "WriteBytes" argument) (_ : Files.writeBytesHandler argument) 16 operations = [(pair "ReadBytes" readBytes) (pair "WriteBytes" writeBytesHandler)] 17 reference rows = map (row : pair (fst row) (fst (snd (snd row)))) rows 18 lexical rows = map (row : pair (fst row) (S.makeConsumer t (L.lWorker t (fst (snd row))))) rows 19 -- Registries wrap lexical descriptors in consumers; pure calls need the descriptor. 20 refWorker receivers name = lazyMaybe (_ : t) (value : value) (Registry.lookup receivers name) 21 lexWorker receivers name = snd (refWorker receivers name) 22 path name = append probeRoot name 23 rawText = append "alpha\r\nbeta\rZ\n" [0 195 169 255] 24 normalizedText = append "alpha\nbetaZ\n" [0 195 169 255] 25 ownedPackage receivers entry names helpers = (bindResult (Packages.ownedRows names receivers) 26 (owned _ : E.makePackage entry owned helpers)) 27 runCase step package input state = (bind (put t) (_ : 28 bind (E.run step operations package input state) (result : 29 bind get (trace : pure (pair result (reverse trace)))))) 30 recovered outcome stage = (matchResult (_ _ : false) 31 (value _ : and? (equal? (fst value) "recovered") 32 (and? (equal? (fst (snd value)) stage) 33 (not? (emptyList? (snd (snd value)))))) outcome) 34 propagated outcome stage = (matchResult 35 (value _ : and? (equal? (fst value) stage) (not? (emptyList? (snd value)))) 36 (_ _ : false) outcome) 37 checkConversion step receivers getWorker helper = (let transform = getWorker receivers "removeCR" in 38 E.prepare (ownedPackage receivers "convert" ["convert" "convertEnd"] 39 [(pair "copyText" helper)]) (package : 40 bind (runCase step package (pair (path "/input") (path "/output")) transform) (converted : 41 bind (readFile (path "/output")) (written : 42 bind (runCase step package (pair (path "/input") (path "/identity")) 43 (getWorker receivers "identityText")) (injected : 44 bind (readFile (path "/identity")) (unchanged : 45 bind (runCase step package (pair (path "/absent") (path "/untouched")) transform) (readFailure : 46 bind (runCase step package (pair (path "/input") (path "/missing/output")) transform) (writeFailure : 47 bind (runCase step helper (path "/input") (pair transform (path "/missing/output"))) (propagation : 48 pure (pair [converted injected readFailure writeFailure propagation] (foldl and? true [ 49 (equal? (fst converted) (ok (path "/output") t)) 50 (equal? (snd converted) [(pair "ReadBytes" (path "/input")) 51 (pair "WriteBytes" (pair (path "/output") normalizedText))]) 52 (equal? written (ok normalizedText t)) 53 (equal? (fst injected) (ok (path "/identity") t)) 54 (equal? unchanged (ok rawText t)) 55 (recovered (fst readFailure) "read") 56 (equal? (snd readFailure) [(pair "ReadBytes" (path "/absent"))]) 57 (recovered (fst writeFailure) "write") 58 (equal? (snd writeFailure) [(pair "ReadBytes" (path "/input")) 59 (pair "WriteBytes" (pair (path "/missing/output") normalizedText))]) 60 (propagated (fst propagation) "write") 61 (equal? (snd propagation) (snd writeFailure))]))))))))))) 62 checkTwo step receivers getWorker = (E.prepare 63 (ownedPackage receivers "readPair" ["readPair" "pairFirst" "pairSecond"] t) (package : 64 let appender = getWorker receivers "appendParts" in 65 bind (runCase step package (pair (path "/input") (path "/input-second")) appender) (combined : 66 bind (runCase step package (pair (path "/absent") (path "/input-second")) appender) (firstFailure : 67 bind (runCase step package (pair (path "/input") (path "/absent")) appender) (secondFailure : 68 pure (pair [combined firstFailure secondFailure] (foldl and? true [ 69 (equal? combined (pair (ok (append rawText "second\r\n") t) 70 [(pair "ReadBytes" (path "/input")) (pair "ReadBytes" (path "/input-second"))])) 71 (propagated (fst firstFailure) "read-first") 72 (equal? (snd firstFailure) [(pair "ReadBytes" (path "/absent"))]) 73 (propagated (fst secondFailure) "read-second") 74 (equal? (snd secondFailure) [(pair "ReadBytes" (path "/input")) 75 (pair "ReadBytes" (path "/absent"))])]))))))) 76 -- Manifest decoding is test input adaptation. The list is loaded through real 77 -- IO; all traversal, requests, accumulation, and error policy remain in SCP. 78 loadPaths manifest = (onResult_ (readFile manifest) 79 (problem : pure (err problem t)) 80 (bytes : pure (ok (lazyBool (_ : t) (_ : lines bytes) (equal? bytes t)) t))) 81 batchState receivers getWorker = (pair (getWorker receivers "writeAll") 82 (pair "batch\n" (pair (getWorker receivers "reversePaths") t))) 83 traceFor paths = map (destination : pair "WriteBytes" (pair destination "batch\n")) paths 84 batchFailure actual first bad = (matchResult 85 (value _ : and? (equal? (fst value) bad) 86 (and? (equal? (fst (snd value)) [first]) 87 (not? (emptyList? (snd (snd value)))))) 88 (_ _ : false) actual) 89 checkBatch step receivers getWorker paths emptyPaths failedPaths = (let state = batchState receivers getWorker in 90 E.prepare (ownedPackage receivers "writeAll" ["writeAll" "writeNext"] t) (package : 91 bind (runCase step package paths state) (completed : 92 bind (runCase step package emptyPaths state) (empty : 93 bind (runCase step package failedPaths state) (failed : 94 pure (pair [completed empty failed] (foldl and? true [ 95 (equal? completed (pair (ok paths t) (traceFor paths))) 96 (equal? empty (pair (ok t t) t)) 97 (batchFailure (fst failed) (path "/batch-first") (path "/missing/batch")) 98 (equal? (snd failed) (traceFor [(path "/batch-first") (path "/missing/batch")]))]))))))) 99 check rows packages paths emptyPaths failedPaths = (let refs = reference rows in 100 E.prepare (L.lPrepareEffectReceivers (lexical rows)) (lex : 101 thenIO (putStrLn "READY") 102 (bind (checkConversion S.runConsumer refs refWorker (fst packages)) (refConversion : 103 bind (checkTwo S.runConsumer refs refWorker) (refTwo : thenIO (putStrLn "REF_CONVERSION_DONE") 104 (bind (checkConversion L.lPreparedEffectStep lex lexWorker (snd packages)) (lexConversion : 105 bind (checkTwo L.lPreparedEffectStep lex lexWorker) (lexTwo : thenIO (putStrLn "LEX_CONVERSION_DONE") 106 (bind (checkBatch S.runConsumer refs refWorker paths emptyPaths failedPaths) (refBatch : 107 thenIO (putStrLn "REF_BATCH_DONE") 108 (bind (checkBatch L.lPreparedEffectStep lex lexWorker paths emptyPaths failedPaths) (lexBatch : 109 thenIO (putStrLn "LEX_BATCH_DONE") 110 (putStrLn (matchBool "consumer-effect-files-ok" "consumer-effect-files-DIFFER" 111 (foldl and? true [(equal? refConversion lexConversion) (snd lexConversion) 112 (equal? refBatch lexBatch) (snd lexBatch) 113 (equal? refTwo lexTwo) (snd lexTwo)]))))))))))))))) 114 main = io (onResult_ (readFile "demos/consumers/effect-files/workflows.scp") 115 (_ : putStrLn "consumer-effect-files-source-error") 116 (source : lazyResult 117 (_ _ : putStrLn "consumer-effect-files-compile-error") 118 (rows _ : onResult_ (readFile "lib/consumer/effects/copy-bytes.scp") 119 (_ : putStrLn "consumer-effect-files-helper-source-error") 120 (helperSource : lazyResult 121 (_ _ : putStrLn "consumer-effect-files-helper-compile-error") 122 (packages _ : onResult_ (loadPaths (path "/targets")) 123 (_ : putStrLn "consumer-effect-files-manifest-error") 124 (paths : onResult_ (loadPaths (path "/failed-targets")) 125 (_ : putStrLn "consumer-effect-files-manifest-error") 126 (failedPaths : onResult_ (loadPaths (path "/empty-targets")) 127 (_ : putStrLn "consumer-effect-files-manifest-error") 128 (emptyPaths : check rows packages paths emptyPaths failedPaths)))) 129 (Copy.compileSource helperSource))) 130 (U.compileScpUnit source t))) 131 main