{- Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. -} {-# LANGUAGE TypeApplications #-} module ApiTest (main) where import Control.Exception import Data.ByteString (ByteString) import Data.Text (Text) import Glean.Query.Angle import Glean.Query.Thrift import Glean.Init import qualified Glean.Schema.GleanTest.Types as Glean.Test import Glean.Types import Test.HUnit import TestRunner import TestDB main :: IO () main = withUnitTest $ testRunner $ TestList [ TestLabel "angle DSL" angleDSL ] angleDSL :: Test angleDSL = dbTestCase $ \env repo -> do results <- runQuery env repo $ query $ predicate @Glean.Test.Predicate $ rec $ field @"string_" "acca" $ field @"nat" (nat 42) $ field @"array_of_nat" (array [nat 3, nat 4, nat 5]) $ field @"bool_" false end assertEqual "angle - DSL 0" 1 (length results) results <- runQuery env repo $ query $ var $ \p -> p `where_` [ wild .= predicate @Glean.Test.Predicate ( rec $ field @"sum_" ( alt @"c" (asPredicate p)) end) , p .= predicate @Glean.Test.Predicate ( rec $ field @"string_" "abba" end) ] assertEqual "angle - DSL 1" 1 (length results) results <- runQuery env repo $ query $ predicate @Glean.Test.Tree $ rec $ field @"left" (just wild) $ field @"right" nothing end assertEqual "angle - DSL 2" 1 (length results) results <- runQuery_ env repo $ query $ vars $ \x y -> tuple (x,y) `where_` [ x .= nat 1, y .= nat 2 ] assertEqual "angle - DSL 3" [(Nat 1, Nat 2)] results results <- runQuery_ env repo $ query $ vars $ \x -> x `where_` [ x .= elementsOf (array [nat 1, nat 2, nat 3 ]), not_ [x .= (nat 1 .| nat 3)] ] assertEqual "angle - DSL 4" [Nat 2] results -- This is just a compile test, inference should not fail with an -- ambiguous type error. _results <- runQuery_ env repo $ query $ vars $ \(x :: Angle Text) -> x `where_` [ wild .= predicate @Glean.Test.Node (rec $ field @"label" x end) ] results <- runQuery_ env repo $ query $ var $ \p -> p `where_` [p .= sig (never @Glean.Test.Predicate)] assertEqual "angle - DSL 4" 0 (length results) results <- runQuery_ env repo $ query @((), Bool, Text) $ var $ \p -> p `where_` [ wild .= sig (wild @Glean.Test.Predicate) , wild .= sig unit , wild .= sig true , wild .= sig (string "a") , wild .= sig (nat 1) , wild .= sig @Glean.Test.Sum (alt @"wed" true) , wild .= sig (array [nat 1, nat 2]) , wild .= sig (nothing :: Angle (Maybe Glean.Test.Predicate)) , wild .= sig (tuple (unit, true)) , p .= sig (tuple (unit, true, string "a")) ] assertEqual "angle - DSL type signatures" 1 (length results) -- test for a bug in which RecordFields and SumFields gave the wrong -- type for a predicate nested inside an array or maybe type. results <- runQuery_ env repo $ query @[Glean.Test.Predicate] $ var $ \p -> p `where_` [ wild .= predicate @Glean.Test.Predicate ( rec $ field @"array_of_pred" p end) ] assertEqual "angle - DSL 5" 2 (length (concat results)) -- test for type inference with the DSL. If we don't tell the compiler -- what type we're expecting for the variable `p` it will assume -- the type of the field (Sys.Blob) rather than the key type (ByteString) -- and we'll get a deserialization error. r <- try $ runQuery_ env repo $ query @(ByteString,ByteString) $ var $ \p -> tuple (p,p) `where_` [ wild .= predicate @Glean.Test.Predicate ( rec $ field @"pred" p end) ] print r assertBool "angle - DSL 6" $ case r of Left BadQuery{} -> True _ -> False -- Test signatures around `elementsOf`. T192115813 r <- runQuery_ env repo $ query @Nat $ sig (elementsOf (array [nat 1, nat 2])) print r assertEqual "angle - sig elementsOf" r [Nat 1, Nat 2] -- Test "expanding" r <- runQuery_ env repo $ keys $ expanding @Glean.Test.Node $ query @Glean.Test.Tree $ predicate @Glean.Test.Tree ( rec $ field @"node" (rec $ field @"label" "a" end) end) print r assertBool "angle - expanding" $ case r of [Glean.Test.Tree_key { tree_key_node = Glean.Test.Node { node_key = Just{} } , tree_key_left = Just Glean.Test.Tree { tree_key = Nothing } , tree_key_right = Just Glean.Test.Tree { tree_key = Nothing } }] -> True _ -> False r <- runQuery_ env repo $ query $ var $ \x -> zipp x x `where_` [ stmt $ predicate @Glean.Test.Predicate ( rec $ field @"nat" (nat 42) $ field @"array_of_nat" x end) ] print r assertEqual "angle - DSL zip" [[(Nat 1, Nat 1),(Nat 2, Nat 2)]] r r <- runQuery_ env repo $ query $ var $ \x -> conc x x `where_` [ stmt $ predicate @Glean.Test.Predicate ( rec $ field @"nat" (nat 42) $ field @"array_of_nat" x end ) ] print r assertEqual "concat" [[Nat 1, Nat 2, Nat 1, Nat 2]] r