{-# LANGUAGE OverloadedStrings #-} module UnificationTest (tests) where import qualified Convex.Action.Parser as Action import qualified Convex.Parser as Parser import qualified Convex.Schema.Parser as Schema import Test.HUnit testUnifyWithTableDoc :: Test testUnifyWithTableDoc = "unifies function return with table doc" ~: TestCase $ do let schemaContent = unlines [ "import { defineSchema, defineTable } from \"convex/server\";", "import { v } from \"convex/values\";", "", "export default defineSchema({", " users: defineTable({", " name: v.string(),", " email: v.string()", " })", "});" ] let apiFileContent = unlines [ "declare const fullApi: ApiFromModules<{", " \"myActions\": typeof myActions;", "}>;" ] let actionContent = unlines [ "export declare const getUser: import(\"convex/server\").RegisteredQuery<\"public\", {}, Promise<{ _id: import(\"convex/values\").GenericId<\"users\">; _creationTime: number; name: string; email: string; }>>;" ] let actionContents = [("myActions", actionContent)] result <- Parser.parseProjectFromContents schemaContent apiFileContent actionContents case result of Left err -> assertFailure ("Parser failed: " ++ show err) Right project -> let expected = [ Action.ConvexFunction { Action.funcName = "getUser", Action.funcPath = "myActions", Action.funcType = Action.Query, Action.funcArgs = [], Action.funcReturn = Schema.VReference "UsersDoc" } ] in Parser.ppFunctions project @?= expected testUnifyWithNestedObject :: Test testUnifyWithNestedObject = "unifies function return with nested object" ~: TestCase $ do let schemaContent = unlines [ "import { defineSchema, defineTable } from \"convex/server\";", "import { v } from \"convex/values\";", "", "export default defineSchema({", " users: defineTable({", " name: v.string(),", " profile: v.object({", " image: v.string()", " })", " })", "});" ] let apiFileContent = unlines [ "declare const fullApi: ApiFromModules<{", " \"myActions\": typeof myActions;", "}>;" ] let actionContent = unlines [ "export declare const getUser: import(\"convex/server\").RegisteredQuery<\"public\", {}, Promise<{ _id: import(\"convex/values\").GenericId<\"users\">; _creationTime: number; name: string; profile: { image: string; }; }>>;" ] let actionContents = [("myActions", actionContent)] result <- Parser.parseProjectFromContents schemaContent apiFileContent actionContents case result of Left err -> assertFailure ("Parser failed: " ++ show err) Right project -> let expected = [ Action.ConvexFunction { Action.funcName = "getUser", Action.funcPath = "myActions", Action.funcType = Action.Query, Action.funcArgs = [], Action.funcReturn = Schema.VReference "UsersDoc" } ] in Parser.ppFunctions project @?= expected testUnifyWithArrayOfDocs :: Test testUnifyWithArrayOfDocs = "unifies function returning an array of docs" ~: TestCase $ do let schemaContent = unlines [ "import { defineSchema, defineTable } from \"convex/server\";", "import { v } from \"convex/values\";", "", "export default defineSchema({", " users: defineTable({", " name: v.string(),", " email: v.string()", " })", "});" ] let apiFileContent = unlines [ "declare const fullApi: ApiFromModules<{", " \"myActions\": typeof myActions;", "}>;" ] let actionContent = unlines [ "export declare const listUsers: import(\"convex/server\").RegisteredQuery<\"public\", {}, Promise<{", " _id: import(\"convex/values\").GenericId<\"users\">;", " _creationTime: number;", " name: string;", " email: string;", "}[]>>;" ] let actionContents = [("myActions", actionContent)] result <- Parser.parseProjectFromContents schemaContent apiFileContent actionContents case result of Left err -> assertFailure ("Parser failed: " ++ show err) Right project -> let expected = [ Action.ConvexFunction { Action.funcName = "listUsers", Action.funcPath = "myActions", Action.funcType = Action.Query, Action.funcArgs = [], Action.funcReturn = Schema.VArray (Schema.VReference "UsersDoc") } ] in Parser.ppFunctions project @?= expected testUnifyWithDeeplyNestedObject :: Test testUnifyWithDeeplyNestedObject = "unifies function return with deeply nested object" ~: TestCase $ do let schemaContent = unlines [ "import { defineSchema, defineTable } from \"convex/server\";", "import { v } from \"convex/values\";", "", "export default defineSchema({", " users: defineTable({", " name: v.string(),", " profile: v.object({", " image: v.string(),", " details: v.object({", " bio: v.string()", " })", " })", " })", "});" ] let apiFileContent = unlines [ "declare const fullApi: ApiFromModules<{", " \"myActions\": typeof myActions;", "}>;" ] let actionContent = unlines [ "export declare const getUser: import(\"convex/server\").RegisteredQuery<\"public\", {}, Promise<{ _id: import(\"convex/values\").GenericId<\"users\">; _creationTime: number; name: string; profile: { image: string; details: { bio: string; } }; }>>;" ] let actionContents = [("myActions", actionContent)] result <- Parser.parseProjectFromContents schemaContent apiFileContent actionContents case result of Left err -> assertFailure ("Parser failed: " ++ show err) Right project -> let expected = [ Action.ConvexFunction { Action.funcName = "getUser", Action.funcPath = "myActions", Action.funcType = Action.Query, Action.funcArgs = [], Action.funcReturn = Schema.VReference "UsersDoc" } ] in Parser.ppFunctions project @?= expected tests :: Test tests = "Unification" ~: test [ testUnifyWithTableDoc, testUnifyWithNestedObject, testUnifyWithArrayOfDocs, testUnifyWithDeeplyNestedObject, testUnifyWithShuffledFields ] testUnifyWithShuffledFields :: Test testUnifyWithShuffledFields = "unifies function return with shuffled fields" ~: TestCase $ do let schemaContent = unlines [ "import { defineSchema, defineTable } from \"convex/server\";", "import { v } from \"convex/values\";", "", "export default defineSchema({", " users: defineTable({", " name: v.string(),", " email: v.string()", " })", "});" ] let apiFileContent = unlines [ "declare const fullApi: ApiFromModules<{", " \"myActions\": typeof myActions;", "}>;" ] let actionContent = unlines -- Note the shuffled fields: email, name instead of name, email [ "export declare const getUser: import(\"convex/server\").RegisteredQuery<\"public\", {}, Promise<{ _id: import(\"convex/values\").GenericId<\"users\">; _creationTime: number; email: string; name: string; }>>;" ] let actionContents = [("myActions", actionContent)] result <- Parser.parseProjectFromContents schemaContent apiFileContent actionContents case result of Left err -> assertFailure ("Parser failed: " ++ show err) Right project -> let expected = [ Action.ConvexFunction { Action.funcName = "getUser", Action.funcPath = "myActions", Action.funcType = Action.Query, Action.funcArgs = [], Action.funcReturn = Schema.VReference "UsersDoc" } ] in Parser.ppFunctions project @?= expected