blob: f0248af56f26983358915d17c0da2f27d3087a65 (
plain)
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
|
(.require
[library
[lux (.except)
[abstract
[monad (.only do)]]
[control
["[0]" try (.use "[1]#[0]" functor)]
[concurrency
["[0]" async (.only Async) (.use "[1]#[0]" monad)]]]
[data
["[0]" product]
["[0]" text (.use "[1]#[0]" equivalence)
["%" \\format (.only format)]]]
[math
["[0]" random]
[number
["n" nat]
["i" int]]]
[test
["_" property (.only Test)]
["[0]" unit]]]]
[\\library
["[0]" / (.only)
[//
[file (.only Path)]
["[0]" environment
["[1]" \\parser (.only Environment)]]]]])
(with_template [<name> <command> <type> <prep>]
[(def <name>
(-> <type> [Environment Path /.Command (List /.Argument)])
(|>> <prep> list [environment.empty "~" <command>]))]
[echo! "echo" Text (|>)]
[sleep! "sleep" Nat %.nat]
)
(def (can_wait! process)
(-> (/.Process Async) unit.Test)
(|> (of process await [])
(async#each (|>> (try#each (i.= /.normal))
(try.else false)
(unit.coverage [/.Exit /.normal])))
async#conjoint))
(def (can_read! expected process)
(-> Text (/.Process Async) (Async Bit))
(|> (of process read [])
(async#each (|>> (try#each (text#= expected))
(try.else false)))))
(def (can_destroy! process)
(-> (/.Process Async) (Async Bit))
(do async.monad
[?destroy (of process destroy [])
?await (of process await [])]
(in (and (when ?destroy
{try.#Success _}
true
{try.#Failure error}
false)
(when ?await
{try.#Success _}
false
{try.#Failure error}
true)))))
(with_expansions [<shell_coverage> (these [/.Command /.Argument])]
(def .public (spec shell)
(-> (/.Shell Async) Test)
(<| (_.for [/.Shell
/.execute
/.Process
/.read /.fail /.write /.destroy /.await])
(do [! random.monad]
[message (random.alphabetic 10)
seconds (of ! each (|>> (n.% 5) (n.+ 5)) random.nat)]
(in (do [! async.monad]
[?echo (of shell execute (..echo! message))
?sleep (of shell execute (..sleep! seconds))]
(when [?echo ?sleep]
[{try.#Success echo} {try.#Success sleep}]
(do !
[can_read! (..can_read! message echo)
can_destroy! (..can_destroy! sleep)]
(all unit.and
(unit.coverage <shell_coverage>
(and can_read!
can_destroy!))
(..can_wait! echo)
))
_
(unit.coverage <shell_coverage>
false))))))))
|