aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/world/file.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/test/lux/world/file.lux')
-rw-r--r--stdlib/source/test/lux/world/file.lux335
1 files changed, 322 insertions, 13 deletions
diff --git a/stdlib/source/test/lux/world/file.lux b/stdlib/source/test/lux/world/file.lux
index b7ffb5f6c..edc511f2b 100644
--- a/stdlib/source/test/lux/world/file.lux
+++ b/stdlib/source/test/lux/world/file.lux
@@ -5,35 +5,344 @@
["[0]" monad (.only do)]]
[control
["[0]" io (.only IO)]
- ["[0]" try (.only Try)]
+ ["[0]" maybe (.use "[1]#[0]" functor)]
+ ["[0]" try (.only Try) (.use "[1]#[0]" functor)]
["[0]" exception]
[concurrency
["[0]" async (.only Async)]
- ["[0]" atom (.only Atom)]]]
+ ["[0]" atom (.only Atom)]]
+ [function
+ ["[0]" predicate]]]
[data
- ["[0]" binary (.only Binary) (.use "[1]#[0]" monoid)]
- ["[0]" text (.use "[1]#[0]" equivalence)]
+ ["[0]" binary (.only Binary) (.use "[1]#[0]" equivalence monoid)
+ ["$[1]" \\test]]
+ ["[0]" text (.use "[1]#[0]" equivalence)
+ ["%" \\format (.only format)]
+ [encoding
+ ["[0]" utf8 (.use "[1]#[0]" codec)]]]
[collection
["[0]" dictionary (.only Dictionary)]
["[0]" list]]]
[math
- ["[0]" random]]
+ ["[0]" random]
+ [number
+ ["n" nat]]]
[meta
[macro
["^" pattern]]]
[world
[time
- ["[0]" instant (.only Instant)]]]
+ ["[0]" instant (.only Instant) (.use "[1]#[0]" equivalence)]]]
[test
- ["[0]" unit]
- ["_" property (.only Test)]]]]
+ ["_" property (.only Test)]
+ ["[0]" unit]]]]
["[0]" /
["[1][0]" watch]
["[1][0]" extension]]
[\\library
- ["[0]" /]]
- [\\specification
- ["$[0]" /]])
+ ["[0]" /]])
+
+(def (for_path fs)
+ (-> (IO (/.System Async)) Test)
+ (<| (_.for [/.Path])
+ (do [! random.monad]
+ [parent (random.numeric 2)
+ child (random.numeric 2)])
+ in
+ (do async.monad
+ [fs (async.future fs)]
+ (all unit.and
+ (unit.coverage [/.rooted]
+ (let [path (/.rooted fs parent child)]
+ (and (text.starts_with? parent path)
+ (text.ends_with? child path))))
+ (unit.coverage [/.parent]
+ (|> (/.rooted fs parent child)
+ (/.parent fs)
+ (maybe#each (text#= parent))
+ (maybe.else false)))
+ (unit.coverage [/.name]
+ (|> (/.rooted fs parent child)
+ (/.name fs)
+ (text#= child)))
+ ))))
+
+(def (directory?&make_directory fs parent)
+ (-> (/.System Async) /.Path (Async Bit))
+ (do async.monad
+ [directory_pre! (of fs directory? parent)
+ made? (of fs make_directory parent)
+ directory_post! (of fs directory? parent)]
+ (in (and (not directory_pre!)
+ (when made?
+ {try.#Success _} true
+ {try.#Failure _} false)
+ directory_post!))))
+
+(def (file?&write fs content path)
+ (-> (/.System Async) Binary /.Path (Async Bit))
+ (do async.monad
+ [file_pre! (of fs file? path)
+ made? (of fs write path content)
+ file_post! (of fs file? path)]
+ (in (and (not file_pre!)
+ (when made?
+ {try.#Success _} true
+ {try.#Failure _} false)
+ file_post!))))
+
+(def (file_size&read&append fs expected_file_size content appendix path)
+ (-> (/.System Async) Nat Binary Binary /.Path (Async Bit))
+ (do async.monad
+ [pre_file_size (of fs file_size path)
+ pre_content (of fs read path)
+ appended? (of fs append path appendix)
+ post_file_size (of fs file_size path)
+ post_content (of fs read path)]
+ (in (<| (try.else false)
+ (do [! try.monad]
+ [pre_file_size!
+ (of ! each (n.= expected_file_size) pre_file_size)
+
+ pre_content!
+ (of ! each (binary#= content) pre_content)
+
+ _ appended?
+
+ post_file_size!
+ (of ! each (n.= (n.* 2 expected_file_size)) post_file_size)
+
+ post_content!
+ (of ! each (binary#= (binary#composite content appendix)) post_content)]
+ (in (and pre_file_size!
+ pre_content!
+ post_file_size!
+ post_content!)))))))
+
+(def (modified?&last_modified fs expected_time path)
+ (-> (/.System Async) Instant /.Path (Async Bit))
+ (do async.monad
+ [modified? (of fs modify path expected_time)
+ last_modified (of fs last_modified path)]
+ (in (<| (try.else false)
+ (do [! try.monad]
+ [_ modified?]
+ (of ! each (instant#= expected_time) last_modified))))))
+
+(def (directory_files&sub_directories fs parent sub_dir child)
+ (-> (/.System Async) /.Path /.Path /.Path (Async Bit))
+ (let [sub_dir (/.rooted fs parent sub_dir)
+ child (/.rooted fs parent child)]
+ (do async.monad
+ [made_sub? (of fs make_directory sub_dir)
+ directory_files (of fs directory_files parent)
+ sub_directories (of fs sub_directories parent)
+ .let [(open "list#[0]") (list.equivalence text.equivalence)]]
+ (in (<| (try.else false)
+ (do try.monad
+ [_ made_sub?]
+ (in (and (|> directory_files
+ (try#each (list#= (list child)))
+ (try.else false))
+ (|> sub_directories
+ (try#each (list#= (list sub_dir)))
+ (try.else false))))))))))
+
+(def (move&delete fs parent child alternate_child)
+ (-> (/.System Async) /.Path Text Text (Async Bit))
+ (let [origin (/.rooted fs parent child)
+ destination (/.rooted fs parent alternate_child)]
+ (do [! async.monad]
+ [moved? (of fs move origin destination)
+ lost? (|> origin
+ (of fs file?)
+ (of ! each not))
+ found? (of fs file? destination)
+ deleted? (of fs delete destination)]
+ (in (<| (try.else false)
+ (do try.monad
+ [_ moved?
+ _ deleted?]
+ (in (and lost?
+ found?))))))))
+
+(def (for_system fs)
+ (-> (IO (/.System Async)) Test)
+ (<| (do [! random.monad]
+ [parent (random.numeric 2)
+ child (random.numeric 2)
+ sub_dir (random.only (|>> (text#= child) not)
+ (random.numeric 2))
+ alternate_child (random.only (predicate.and
+ (|>> (text#= child) not)
+ (|>> (text#= sub_dir) not))
+ (random.numeric 2))
+ expected_file_size (of ! each (|>> (n.% 10) ++) random.nat)
+ content ($binary.random expected_file_size)
+ appendix ($binary.random expected_file_size)
+ expected_time random.instant])
+ in
+ (do [! async.monad]
+ [fs (async.future fs)
+ .let [path (/.rooted fs parent child)]
+
+ directory?&make_directory
+ (..directory?&make_directory fs parent)
+
+ file?&write
+ (..file?&write fs content path)
+
+ file_size&read&append
+ (..file_size&read&append fs expected_file_size content appendix path)
+
+ modified?&last_modified
+ (..modified?&last_modified fs expected_time path)
+
+ can_execute?
+ (|> path
+ (of fs can_execute?)
+ (of ! each (|>> (try.else true) not)))
+
+ directory_files&sub_directories
+ (..directory_files&sub_directories fs parent sub_dir child)
+
+ move&delete
+ (..move&delete fs parent child alternate_child)])
+ (unit.coverage [/.System]
+ (and directory?&make_directory
+ file?&write
+ file_size&read&append
+ modified?&last_modified
+ can_execute?
+ directory_files&sub_directories
+ move&delete))))
+
+(def (make_directories&cannot_make_directory fs)
+ (-> (IO (/.System Async)) Test)
+ (<| (do [! random.monad]
+ [dir/0 (random.numeric 2)
+ dir/1 (random.numeric 2)
+ dir/2 (random.numeric 2)])
+ in
+ (do [! async.monad]
+ [fs (async.future fs)
+ .let [dir/1 (/.rooted fs dir/0 dir/1)
+ dir/2 (/.rooted fs dir/1 dir/2)]
+ pre_dir/0 (of fs directory? dir/0)
+ pre_dir/1 (of fs directory? dir/1)
+ pre_dir/2 (of fs directory? dir/2)
+ made? (/.make_directories ! fs dir/2)
+ post_dir/0 (of fs directory? dir/0)
+ post_dir/1 (of fs directory? dir/1)
+ post_dir/2 (of fs directory? dir/2)
+
+ cannot_make_directory!/0 (/.make_directories ! fs "")
+ cannot_make_directory!/1 (/.make_directories ! fs (of fs separator))])
+ (all unit.and
+ (unit.coverage [/.make_directories]
+ (and (not pre_dir/0)
+ (not pre_dir/1)
+ (not pre_dir/2)
+ (when made?
+ {try.#Success _} true
+ {try.#Failure _} false)
+ post_dir/0
+ post_dir/1
+ post_dir/2))
+ (unit.coverage [/.cannot_make_directory]
+ (and (when cannot_make_directory!/0
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? /.cannot_make_directory error))
+ (when cannot_make_directory!/1
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? /.cannot_make_directory error))))
+ )))
+
+(def (make_file&cannot_make_file fs)
+ (-> (IO (/.System Async)) Test)
+ (<| (do [! random.monad]
+ [file/0 (random.numeric 3)])
+ in
+ (do [! async.monad]
+ [fs (async.future fs)
+ make_file!/0 (/.make_file ! fs (utf8#encoded file/0) file/0)
+ make_file!/1 (/.make_file ! fs (utf8#encoded file/0) file/0)])
+ (all unit.and
+ (unit.coverage [/.make_file]
+ (when make_file!/0
+ {try.#Success _} true
+ {try.#Failure error} false))
+ (unit.coverage [/.cannot_make_file]
+ (when make_file!/1
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? /.cannot_make_file error)))
+ )))
+
+(def (for_utilities fs)
+ (-> (IO (/.System Async)) Test)
+ (all _.and
+ (..make_directories&cannot_make_directory fs)
+ (..make_file&cannot_make_file fs)
+ ))
+
+(def (exists? fs)
+ (-> (IO (/.System Async)) Test)
+ (<| (do [! random.monad]
+ [file (random.numeric 2)
+ dir (random.only (|>> (text#= file) not)
+ (random.numeric 2))])
+ in
+ (do [! async.monad]
+ [fs (async.future fs)
+
+ pre_file/0 (of fs file? file)
+ pre_file/1 (/.exists? ! fs file)
+ pre_dir/0 (of fs directory? dir)
+ pre_dir/1 (/.exists? ! fs dir)
+
+ made_file? (/.make_file ! fs (utf8#encoded file) file)
+ made_dir? (of fs make_directory dir)
+
+ post_file/0 (of fs file? file)
+ post_file/1 (/.exists? ! fs file)
+ post_dir/0 (of fs directory? dir)
+ post_dir/1 (/.exists? ! fs dir)])
+ (unit.coverage [/.exists?]
+ (and (not pre_file/0)
+ (not pre_file/1)
+ (not pre_dir/0)
+ (not pre_dir/1)
+
+ (when made_file?
+ {try.#Success _} true
+ {try.#Failure _} false)
+ (when made_dir?
+ {try.#Success _} true
+ {try.#Failure _} false)
+
+ post_file/0
+ post_file/1
+ post_dir/0
+ post_dir/1))))
+
+(def .public (spec fs)
+ (-> (IO (/.System Async))
+ Test)
+ (all _.and
+ (..for_path fs)
+ (..for_utilities fs)
+ (..for_system fs)
+ (..exists? fs)
+ ))
(type Disk
(Dictionary /.Path (Either [Instant Binary] (List Text))))
@@ -251,9 +560,9 @@
file (random.lower_cased 1)]
(all _.and
(_.for [/.mock]
- ($/.spec (io.io (/.mock /))))
+ (..spec (io.io (/.mock /))))
(_.for [/.async]
- ($/.spec (io.io (/.async (..fs /)))))
+ (..spec (io.io (/.async (..fs /)))))
(in (do async.monad
[.let [fs (/.mock /)]