aboutsummaryrefslogtreecommitdiffstats
path: root/test/unit
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-10-02 22:36:49 -0300
committerMarcos Magueta <maguetamarcos@gmail.com>2026-10-02 22:36:49 -0300
commit32e663591a84d095723e62ef934a0bc6e1470b52 (patch)
tree60d6905606c4c5b829d51dcf95603d62df946f84 /test/unit
parent9f8fe7b4e5891e848d035c240731fb578f6b33b5 (diff)
parent73aec387d33626e33026432db5b1137b59edf0cf (diff)
downloadRNT-32e663591a84d095723e62ef934a0bc6e1470b52.tar.gz
RNT-32e663591a84d095723e62ef934a0bc6e1470b52.zip
Merge branch 'relation-bipartite-registration'
Diffstat (limited to '')
-rw-r--r--test/unit/evaluators/FOL.ml94
-rw-r--r--test/unit/kernel/EphemeralRelation.ml24
2 files changed, 113 insertions, 5 deletions
diff --git a/test/unit/evaluators/FOL.ml b/test/unit/evaluators/FOL.ml
index 046fa3f..0a3dabc 100644
--- a/test/unit/evaluators/FOL.ml
+++ b/test/unit/evaluators/FOL.ml
@@ -88,6 +88,92 @@ module Make (S : Abstract.Storage.STORAGE) (C : Helpers.Storage.CONFIGURATOR) =
|> List.map (fun tuple -> BatMap.String.bindings tuple.Concepts.Tuple.attributes)
|> List.sort compare )
+ let instantiate_a_program conn =
+ let projected =
+ begin
+ let open Utilities.Result in
+ let* employees = H.relation conn ["name"; "age"] [employee "Alaric" 42] in
+ let root = Kernel.Prototype.(mixture [Directory.of_properties ["employee", employees]]) in
+ let* plan =
+ Rnt.Evaluators.FOL.(
+ instantiate (Kernel.Path.lookup root)
+ (Project (Base Kernel.Path.("employee" @/ this), BatFingerTree.singleton "name")) )
+ in
+ let* evaluator = Protocols.Evaluator.require (Rnt.Evaluators.FOL.make ()) in
+ let* result = Rnt.Evaluators.FOL.program plan |> Protocols.Evaluator.invoke evaluator in
+ drain result
+ end
+ |> Helpers.condition_as_failure
+ in
+ check
+ (list (list (pair string Helpers.value)))
+ "the program ran over the relation its path resolved to"
+ [["name", Concepts.Value.String "Alaric"]]
+ (projected |> List.map (fun tuple -> BatMap.String.bindings tuple.Concepts.Tuple.attributes))
+
+ module E = Kernel.EphemeralRelation.Make (S)
+
+ let store conn term =
+ E.persist conn ~name:"view" ~evaluator:Rnt.Evaluators.FOL.name
+ ~code:(Rnt.Evaluators.FOL.encode term)
+ (BatMap.String.singleton "name" {Protocols.Schematics.domain= "string"; provenance= []})
+
+ let namespace entries =
+ let open Utilities.Result in
+ let root = Kernel.Namespace.make () in
+ let* registry = Protocols.Handle.require Protocols.Registry.from root in
+ let* _ =
+ List.fold_left
+ (fun registered (name, handle) ->
+ let* _ = registered in
+ Protocols.Registry.update registry name None (Some handle) )
+ (Ok true) entries
+ in
+ Ok root
+
+ let expand_a_stored_program conn =
+ let projected =
+ begin
+ let open Utilities.Result in
+ let* employees = H.relation conn ["name"; "age"] [employee "Alaric" 42] in
+ let* view =
+ store conn
+ Rnt.Evaluators.FOL.(
+ Project (Base Kernel.Path.("employee" @/ this), BatFingerTree.singleton "name") )
+ in
+ let* root = namespace ["employee", employees; "view", view] in
+ let* plan =
+ Rnt.Evaluators.FOL.(
+ instantiate (Kernel.Path.lookup root) (Base Kernel.Path.("view" @/ this)) )
+ in
+ let* evaluator = Protocols.Evaluator.require (Rnt.Evaluators.FOL.make ()) in
+ let* result = Rnt.Evaluators.FOL.program plan |> Protocols.Evaluator.invoke evaluator in
+ drain result
+ end
+ |> Helpers.condition_as_failure
+ in
+ check
+ (list (list (pair string Helpers.value)))
+ "the stored program ran in place of its name"
+ [["name", Concepts.Value.String "Alaric"]]
+ (projected |> List.map (fun tuple -> BatMap.String.bindings tuple.Concepts.Tuple.attributes))
+
+ let refuse_a_program_that_reads_itself conn =
+ let expanded =
+ begin
+ let open Utilities.Result in
+ let* view = store conn Rnt.Evaluators.FOL.(Base Kernel.Path.("view" @/ this)) in
+ let* root = namespace ["view", view] in
+ Rnt.Evaluators.FOL.(
+ instantiate (Kernel.Path.lookup root) (Base Kernel.Path.("view" @/ this)) )
+ end
+ in
+ check bool "the expansion stopped at the cycle" true
+ ( match expanded with
+ | Error condition ->
+ BatString.starts_with (Concepts.Condition.to_string_hum condition) "cyclic-program"
+ | Ok _ -> false )
+
let pull_one_tuple_at_a_time () =
let produced = ref 0 and closed = ref false in
let description =
@@ -102,7 +188,7 @@ module Make (S : Abstract.Storage.STORAGE) (C : Helpers.Storage.CONFIGURATOR) =
in
let source =
Kernel.EphemeralRelation.instantiate description
- {Kernel.EphemeralRelation.schematics= `Temporary description}
+ {Kernel.EphemeralRelation.name= None; schematics= `Temporary description; program= None}
(fun () -> Ok (Kernel.Generator.cursor_of ~finally:(fun () -> closed := true) (count 0)))
in
let first =
@@ -130,6 +216,12 @@ module Make (S : Abstract.Storage.STORAGE) (C : Helpers.Storage.CONFIGURATOR) =
[ test_case "scan-a-base-relation" `Quick (H.with_connection scan_a_base_relation "fol-test");
test_case "project-away-an-attribute" `Quick
(H.with_connection project_away_an_attribute "fol-test");
+ test_case "instantiate-a-program" `Quick
+ (H.with_connection instantiate_a_program "fol-test");
+ test_case "expand-a-stored-program" `Quick
+ (H.with_connection expand_a_stored_program "fol-test");
+ test_case "refuse-a-program-that-reads-itself" `Quick
+ (H.with_connection refuse_a_program_that_reads_itself "fol-test");
test_case "pull-one-tuple-at-a-time" `Quick pull_one_tuple_at_a_time ] )
end
diff --git a/test/unit/kernel/EphemeralRelation.ml b/test/unit/kernel/EphemeralRelation.ml
index 95ce56d..7f113ef 100644
--- a/test/unit/kernel/EphemeralRelation.ml
+++ b/test/unit/kernel/EphemeralRelation.ml
@@ -12,10 +12,11 @@ let description =
{ Protocols.Schematics.domain= "integer";
provenance= [{Protocols.Schematics.source= ["example"]; attribute= "value"}] }
-let over ?inputs members =
- Ephemeral.instantiate ?inputs description
- {Ephemeral.schematics= `Temporary description}
- (fun () -> Ok (Rnt.Kernel.Generator.cursor_of (fun ~yield -> List.iter yield members; Ok ())))
+let temporary = {Ephemeral.name= None; schematics= `Temporary description; program= None}
+
+let over ?inputs ?(value = temporary) members =
+ Ephemeral.instantiate ?inputs description value (fun () ->
+ Ok (Rnt.Kernel.Generator.cursor_of (fun ~yield -> List.iter yield members; Ok ())) )
let values tuples =
BatFingerTree.to_list tuples
@@ -78,6 +79,20 @@ let describes_itself () =
^ origin.Protocols.Schematics.attribute ) ) )
| _ -> fail "an ephemeral relation describes itself as a relation"
+let addressed_once_persisted () =
+ let persisted code =
+ { Ephemeral.name= Some "example";
+ schematics= `Persisted (Concepts.Hash.hash_of_int 1);
+ program= Some {Ephemeral.evaluator= "fol"; code= Concepts.Hash.hash_of_int code} }
+ in
+ let address value =
+ Protocols.Addressable.from (over ~value []) |> Option.map Protocols.Addressable.address
+ in
+ check bool "a temporary relation has no address" true (Option.is_none (address temporary));
+ check bool "a persisted one has" true (Option.is_some (address (persisted 2)));
+ check bool "and its program is part of it" false
+ (Option.equal Concepts.Hash.hash_equals (address (persisted 2)) (address (persisted 3)))
+
let releasing_releases_its_inputs () =
let released = ref false in
let input =
@@ -99,4 +114,5 @@ let suites () =
[ test_case "enumerates-every-member" `Quick enumerates_every_member;
test_case "decides-membership" `Quick decides_membership;
test_case "describes-itself" `Quick describes_itself;
+ test_case "addressed-once-persisted" `Quick addressed_once_persisted;
test_case "releasing-releases-its-inputs" `Quick releasing_releases_its_inputs ] ) ]