aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/aedifex/command/auto.lux
blob: c23519bccaf17292b3674d449748a4a9b219c07c (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
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
(.module:
  [lux #*
   ["_" test (#+ Test)]
   [abstract
    [monad (#+ do)]]
   [control
    ["." try]
    [parser
     ["." environment (#+ Environment)]]
    [concurrency
     ["." atom (#+ Atom)]
     ["." promise (#+ Promise)]]
    [security
     ["!" capability]]]
   [data
    ["." text
     ["%" format (#+ format)]]
    [collection
     ["." dictionary]
     ["." set]
     ["." list ("#\." functor)]]]
   [math
    ["." random (#+ Random)]
    [number
     ["n" nat]]]
   [world
    [console (#+ Console)]
    ["." shell (#+ Shell)]
    ["." program (#+ Program)]
    ["." file (#+ Path)
     ["." watch]]]]
  ["." // #_
   ["@." version]
   ["@." build]
   ["$/#" // #_
    ["#." package]]]
  {#program
   ["." /
    ["/#" // #_
     ["#." build]
     ["/#" // #_
      [command (#+ Command)]
      ["#" profile (#+ Profile)]
      ["#." action]
      ["#." artifact
       ["#/." type]]
      ["#." dependency
       ["#/." resolution (#+ Resolution)]]]]]})

(def: (command end_signal dummy_files)
  (-> Text (List Path)
      [(Atom [Nat (List Path)])
       (-> (Console Promise) (Program Promise) (file.System Promise) (Shell Promise) Resolution (Command Any))])
  (let [@runs (: (Atom [Nat (List Path)])
                 (atom.atom [0 dummy_files]))]
    [@runs
     (function (_ console program fs shell resolution profile)
       (do {! promise.monad}
         [[_ [runs remaining_files]] (promise.future
                                      (atom.update (function (_ [runs remaining_files])
                                                     [(inc runs) remaining_files])
                                                   @runs))]
         (case remaining_files
           #.Nil
           (wrap (#try.Failure end_signal))
           
           (#.Cons head tail)
           (do (try.with !)
             [_ (!.use (\ fs create_file) [head])]
             (do !
               [_ (promise.future (atom.write [runs tail] @runs))]
               (wrap (#try.Success [])))))))]))

(def: #export test
  Test
  (<| (_.covering /._)
      (do {! random.monad}
        [#let [/ (\ file.default separator)
               [fs watcher] (watch.mock /)]
         end_signal (random.ascii/alpha 5)
         
         program (random.ascii/alpha 5)
         target (random.ascii/alpha 5)
         source (random.ascii/alpha 5)
         #let [empty_profile (: Profile
                                (\ ///.monoid identity))
               with_target (: (-> Profile Profile)
                              (set@ #///.target (#.Some target)))
               with_program (: (-> Profile Profile)
                               (set@ #///.program (#.Some program)))
               
               profile (|> empty_profile
                           with_program
                           with_target
                           (set@ #///.sources (set.from_list text.hash (list source))))]

         home (random.ascii/alpha 5)
         working_directory (random.ascii/alpha 5)
         
         expected_runs (\ ! map (|>> (n.% 10) (n.max 2)) random.nat)
         dummy_files (|> (random.ascii/alpha 5)
                         (random.set text.hash (dec expected_runs))
                         (\ ! map (|>> set.to_list (list\map (|>> (format source /))))))
         resolution @build.resolution]
        ($_ _.and
            (wrap (do promise.monad
                    [verdict (do ///action.monad
                               [#let [[@runs command] (..command end_signal dummy_files)]
                                _ (!.use (\ fs create_directory) [source])
                                _ (\ watcher poll [])]
                               (do promise.monad
                                 [outcome ((/.do! 1 watcher command)
                                           (@version.echo "")
                                           (program.async (program.mock environment.empty home working_directory))
                                           fs
                                           (shell.async (@build.good_shell []))
                                           resolution
                                           profile)
                                  [actual_runs _] (promise.future (atom.read @runs))]
                                 (wrap (#try.Success (and (n.= expected_runs actual_runs)
                                                          (case outcome
                                                            (#try.Failure error)
                                                            (is? end_signal error)

                                                            (#try.Success _)
                                                            false))))))]
                    (_.cover' [/.do!]
                              (try.default false verdict))))
            ))))