github.com/weaviate/weaviate@v1.24.6/usecases/objects/fakes_for_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package objects 13 14 import ( 15 "context" 16 "fmt" 17 "net/http" 18 19 "github.com/go-openapi/strfmt" 20 "github.com/pkg/errors" 21 "github.com/sirupsen/logrus" 22 "github.com/stretchr/testify/mock" 23 "github.com/tailor-inc/graphql" 24 "github.com/tailor-inc/graphql/language/ast" 25 "github.com/weaviate/weaviate/adapters/handlers/graphql/descriptions" 26 "github.com/weaviate/weaviate/entities/additional" 27 "github.com/weaviate/weaviate/entities/filters" 28 "github.com/weaviate/weaviate/entities/models" 29 "github.com/weaviate/weaviate/entities/modulecapabilities" 30 "github.com/weaviate/weaviate/entities/moduletools" 31 "github.com/weaviate/weaviate/entities/schema" 32 "github.com/weaviate/weaviate/entities/schema/crossref" 33 "github.com/weaviate/weaviate/entities/search" 34 "github.com/weaviate/weaviate/entities/vectorindex/hnsw" 35 ) 36 37 const FindObjectFn = "func(context.Context, string, strfmt.UUID, " + 38 "search.SelectProperties, additional.Properties, string) (*search.Result, error)" 39 40 type fakeSchemaManager struct { 41 CalledWith struct { 42 fromClass string 43 property string 44 toClass string 45 } 46 GetSchemaResponse schema.Schema 47 GetschemaErr error 48 } 49 50 func (f *fakeSchemaManager) UpdatePropertyAddDataType(ctx context.Context, principal *models.Principal, 51 fromClass, property, toClass string, 52 ) error { 53 f.CalledWith = struct { 54 fromClass string 55 property string 56 toClass string 57 }{ 58 fromClass: fromClass, 59 property: property, 60 toClass: toClass, 61 } 62 return nil 63 } 64 65 func (f *fakeSchemaManager) GetSchema(principal *models.Principal) (schema.Schema, error) { 66 return f.GetSchemaResponse, f.GetschemaErr 67 } 68 69 func (f *fakeSchemaManager) ShardOwner(class, shard string) (string, error) { return "", nil } 70 func (f *fakeSchemaManager) TenantShard(class, tenant string) string { return tenant } 71 func (f *fakeSchemaManager) ShardFromUUID(class string, uuid []byte) string { return "" } 72 73 func (f *fakeSchemaManager) GetClass(ctx context.Context, principal *models.Principal, 74 name string, 75 ) (*models.Class, error) { 76 classes := f.GetSchemaResponse.Objects.Classes 77 for _, class := range classes { 78 if class.Class == name { 79 return class, f.GetschemaErr 80 } 81 } 82 return nil, f.GetschemaErr 83 } 84 85 func (f *fakeSchemaManager) AddClass(ctx context.Context, principal *models.Principal, 86 class *models.Class, 87 ) error { 88 if f.GetSchemaResponse.Objects == nil { 89 f.GetSchemaResponse.Objects = schema.Empty().Objects 90 } 91 class.VectorIndexConfig = hnsw.UserConfig{} 92 class.VectorIndexType = "hnsw" 93 class.Vectorizer = "none" 94 classes := f.GetSchemaResponse.Objects.Classes 95 if classes != nil { 96 classes = append(classes, class) 97 } else { 98 classes = []*models.Class{class} 99 } 100 f.GetSchemaResponse.Objects.Classes = classes 101 return nil 102 } 103 104 func (f *fakeSchemaManager) AddClassProperty(ctx context.Context, principal *models.Principal, 105 class string, property *models.Property, 106 ) error { 107 classes := f.GetSchemaResponse.Objects.Classes 108 for _, c := range classes { 109 if c.Class == class { 110 props := c.Properties 111 if props != nil { 112 props = append(props, property) 113 } else { 114 props = []*models.Property{property} 115 } 116 c.Properties = props 117 break 118 } 119 } 120 return nil 121 } 122 123 func (f *fakeSchemaManager) MergeClassObjectProperty(ctx context.Context, principal *models.Principal, 124 class string, property *models.Property, 125 ) error { 126 classes := f.GetSchemaResponse.Objects.Classes 127 for _, c := range classes { 128 if c.Class == class { 129 for i, prop := range c.Properties { 130 if prop.Name == property.Name { 131 c.Properties[i].NestedProperties, _ = schema.MergeRecursivelyNestedProperties( 132 c.Properties[i].NestedProperties, property.NestedProperties) 133 break 134 } 135 } 136 break 137 } 138 } 139 return nil 140 } 141 142 type fakeLocks struct { 143 Err error 144 } 145 146 func (f *fakeLocks) LockConnector() (func() error, error) { 147 return func() error { return nil }, f.Err 148 } 149 150 func (f *fakeLocks) LockSchema() (func() error, error) { 151 return func() error { return nil }, f.Err 152 } 153 154 type fakeAuthorizer struct { 155 Err error 156 } 157 158 func (f *fakeAuthorizer) Authorize(principal *models.Principal, verb, resource string) error { 159 return f.Err 160 } 161 162 type fakeVectorRepo struct { 163 mock.Mock 164 } 165 166 func (f *fakeVectorRepo) Exists(ctx context.Context, class string, id strfmt.UUID, repl *additional.ReplicationProperties, tenant string) (bool, error) { 167 args := f.Called(class, id) 168 return args.Bool(0), args.Error(1) 169 } 170 171 func (f *fakeVectorRepo) Object(ctx context.Context, cls string, id strfmt.UUID, 172 props search.SelectProperties, additional additional.Properties, 173 repl *additional.ReplicationProperties, tenant string, 174 ) (*search.Result, error) { 175 args := f.Called(cls, id, props, additional, tenant) 176 if args.Get(0) != nil { 177 return args.Get(0).(*search.Result), args.Error(1) 178 } 179 return nil, args.Error(1) 180 } 181 182 func (f *fakeVectorRepo) ObjectByID(ctx context.Context, id strfmt.UUID, 183 props search.SelectProperties, additional additional.Properties, 184 tenant string, 185 ) (*search.Result, error) { 186 args := f.Called(id, props, additional) 187 if args.Get(0) != nil { 188 return args.Get(0).(*search.Result), args.Error(1) 189 } 190 return nil, args.Error(1) 191 } 192 193 func (f *fakeVectorRepo) ObjectSearch(ctx context.Context, offset, limit int, filters *filters.LocalFilter, 194 sort []filters.Sort, additional additional.Properties, tenant string, 195 ) (search.Results, error) { 196 args := f.Called(offset, limit, sort, filters, additional) 197 return args.Get(0).([]search.Result), args.Error(1) 198 } 199 200 func (f *fakeVectorRepo) Query(ctx context.Context, q *QueryInput) (search.Results, *Error) { 201 args := f.Called(q) 202 res, err := args.Get(0).([]search.Result), args.Error(1).(*Error) 203 return res, err 204 } 205 206 func (f *fakeVectorRepo) PutObject(ctx context.Context, concept *models.Object, vector []float32, 207 vectors models.Vectors, repl *additional.ReplicationProperties, 208 ) error { 209 args := f.Called(concept, vector) 210 return args.Error(0) 211 } 212 213 func (f *fakeVectorRepo) BatchPutObjects(ctx context.Context, batch BatchObjects, 214 repl *additional.ReplicationProperties, 215 ) (BatchObjects, error) { 216 args := f.Called(batch) 217 return batch, args.Error(0) 218 } 219 220 func (f *fakeVectorRepo) AddBatchReferences(ctx context.Context, batch BatchReferences, 221 repl *additional.ReplicationProperties, 222 ) (BatchReferences, error) { 223 args := f.Called(batch) 224 return batch, args.Error(0) 225 } 226 227 func (f *fakeVectorRepo) BatchDeleteObjects(ctx context.Context, params BatchDeleteParams, 228 repl *additional.ReplicationProperties, tenant string, 229 ) (BatchDeleteResult, error) { 230 args := f.Called(params) 231 return args.Get(0).(BatchDeleteResult), args.Error(1) 232 } 233 234 func (f *fakeVectorRepo) Merge(ctx context.Context, merge MergeDocument, repl *additional.ReplicationProperties, tenant string) error { 235 args := f.Called(merge) 236 return args.Error(0) 237 } 238 239 func (f *fakeVectorRepo) DeleteObject(ctx context.Context, className string, 240 id strfmt.UUID, repl *additional.ReplicationProperties, tenant string, 241 ) error { 242 args := f.Called(className, id) 243 return args.Error(0) 244 } 245 246 func (f *fakeVectorRepo) AddReference(ctx context.Context, source *crossref.RefSource, 247 target *crossref.Ref, repl *additional.ReplicationProperties, tenant string, 248 ) error { 249 args := f.Called(source, target) 250 return args.Error(0) 251 } 252 253 func (f *fakeVectorRepo) ReferenceVectorSearch(ctx context.Context, 254 obj *models.Object, refProps map[string]struct{}, 255 ) ([][]float32, error) { 256 return nil, nil 257 } 258 259 type fakeExtender struct { 260 multi []search.Result 261 } 262 263 func (f *fakeExtender) AdditionalPropertyFn(ctx context.Context, 264 in []search.Result, params interface{}, limit *int, 265 argumentModuleParams map[string]interface{}, cfg moduletools.ClassConfig, 266 ) ([]search.Result, error) { 267 return f.multi, nil 268 } 269 270 func (f *fakeExtender) ExtractAdditionalFn(param []*ast.Argument) interface{} { 271 return nil 272 } 273 274 func (f *fakeExtender) AdditionalPropertyDefaultValue() interface{} { 275 return getDefaultParam("nearestNeighbors") 276 } 277 278 type fakeProjector struct { 279 multi []search.Result 280 } 281 282 func (f *fakeProjector) AdditionalPropertyFn(ctx context.Context, 283 in []search.Result, params interface{}, limit *int, 284 argumentModuleParams map[string]interface{}, cfg moduletools.ClassConfig, 285 ) ([]search.Result, error) { 286 return f.multi, nil 287 } 288 289 func (f *fakeProjector) ExtractAdditionalFn(param []*ast.Argument) interface{} { 290 return nil 291 } 292 293 func (f *fakeProjector) AdditionalPropertyDefaultValue() interface{} { 294 return getDefaultParam("featureProjection") 295 } 296 297 type fakePathBuilder struct { 298 multi []search.Result 299 } 300 301 func (f *fakePathBuilder) AdditionalPropertyFn(ctx context.Context, 302 in []search.Result, params interface{}, limit *int, 303 argumentModuleParams map[string]interface{}, cfg moduletools.ClassConfig, 304 ) ([]search.Result, error) { 305 return f.multi, nil 306 } 307 308 func (f *fakePathBuilder) ExtractAdditionalFn(param []*ast.Argument) interface{} { 309 return nil 310 } 311 312 func (f *fakePathBuilder) AdditionalPropertyDefaultValue() interface{} { 313 return getDefaultParam("semanticPath") 314 } 315 316 type fakeModulesProvider struct { 317 mock.Mock 318 customExtender *fakeExtender 319 customProjector *fakeProjector 320 } 321 322 func (p *fakeModulesProvider) GetObjectAdditionalExtend(ctx context.Context, 323 in *search.Result, moduleParams map[string]interface{}, 324 ) (*search.Result, error) { 325 res, err := p.additionalExtend(ctx, search.Results{*in}, moduleParams, "ObjectGet") 326 if err != nil { 327 return nil, err 328 } 329 return &res[0], nil 330 } 331 332 func (p *fakeModulesProvider) ListObjectsAdditionalExtend(ctx context.Context, 333 in search.Results, moduleParams map[string]interface{}, 334 ) (search.Results, error) { 335 return p.additionalExtend(ctx, in, moduleParams, "ObjectList") 336 } 337 338 func (p *fakeModulesProvider) UsingRef2Vec(moduleName string) bool { 339 args := p.Called(moduleName) 340 return args.Bool(0) 341 } 342 343 func (p *fakeModulesProvider) UpdateVector(ctx context.Context, object *models.Object, class *models.Class, 344 compFactory moduletools.PropsComparatorFactory, findObjFn modulecapabilities.FindObjectFn, logger logrus.FieldLogger, 345 ) error { 346 args := p.Called(object, findObjFn) 347 switch vec := args.Get(0).(type) { 348 case models.C11yVector: 349 object.Vector = vec 350 return args.Error(1) 351 case []float32: 352 object.Vector = vec 353 return args.Error(1) 354 default: 355 return args.Error(1) 356 } 357 } 358 359 func (p *fakeModulesProvider) VectorizerName(className string) (string, error) { 360 args := p.Called(className) 361 return args.String(0), args.Error(1) 362 } 363 364 func (p *fakeModulesProvider) additionalExtend(ctx context.Context, 365 in search.Results, moduleParams map[string]interface{}, capability string, 366 ) (search.Results, error) { 367 txt2vec := newNearCustomTextModule(p.getExtender(), p.getProjector(), &fakePathBuilder{}) 368 additionalProperties := txt2vec.AdditionalProperties() 369 if err := p.checkCapabilities(additionalProperties, moduleParams, capability); err != nil { 370 return nil, err 371 } 372 for name, value := range moduleParams { 373 additionalPropertyFn := p.getAdditionalPropertyFn(additionalProperties[name], capability) 374 if additionalPropertyFn != nil && value != nil { 375 resArray, err := additionalPropertyFn(ctx, in, nil, nil, nil, nil) 376 if err != nil { 377 return nil, err 378 } 379 in = resArray 380 } 381 } 382 return in, nil 383 } 384 385 func (p *fakeModulesProvider) checkCapabilities(additionalProperties map[string]modulecapabilities.AdditionalProperty, 386 moduleParams map[string]interface{}, capability string, 387 ) error { 388 for name := range moduleParams { 389 additionalPropertyFn := p.getAdditionalPropertyFn(additionalProperties[name], capability) 390 if additionalPropertyFn == nil { 391 return errors.Errorf("unknown capability: %s", name) 392 } 393 } 394 return nil 395 } 396 397 func (p *fakeModulesProvider) getAdditionalPropertyFn(additionalProperty modulecapabilities.AdditionalProperty, 398 capability string, 399 ) modulecapabilities.AdditionalPropertyFn { 400 switch capability { 401 case "ObjectGet": 402 return additionalProperty.SearchFunctions.ObjectGet 403 case "ObjectList": 404 return additionalProperty.SearchFunctions.ObjectList 405 case "ExploreGet": 406 return additionalProperty.SearchFunctions.ExploreGet 407 case "ExploreList": 408 return additionalProperty.SearchFunctions.ExploreList 409 default: 410 return nil 411 } 412 } 413 414 func (p *fakeModulesProvider) getExtender() *fakeExtender { 415 if p.customExtender != nil { 416 return p.customExtender 417 } 418 return &fakeExtender{} 419 } 420 421 func (p *fakeModulesProvider) getProjector() *fakeProjector { 422 if p.customProjector != nil { 423 return p.customProjector 424 } 425 return &fakeProjector{} 426 } 427 428 type nearCustomTextParams struct { 429 Values []string 430 MoveTo nearExploreMove 431 Certainty float64 432 } 433 434 type nearExploreMove struct { 435 Values []string 436 Force float32 437 Objects []nearObjectMove 438 } 439 440 type nearObjectMove struct { 441 ID string 442 Beacon string 443 } 444 445 type nearCustomTextModule struct { 446 fakeExtender *fakeExtender 447 fakeProjector *fakeProjector 448 fakePathBuilder *fakePathBuilder 449 } 450 451 func newNearCustomTextModule( 452 fakeExtender *fakeExtender, 453 fakeProjector *fakeProjector, 454 fakePathBuilder *fakePathBuilder, 455 ) *nearCustomTextModule { 456 return &nearCustomTextModule{fakeExtender, fakeProjector, fakePathBuilder} 457 } 458 459 func (m *nearCustomTextModule) Name() string { 460 return "mock-custom-near-text-module" 461 } 462 463 func (m *nearCustomTextModule) Init(params moduletools.ModuleInitParams) error { 464 return nil 465 } 466 467 func (m *nearCustomTextModule) RootHandler() http.Handler { 468 return nil 469 } 470 471 func (m *nearCustomTextModule) getNearCustomTextArgument(classname string) *graphql.ArgumentConfig { 472 prefix := classname 473 return &graphql.ArgumentConfig{ 474 Type: graphql.NewInputObject( 475 graphql.InputObjectConfig{ 476 Name: fmt.Sprintf("%sNearCustomTextInpObj", prefix), 477 Fields: graphql.InputObjectConfigFieldMap{ 478 "concepts": &graphql.InputObjectFieldConfig{ 479 Type: graphql.NewNonNull(graphql.NewList(graphql.String)), 480 }, 481 "moveTo": &graphql.InputObjectFieldConfig{ 482 Description: descriptions.VectorMovement, 483 Type: graphql.NewInputObject( 484 graphql.InputObjectConfig{ 485 Name: fmt.Sprintf("%sMoveTo", prefix), 486 Fields: graphql.InputObjectConfigFieldMap{ 487 "concepts": &graphql.InputObjectFieldConfig{ 488 Description: descriptions.Keywords, 489 Type: graphql.NewList(graphql.String), 490 }, 491 "objects": &graphql.InputObjectFieldConfig{ 492 Description: "objects", 493 Type: graphql.NewList(graphql.NewInputObject( 494 graphql.InputObjectConfig{ 495 Name: fmt.Sprintf("%sMovementObjectsInpObj", prefix), 496 Fields: graphql.InputObjectConfigFieldMap{ 497 "id": &graphql.InputObjectFieldConfig{ 498 Type: graphql.String, 499 Description: "id of an object", 500 }, 501 "beacon": &graphql.InputObjectFieldConfig{ 502 Type: graphql.String, 503 Description: descriptions.Beacon, 504 }, 505 }, 506 Description: "Movement Object", 507 }, 508 )), 509 }, 510 "force": &graphql.InputObjectFieldConfig{ 511 Description: descriptions.Force, 512 Type: graphql.NewNonNull(graphql.Float), 513 }, 514 }, 515 }), 516 }, 517 "certainty": &graphql.InputObjectFieldConfig{ 518 Description: descriptions.Certainty, 519 Type: graphql.Float, 520 }, 521 }, 522 Description: descriptions.GetWhereInpObj, 523 }, 524 ), 525 } 526 } 527 528 func (m *nearCustomTextModule) extractNearCustomTextArgument(source map[string]interface{}) *nearCustomTextParams { 529 var args nearCustomTextParams 530 531 concepts := source["concepts"].([]interface{}) 532 args.Values = make([]string, len(concepts)) 533 for i, value := range concepts { 534 args.Values[i] = value.(string) 535 } 536 537 certainty, ok := source["certainty"] 538 if ok { 539 args.Certainty = certainty.(float64) 540 } 541 542 // moveTo is an optional arg, so it could be nil 543 moveTo, ok := source["moveTo"] 544 if ok { 545 moveToMap := moveTo.(map[string]interface{}) 546 res := nearExploreMove{} 547 res.Force = float32(moveToMap["force"].(float64)) 548 549 concepts, ok := moveToMap["concepts"].([]interface{}) 550 if ok { 551 res.Values = make([]string, len(concepts)) 552 for i, value := range concepts { 553 res.Values[i] = value.(string) 554 } 555 } 556 557 objects, ok := moveToMap["objects"].([]interface{}) 558 if ok { 559 res.Objects = make([]nearObjectMove, len(objects)) 560 for i, value := range objects { 561 v, ok := value.(map[string]interface{}) 562 if ok { 563 if v["id"] != nil { 564 res.Objects[i].ID = v["id"].(string) 565 } 566 if v["beacon"] != nil { 567 res.Objects[i].Beacon = v["beacon"].(string) 568 } 569 } 570 } 571 } 572 573 args.MoveTo = res 574 } 575 576 return &args 577 } 578 579 func (m *nearCustomTextModule) Arguments() map[string]modulecapabilities.GraphQLArgument { 580 arguments := map[string]modulecapabilities.GraphQLArgument{} 581 // define nearCustomText argument 582 arguments["nearCustomText"] = modulecapabilities.GraphQLArgument{ 583 GetArgumentsFunction: func(classname string) *graphql.ArgumentConfig { 584 return m.getNearCustomTextArgument(classname) 585 }, 586 ExtractFunction: func(source map[string]interface{}) interface{} { 587 return m.extractNearCustomTextArgument(source) 588 }, 589 ValidateFunction: func(param interface{}) error { 590 // all is valid 591 return nil 592 }, 593 } 594 return arguments 595 } 596 597 // additional properties 598 func (m *nearCustomTextModule) AdditionalProperties() map[string]modulecapabilities.AdditionalProperty { 599 additionalProperties := map[string]modulecapabilities.AdditionalProperty{} 600 additionalProperties["featureProjection"] = m.getFeatureProjection() 601 additionalProperties["nearestNeighbors"] = m.getNearestNeighbors() 602 additionalProperties["semanticPath"] = m.getSemanticPath() 603 return additionalProperties 604 } 605 606 func (m *nearCustomTextModule) getFeatureProjection() modulecapabilities.AdditionalProperty { 607 return modulecapabilities.AdditionalProperty{ 608 DefaultValue: m.fakeProjector.AdditionalPropertyDefaultValue(), 609 GraphQLNames: []string{"featureProjection"}, 610 GraphQLFieldFunction: func(classname string) *graphql.Field { 611 return &graphql.Field{ 612 Args: graphql.FieldConfigArgument{ 613 "algorithm": &graphql.ArgumentConfig{ 614 Type: graphql.String, 615 DefaultValue: nil, 616 }, 617 "dimensions": &graphql.ArgumentConfig{ 618 Type: graphql.Int, 619 DefaultValue: nil, 620 }, 621 "learningRate": &graphql.ArgumentConfig{ 622 Type: graphql.Int, 623 DefaultValue: nil, 624 }, 625 "iterations": &graphql.ArgumentConfig{ 626 Type: graphql.Int, 627 DefaultValue: nil, 628 }, 629 "perplexity": &graphql.ArgumentConfig{ 630 Type: graphql.Int, 631 DefaultValue: nil, 632 }, 633 }, 634 Type: graphql.NewObject(graphql.ObjectConfig{ 635 Name: fmt.Sprintf("%sAdditionalFeatureProjection", classname), 636 Fields: graphql.Fields{ 637 "vector": &graphql.Field{Type: graphql.NewList(graphql.Float)}, 638 }, 639 }), 640 } 641 }, 642 GraphQLExtractFunction: m.fakeProjector.ExtractAdditionalFn, 643 SearchFunctions: modulecapabilities.AdditionalSearch{ 644 ObjectList: m.fakeProjector.AdditionalPropertyFn, 645 ExploreGet: m.fakeProjector.AdditionalPropertyFn, 646 ExploreList: m.fakeProjector.AdditionalPropertyFn, 647 }, 648 } 649 } 650 651 func (m *nearCustomTextModule) getNearestNeighbors() modulecapabilities.AdditionalProperty { 652 return modulecapabilities.AdditionalProperty{ 653 DefaultValue: m.fakeExtender.AdditionalPropertyDefaultValue(), 654 GraphQLNames: []string{"nearestNeighbors"}, 655 GraphQLFieldFunction: func(classname string) *graphql.Field { 656 return &graphql.Field{ 657 Type: graphql.NewObject(graphql.ObjectConfig{ 658 Name: fmt.Sprintf("%sAdditionalNearestNeighbors", classname), 659 Fields: graphql.Fields{ 660 "neighbors": &graphql.Field{Type: graphql.NewList(graphql.NewObject(graphql.ObjectConfig{ 661 Name: fmt.Sprintf("%sAdditionalNearestNeighborsNeighbors", classname), 662 Fields: graphql.Fields{ 663 "concept": &graphql.Field{Type: graphql.String}, 664 "distance": &graphql.Field{Type: graphql.Float}, 665 }, 666 }))}, 667 }, 668 }), 669 } 670 }, 671 GraphQLExtractFunction: m.fakeExtender.ExtractAdditionalFn, 672 SearchFunctions: modulecapabilities.AdditionalSearch{ 673 ObjectGet: m.fakeExtender.AdditionalPropertyFn, 674 ObjectList: m.fakeExtender.AdditionalPropertyFn, 675 ExploreGet: m.fakeExtender.AdditionalPropertyFn, 676 ExploreList: m.fakeExtender.AdditionalPropertyFn, 677 }, 678 } 679 } 680 681 func (m *nearCustomTextModule) getSemanticPath() modulecapabilities.AdditionalProperty { 682 return modulecapabilities.AdditionalProperty{ 683 DefaultValue: m.fakePathBuilder.AdditionalPropertyDefaultValue(), 684 GraphQLNames: []string{"semanticPath"}, 685 GraphQLFieldFunction: func(classname string) *graphql.Field { 686 return &graphql.Field{ 687 Type: graphql.NewObject(graphql.ObjectConfig{ 688 Name: fmt.Sprintf("%sAdditionalSemanticPath", classname), 689 Fields: graphql.Fields{ 690 "path": &graphql.Field{Type: graphql.NewList(graphql.NewObject(graphql.ObjectConfig{ 691 Name: fmt.Sprintf("%sAdditionalSemanticPathElement", classname), 692 Fields: graphql.Fields{ 693 "concept": &graphql.Field{Type: graphql.String}, 694 "distanceToQuery": &graphql.Field{Type: graphql.Float}, 695 "distanceToResult": &graphql.Field{Type: graphql.Float}, 696 "distanceToNext": &graphql.Field{Type: graphql.Float}, 697 "distanceToPrevious": &graphql.Field{Type: graphql.Float}, 698 }, 699 }))}, 700 }, 701 }), 702 } 703 }, 704 GraphQLExtractFunction: m.fakePathBuilder.ExtractAdditionalFn, 705 SearchFunctions: modulecapabilities.AdditionalSearch{ 706 ExploreGet: m.fakePathBuilder.AdditionalPropertyFn, 707 }, 708 } 709 } 710 711 type fakeParams struct{} 712 713 func getDefaultParam(name string) interface{} { 714 switch name { 715 case "featureProjection", "semanticPath": 716 return &fakeParams{} 717 case "nearestNeighbors": 718 return true 719 default: 720 return nil 721 } 722 } 723 724 func getFakeModulesProvider(opts ...func(p *fakeModulesProvider)) *fakeModulesProvider { 725 p := &fakeModulesProvider{} 726 p.applyOptions(opts...) 727 return p 728 } 729 730 func (p *fakeModulesProvider) applyOptions(opts ...func(provider *fakeModulesProvider)) { 731 for _, opt := range opts { 732 opt(p) 733 } 734 } 735 736 func getFakeModulesProviderWithCustomExtenders( 737 customExtender *fakeExtender, 738 customProjector *fakeProjector, 739 opts ...func(provider *fakeModulesProvider), 740 ) *fakeModulesProvider { 741 p := &fakeModulesProvider{mock.Mock{}, customExtender, customProjector} 742 p.applyOptions(opts...) 743 return p 744 } 745 746 type fakeMetrics struct { 747 // Note: only those metric functions that relate to usage-related metrics are 748 // covered by this mock, others are empty shells 749 mock.Mock 750 } 751 752 func (f *fakeMetrics) BatchInc() { 753 } 754 755 func (f *fakeMetrics) BatchDec() { 756 } 757 758 func (f *fakeMetrics) BatchRefInc() { 759 } 760 761 func (f *fakeMetrics) BatchRefDec() { 762 } 763 764 func (f *fakeMetrics) BatchDeleteInc() { 765 } 766 767 func (f *fakeMetrics) BatchDeleteDec() { 768 } 769 770 func (f *fakeMetrics) AddObjectInc() { 771 } 772 773 func (f *fakeMetrics) AddObjectDec() { 774 } 775 776 func (f *fakeMetrics) UpdateObjectInc() { 777 } 778 779 func (f *fakeMetrics) UpdateObjectDec() { 780 } 781 782 func (f *fakeMetrics) MergeObjectInc() { 783 } 784 785 func (f *fakeMetrics) MergeObjectDec() { 786 } 787 788 func (f *fakeMetrics) DeleteObjectInc() { 789 } 790 791 func (f *fakeMetrics) DeleteObjectDec() { 792 } 793 794 func (f *fakeMetrics) GetObjectInc() { 795 } 796 797 func (f *fakeMetrics) GetObjectDec() { 798 } 799 800 func (f *fakeMetrics) HeadObjectInc() { 801 } 802 803 func (f *fakeMetrics) HeadObjectDec() { 804 } 805 806 func (f *fakeMetrics) AddReferenceInc() { 807 } 808 809 func (f *fakeMetrics) AddReferenceDec() { 810 } 811 812 func (f *fakeMetrics) UpdateReferenceInc() { 813 } 814 815 func (f *fakeMetrics) UpdateReferenceDec() { 816 } 817 818 func (f *fakeMetrics) DeleteReferenceInc() { 819 } 820 821 func (f *fakeMetrics) DeleteReferenceDec() { 822 } 823 824 func (f *fakeMetrics) AddUsageDimensions(className, queryType, op string, dims int) { 825 f.Mock.MethodCalled("AddUsageDimensions", className, queryType, op, dims) 826 }