KevinStephenson
Adding in weaviate code
b110593
raw
history blame
11.5 kB
// _ _
// __ _____ __ ___ ___ __ _| |_ ___
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
// \ V V / __/ (_| |\ V /| | (_| | || __/
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
//
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
//
// CONTACT: [email protected]
//
package test
import (
"fmt"
"testing"
"github.com/go-openapi/strfmt"
"github.com/weaviate/weaviate/client/objects"
clschema "github.com/weaviate/weaviate/client/schema"
"github.com/weaviate/weaviate/entities/models"
"github.com/weaviate/weaviate/entities/schema"
"github.com/weaviate/weaviate/test/helper"
testhelper "github.com/weaviate/weaviate/test/helper"
)
var (
// contextual
article1 strfmt.UUID = "dcbe5df8-af01-46f1-b45f-bcc9a7a0773d" // apple macbook
article2 strfmt.UUID = "6a8c7b62-fd45-488f-b884-ec87227f6eb3" // ice cream and steak
article3 strfmt.UUID = "92f05097-6371-499c-a0fe-3e60ae16fe3d" // president of the us
// knn
recipeTypeSavory strfmt.UUID = "989d792c-b59e-4430-80a3-cf7f320f31b0"
recipeTypeSweet strfmt.UUID = "c9dfda02-6b05-4117-9d95-a188342cca48"
unclassifiedSavory strfmt.UUID = "953c03f8-d61e-44c0-bbf1-2afe0dc1ce87"
unclassifiedSweet strfmt.UUID = "04603002-cb66-4fce-bf6d-56bdf9b0b5d4"
// zeroshot
foodTypeMeat strfmt.UUID = "998d792c-b59e-4430-80a3-cf7f320f31b0"
foodTypeIceCream strfmt.UUID = "998d792c-b59e-4430-80a3-cf7f320f31b1"
unclassifiedSteak strfmt.UUID = "953c03f8-d61e-44c0-bbf1-2afe0dc1ce10"
unclassifiedIceCreams strfmt.UUID = "953c03f8-d61e-44c0-bbf1-2afe0dc1ce11"
)
func Test_Classifications(t *testing.T) {
t.Run("article/category setup for contextual classification", setupArticleCategory)
t.Run("recipe setup for knn classification", setupRecipe)
t.Run("food types and recipes setup for zeroshot classification", setupFoodTypes)
// tests
t.Run("contextual classification", contextualClassification)
t.Run("knn classification", knnClassification)
t.Run("zeroshot classification", zeroshotClassification)
// tear down
deleteObjectClass(t, "Article")
deleteObjectClass(t, "Category")
deleteObjectClass(t, "Recipe")
deleteObjectClass(t, "RecipeType")
deleteObjectClass(t, "FoodType")
deleteObjectClass(t, "Recipes")
}
func setupArticleCategory(t *testing.T) {
t.Run("schema setup", func(t *testing.T) {
createObjectClass(t, &models.Class{
Class: "Category",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "name",
DataType: schema.DataTypeText.PropString(),
Tokenization: models.PropertyTokenizationWhitespace,
},
},
})
createObjectClass(t, &models.Class{
Class: "Article",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "content",
DataType: []string{"text"},
},
{
Name: "OfCategory",
DataType: []string{"Category"},
},
},
})
})
t.Run("object setup - categories", func(t *testing.T) {
createObject(t, &models.Object{
Class: "Category",
Properties: map[string]interface{}{
"name": "Food and Drink",
},
})
createObject(t, &models.Object{
Class: "Category",
Properties: map[string]interface{}{
"name": "Computers and Technology",
},
})
createObject(t, &models.Object{
Class: "Category",
Properties: map[string]interface{}{
"name": "Politics",
},
})
})
t.Run("object setup - articles", func(t *testing.T) {
createObject(t, &models.Object{
ID: article1,
Class: "Article",
Properties: map[string]interface{}{
"content": "The new Apple Macbook 16 inch provides great performance",
},
})
createObject(t, &models.Object{
ID: article2,
Class: "Article",
Properties: map[string]interface{}{
"content": "I love eating ice cream with my t-bone steak",
},
})
createObject(t, &models.Object{
ID: article3,
Class: "Article",
Properties: map[string]interface{}{
"content": "Barack Obama was the 44th president of the united states",
},
})
})
assertGetObjectEventually(t, "92f05097-6371-499c-a0fe-3e60ae16fe3d")
}
func setupRecipe(t *testing.T) {
t.Run("schema setup", func(t *testing.T) {
createObjectClass(t, &models.Class{
Class: "RecipeType",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "name",
DataType: schema.DataTypeText.PropString(),
Tokenization: models.PropertyTokenizationWhitespace,
},
},
})
createObjectClass(t, &models.Class{
Class: "Recipe",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "content",
DataType: []string{"text"},
},
{
Name: "OfType",
DataType: []string{"RecipeType"},
},
},
})
})
t.Run("object setup - recipe types", func(t *testing.T) {
createObject(t, &models.Object{
Class: "RecipeType",
ID: recipeTypeSavory,
Properties: map[string]interface{}{
"name": "Savory",
},
})
createObject(t, &models.Object{
Class: "RecipeType",
ID: recipeTypeSweet,
Properties: map[string]interface{}{
"name": "Sweet",
},
})
})
t.Run("object setup - articles", func(t *testing.T) {
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Mix two eggs with milk and 7 grams of sugar, bake in the oven at 200 degrees",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSweet),
},
},
},
})
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Sautee the apples with sugar and add a dash of milk.",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSweet),
},
},
},
})
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Mix butter, cream and sugar. Make eggwhites fluffy and mix with the batter",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSweet),
},
},
},
})
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Fry the steak in the pan, then sautee the onions in the same pan",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSavory),
},
},
},
})
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Cut the potatoes in half and add salt and pepper. Serve with the meat.",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSavory),
},
},
},
})
createObject(t, &models.Object{
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Put the pasta and sauce mix in the oven, top with plenty of cheese",
"ofType": []interface{}{
map[string]interface{}{
"beacon": fmt.Sprintf("weaviate://localhost/%s", recipeTypeSavory),
},
},
},
})
createObject(t, &models.Object{
ID: unclassifiedSavory,
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Serve the steak with fries and ketchup.",
},
})
createObject(t, &models.Object{
ID: unclassifiedSweet,
Class: "Recipe",
Properties: map[string]interface{}{
"content": "Whisk the cream, add sugar and serve with strawberries",
},
})
})
assertGetObjectEventually(t, unclassifiedSweet)
}
func setupFoodTypes(t *testing.T) {
t.Run("schema setup", func(t *testing.T) {
createObjectClass(t, &models.Class{
Class: "FoodType",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "text",
DataType: schema.DataTypeText.PropString(),
Tokenization: models.PropertyTokenizationWhitespace,
},
},
})
createObjectClass(t, &models.Class{
Class: "Recipes",
ModuleConfig: map[string]interface{}{
"text2vec-contextionary": map[string]interface{}{
"vectorizeClassName": true,
},
},
Properties: []*models.Property{
{
Name: "text",
DataType: []string{"text"},
},
{
Name: "ofFoodType",
DataType: []string{"FoodType"},
},
},
})
})
t.Run("object setup - food types", func(t *testing.T) {
createObject(t, &models.Object{
Class: "FoodType",
ID: foodTypeIceCream,
Properties: map[string]interface{}{
"text": "Ice cream",
},
})
createObject(t, &models.Object{
Class: "FoodType",
ID: foodTypeMeat,
Properties: map[string]interface{}{
"text": "Meat",
},
})
})
t.Run("object setup - recipes", func(t *testing.T) {
createObject(t, &models.Object{
Class: "Recipes",
ID: unclassifiedSteak,
Properties: map[string]interface{}{
"text": "Cut the steak in half and put it into pan",
},
})
createObject(t, &models.Object{
Class: "Recipes",
ID: unclassifiedIceCreams,
Properties: map[string]interface{}{
"text": "There are flavors of vanilla, chocolate and strawberry",
},
})
})
}
func createObjectClass(t *testing.T, class *models.Class) {
params := clschema.NewSchemaObjectsCreateParams().WithObjectClass(class)
resp, err := helper.Client(t).Schema.SchemaObjectsCreate(params, nil)
helper.AssertRequestOk(t, resp, err, nil)
}
func createObject(t *testing.T, object *models.Object) {
params := objects.NewObjectsCreateParams().WithBody(object)
resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
helper.AssertRequestOk(t, resp, err, nil)
}
func deleteObjectClass(t *testing.T, class string) {
delParams := clschema.NewSchemaObjectsDeleteParams().WithClassName(class)
delRes, err := helper.Client(t).Schema.SchemaObjectsDelete(delParams, nil)
helper.AssertRequestOk(t, delRes, err, nil)
}
func assertGetObjectEventually(t *testing.T, uuid strfmt.UUID) *models.Object {
var (
resp *objects.ObjectsGetOK
err error
)
checkThunk := func() interface{} {
resp, err = helper.Client(t).Objects.ObjectsGet(objects.NewObjectsGetParams().WithID(uuid), nil)
return err == nil
}
testhelper.AssertEventuallyEqual(t, true, checkThunk)
var object *models.Object
helper.AssertRequestOk(t, resp, err, func() {
object = resp.Payload
})
return object
}