diff --git a/enterprise/e2e/html/hurl/mcp-2025-11-25-resources.all.hurl b/enterprise/e2e/html/hurl/mcp-2025-11-25-resources.all.hurl index 76a1465dd..3f51522c9 100644 --- a/enterprise/e2e/html/hurl/mcp-2025-11-25-resources.all.hurl +++ b/enterprise/e2e/html/hurl/mcp-2025-11-25-resources.all.hurl @@ -24,251 +24,301 @@ jsonpath "$.result.resources[0].name" == "error" jsonpath "$.result.resources[0].description" == "The error response format returned by the Sourcemeta One API endpoints" jsonpath "$.result.resources[0].mimeType" == "application/schema+json" jsonpath "$.result.resources[0].size" == 1035 +jsonpath "$.result.resources[0].annotations.priority" == 0 jsonpath "$.result.resources[1].uri" == "{{base}}/self/v1/schemas/api/list/response" jsonpath "$.result.resources[1].name" == "response" jsonpath "$.result.resources[1].description" == "The response format for the directory listing API endpoint" jsonpath "$.result.resources[1].mimeType" == "application/schema+json" jsonpath "$.result.resources[1].size" == 3885 +jsonpath "$.result.resources[1].annotations.priority" == 0 jsonpath "$.result.resources[2].uri" == "{{base}}/self/v1/schemas/api/list/rpc" jsonpath "$.result.resources[2].name" == "rpc" jsonpath "$.result.resources[2].description" == "List the contents of a directory in the catalog" jsonpath "$.result.resources[2].mimeType" == "application/schema+json" jsonpath "$.result.resources[2].size" == 524 +jsonpath "$.result.resources[2].annotations.priority" == 0 jsonpath "$.result.resources[3].uri" == "{{base}}/self/v1/schemas/api/schemas/dependencies/response" jsonpath "$.result.resources[3].name" == "response" jsonpath "$.result.resources[3].description" == "The response format for the schema dependencies API endpoint" jsonpath "$.result.resources[3].mimeType" == "application/schema+json" jsonpath "$.result.resources[3].size" == 1101 +jsonpath "$.result.resources[3].annotations.priority" == 0 jsonpath "$.result.resources[4].uri" == "{{base}}/self/v1/schemas/api/schemas/dependencies/rpc" jsonpath "$.result.resources[4].name" == "rpc" jsonpath "$.result.resources[4].description" == "Get all direct and indirect dependencies of a schema in the catalog" jsonpath "$.result.resources[4].mimeType" == "application/schema+json" jsonpath "$.result.resources[4].size" == 678 +jsonpath "$.result.resources[4].annotations.priority" == 0 jsonpath "$.result.resources[5].uri" == "{{base}}/self/v1/schemas/api/schemas/dependents/response" jsonpath "$.result.resources[5].name" == "response" jsonpath "$.result.resources[5].description" == "The response format for the schema dependents API endpoint" jsonpath "$.result.resources[5].mimeType" == "application/schema+json" jsonpath "$.result.resources[5].size" == 896 +jsonpath "$.result.resources[5].annotations.priority" == 0 jsonpath "$.result.resources[6].uri" == "{{base}}/self/v1/schemas/api/schemas/dependents/rpc" jsonpath "$.result.resources[6].name" == "rpc" jsonpath "$.result.resources[6].description" == "Get all direct and transitive dependents of a schema in the catalog" jsonpath "$.result.resources[6].mimeType" == "application/schema+json" jsonpath "$.result.resources[6].size" == 674 +jsonpath "$.result.resources[6].annotations.priority" == 0 jsonpath "$.result.resources[7].uri" == "{{base}}/self/v1/schemas/api/schemas/evaluate/request" jsonpath "$.result.resources[7].name" == "request" jsonpath "$.result.resources[7].description" == "The JSON instance to validate against a schema in the catalog" jsonpath "$.result.resources[7].mimeType" == "application/schema+json" jsonpath "$.result.resources[7].size" == 417 +jsonpath "$.result.resources[7].annotations.priority" == 0 jsonpath "$.result.resources[8].uri" == "{{base}}/self/v1/schemas/api/schemas/evaluate/response" jsonpath "$.result.resources[8].name" == "response" jsonpath "$.result.resources[8].description" == "The response format for the schema evaluation API endpoint" jsonpath "$.result.resources[8].mimeType" == "application/schema+json" jsonpath "$.result.resources[8].size" == 3277 +jsonpath "$.result.resources[8].annotations.priority" == 0 jsonpath "$.result.resources[9].uri" == "{{base}}/self/v1/schemas/api/schemas/evaluate/rpc" jsonpath "$.result.resources[9].name" == "rpc" jsonpath "$.result.resources[9].description" == "Evaluate a JSON instance against a schema in the catalog and return whether it is valid plus any errors" jsonpath "$.result.resources[9].mimeType" == "application/schema+json" jsonpath "$.result.resources[9].size" == 1561 +jsonpath "$.result.resources[9].annotations.priority" == 0 jsonpath "$.result.resources[10].uri" == "{{base}}/self/v1/schemas/api/schemas/health/response" jsonpath "$.result.resources[10].name" == "response" jsonpath "$.result.resources[10].description" == "The response format for the schema health API endpoint" jsonpath "$.result.resources[10].mimeType" == "application/schema+json" jsonpath "$.result.resources[10].size" == 1622 +jsonpath "$.result.resources[10].annotations.priority" == 0 jsonpath "$.result.resources[11].uri" == "{{base}}/self/v1/schemas/api/schemas/health/rpc" jsonpath "$.result.resources[11].name" == "rpc" jsonpath "$.result.resources[11].description" == "Get the health analysis and score of a schema in the catalog" jsonpath "$.result.resources[11].mimeType" == "application/schema+json" jsonpath "$.result.resources[11].size" == 659 +jsonpath "$.result.resources[11].annotations.priority" == 0 jsonpath "$.result.resources[12].uri" == "{{base}}/self/v1/schemas/api/schemas/locations/response" jsonpath "$.result.resources[12].name" == "response" jsonpath "$.result.resources[12].description" == "The response format for the schema frame locations API endpoint" jsonpath "$.result.resources[12].mimeType" == "application/schema+json" jsonpath "$.result.resources[12].size" == 2668 +jsonpath "$.result.resources[12].annotations.priority" == 0 jsonpath "$.result.resources[13].uri" == "{{base}}/self/v1/schemas/api/schemas/locations/rpc" jsonpath "$.result.resources[13].name" == "rpc" jsonpath "$.result.resources[13].description" == "Get metadata about every URI associated with a schema, including schema resources, subschemas, and anchors" jsonpath "$.result.resources[13].mimeType" == "application/schema+json" jsonpath "$.result.resources[13].size" == 711 +jsonpath "$.result.resources[13].annotations.priority" == 0 jsonpath "$.result.resources[14].uri" == "{{base}}/self/v1/schemas/api/schemas/metadata/response" jsonpath "$.result.resources[14].name" == "response" jsonpath "$.result.resources[14].description" == "The response format for the schema metadata API endpoint" jsonpath "$.result.resources[14].mimeType" == "application/schema+json" jsonpath "$.result.resources[14].size" == 2876 +jsonpath "$.result.resources[14].annotations.priority" == 0 jsonpath "$.result.resources[15].uri" == "{{base}}/self/v1/schemas/api/schemas/metadata/rpc" jsonpath "$.result.resources[15].name" == "rpc" jsonpath "$.result.resources[15].description" == "Get metadata information about a schema in the catalog" jsonpath "$.result.resources[15].mimeType" == "application/schema+json" jsonpath "$.result.resources[15].size" == 657 +jsonpath "$.result.resources[15].annotations.priority" == 0 jsonpath "$.result.resources[16].uri" == "{{base}}/self/v1/schemas/api/schemas/position" jsonpath "$.result.resources[16].name" == "position" jsonpath "$.result.resources[16].description" == "Represents a position in a JSON document as line start, column start, line end, and column end" jsonpath "$.result.resources[16].mimeType" == "application/schema+json" jsonpath "$.result.resources[16].size" == 446 +jsonpath "$.result.resources[16].annotations.priority" == 0 jsonpath "$.result.resources[17].uri" == "{{base}}/self/v1/schemas/api/schemas/positions/response" jsonpath "$.result.resources[17].name" == "response" jsonpath "$.result.resources[17].description" == "The response format for the schema positions API endpoint" jsonpath "$.result.resources[17].mimeType" == "application/schema+json" jsonpath "$.result.resources[17].size" == 435 +jsonpath "$.result.resources[17].annotations.priority" == 0 jsonpath "$.result.resources[18].uri" == "{{base}}/self/v1/schemas/api/schemas/positions/rpc" jsonpath "$.result.resources[18].name" == "rpc" jsonpath "$.result.resources[18].description" == "Get line and column position information for every token in a schema" jsonpath "$.result.resources[18].mimeType" == "application/schema+json" jsonpath "$.result.resources[18].size" == 673 +jsonpath "$.result.resources[18].annotations.priority" == 0 jsonpath "$.result.resources[19].uri" == "{{base}}/self/v1/schemas/api/schemas/search/response" jsonpath "$.result.resources[19].name" == "response" jsonpath "$.result.resources[19].description" == "The response format for the schema search API endpoint" jsonpath "$.result.resources[19].mimeType" == "application/schema+json" jsonpath "$.result.resources[19].size" == 1108 +jsonpath "$.result.resources[19].annotations.priority" == 0 jsonpath "$.result.resources[20].uri" == "{{base}}/self/v1/schemas/api/schemas/search/rpc" jsonpath "$.result.resources[20].name" == "rpc" jsonpath "$.result.resources[20].description" == "Search for schemas in the catalog by query term" jsonpath "$.result.resources[20].mimeType" == "application/schema+json" jsonpath "$.result.resources[20].size" == 1166 +jsonpath "$.result.resources[20].annotations.priority" == 0 jsonpath "$.result.resources[21].uri" == "{{base}}/self/v1/schemas/api/schemas/stats/response" jsonpath "$.result.resources[21].name" == "response" jsonpath "$.result.resources[21].description" == "The response format for the schema statistics API endpoint" jsonpath "$.result.resources[21].mimeType" == "application/schema+json" jsonpath "$.result.resources[21].size" == 2345 +jsonpath "$.result.resources[21].annotations.priority" == 0 jsonpath "$.result.resources[22].uri" == "{{base}}/self/v1/schemas/api/schemas/stats/rpc" jsonpath "$.result.resources[22].name" == "rpc" jsonpath "$.result.resources[22].description" == "Get keyword statistics by vocabulary about every URI associated with a schema in the catalog" jsonpath "$.result.resources[22].mimeType" == "application/schema+json" jsonpath "$.result.resources[22].size" == 694 +jsonpath "$.result.resources[22].annotations.priority" == 0 jsonpath "$.result.resources[23].uri" == "{{base}}/self/v1/schemas/api/schemas/trace/request" jsonpath "$.result.resources[23].name" == "request" jsonpath "$.result.resources[23].description" == "The JSON instance to trace evaluation against a schema in the catalog" jsonpath "$.result.resources[23].mimeType" == "application/schema+json" jsonpath "$.result.resources[23].size" == 419 +jsonpath "$.result.resources[23].annotations.priority" == 0 jsonpath "$.result.resources[24].uri" == "{{base}}/self/v1/schemas/api/schemas/trace/response" jsonpath "$.result.resources[24].name" == "response" jsonpath "$.result.resources[24].description" == "The response format for the schema trace API endpoint" jsonpath "$.result.resources[24].mimeType" == "application/schema+json" jsonpath "$.result.resources[24].size" == 2270 +jsonpath "$.result.resources[24].annotations.priority" == 0 jsonpath "$.result.resources[25].uri" == "{{base}}/self/v1/schemas/api/schemas/trace/rpc" jsonpath "$.result.resources[25].name" == "rpc" jsonpath "$.result.resources[25].description" == "Trace step-by-step evaluation of a JSON instance against a schema in the catalog, exposing each step, rule application, and decision point" jsonpath "$.result.resources[25].mimeType" == "application/schema+json" jsonpath "$.result.resources[25].size" == 1719 +jsonpath "$.result.resources[25].annotations.priority" == 0 jsonpath "$.result.resources[26].uri" == "{{base}}/self/v1/schemas/mcp/error" jsonpath "$.result.resources[26].name" == "error" jsonpath "$.result.resources[26].description" == "The error response Sourcemeta One returns when an MCP request fails" jsonpath "$.result.resources[26].mimeType" == "application/schema+json" jsonpath "$.result.resources[26].size" == 6633 +jsonpath "$.result.resources[26].annotations.priority" == 0 jsonpath "$.result.resources[27].uri" == "{{base}}/self/v1/schemas/mcp/initialize/request" jsonpath "$.result.resources[27].name" == "request" jsonpath "$.result.resources[27].description" == "Connection handshake from a client" jsonpath "$.result.resources[27].mimeType" == "application/schema+json" jsonpath "$.result.resources[27].size" == 4527 +jsonpath "$.result.resources[27].annotations.priority" == 0 jsonpath "$.result.resources[28].uri" == "{{base}}/self/v1/schemas/mcp/initialize/response" jsonpath "$.result.resources[28].name" == "response" jsonpath "$.result.resources[28].description" == "Sourcemeta One's response to a client's initialization" jsonpath "$.result.resources[28].mimeType" == "application/schema+json" jsonpath "$.result.resources[28].size" == 2482 +jsonpath "$.result.resources[28].annotations.priority" == 0 jsonpath "$.result.resources[29].uri" == "{{base}}/self/v1/schemas/mcp/notifications/cancelled" jsonpath "$.result.resources[29].name" == "cancelled" jsonpath "$.result.resources[29].description" == "Cancellation hint from a client for an in-flight request. Sourcemeta One accepts and discards these" jsonpath "$.result.resources[29].mimeType" == "application/schema+json" jsonpath "$.result.resources[29].size" == 1163 +jsonpath "$.result.resources[29].annotations.priority" == 0 jsonpath "$.result.resources[30].uri" == "{{base}}/self/v1/schemas/mcp/notifications/initialized" jsonpath "$.result.resources[30].name" == "initialized" jsonpath "$.result.resources[30].description" == "Client signal that the handshake is complete and normal operation may begin" jsonpath "$.result.resources[30].mimeType" == "application/schema+json" jsonpath "$.result.resources[30].size" == 740 +jsonpath "$.result.resources[30].annotations.priority" == 0 jsonpath "$.result.resources[31].uri" == "{{base}}/self/v1/schemas/mcp/ping/request" jsonpath "$.result.resources[31].name" == "request" jsonpath "$.result.resources[31].description" == "Liveness check from a client" jsonpath "$.result.resources[31].mimeType" == "application/schema+json" jsonpath "$.result.resources[31].size" == 695 +jsonpath "$.result.resources[31].annotations.priority" == 0 jsonpath "$.result.resources[32].uri" == "{{base}}/self/v1/schemas/mcp/ping/response" jsonpath "$.result.resources[32].name" == "response" jsonpath "$.result.resources[32].description" == "Sourcemeta One's response to a liveness check" jsonpath "$.result.resources[32].mimeType" == "application/schema+json" jsonpath "$.result.resources[32].size" == 598 +jsonpath "$.result.resources[32].annotations.priority" == 0 jsonpath "$.result.resources[33].uri" == "{{base}}/self/v1/schemas/mcp/request" jsonpath "$.result.resources[33].name" == "request" jsonpath "$.result.resources[33].description" == "Any incoming MCP request the server accepts" jsonpath "$.result.resources[33].mimeType" == "application/schema+json" jsonpath "$.result.resources[33].size" == 1773 +jsonpath "$.result.resources[33].annotations.priority" == 0 jsonpath "$.result.resources[34].uri" == "{{base}}/self/v1/schemas/mcp/resources/list/request" jsonpath "$.result.resources[34].name" == "request" jsonpath "$.result.resources[34].description" == "Request from a client to list MCP resources" jsonpath "$.result.resources[34].mimeType" == "application/schema+json" jsonpath "$.result.resources[34].size" == 1071 +jsonpath "$.result.resources[34].annotations.priority" == 0 jsonpath "$.result.resources[35].uri" == "{{base}}/self/v1/schemas/mcp/resources/list/response" jsonpath "$.result.resources[35].name" == "response" jsonpath "$.result.resources[35].description" == "Sourcemeta One's list of MCP resources" jsonpath "$.result.resources[35].mimeType" == "application/schema+json" -jsonpath "$.result.resources[35].size" == 2536 +jsonpath "$.result.resources[35].size" == 3015 +jsonpath "$.result.resources[35].annotations.priority" == 0 jsonpath "$.result.resources[36].uri" == "{{base}}/self/v1/schemas/mcp/resources/read/request" jsonpath "$.result.resources[36].name" == "request" jsonpath "$.result.resources[36].description" == "Request from a client to read an MCP resource" jsonpath "$.result.resources[36].mimeType" == "application/schema+json" jsonpath "$.result.resources[36].size" == 1331 +jsonpath "$.result.resources[36].annotations.priority" == 0 jsonpath "$.result.resources[37].uri" == "{{base}}/self/v1/schemas/mcp/resources/read/response" jsonpath "$.result.resources[37].name" == "response" jsonpath "$.result.resources[37].description" == "Sourcemeta One's response containing an MCP resource" jsonpath "$.result.resources[37].mimeType" == "application/schema+json" jsonpath "$.result.resources[37].size" == 1792 +jsonpath "$.result.resources[37].annotations.priority" == 0 jsonpath "$.result.resources[38].uri" == "{{base}}/self/v1/schemas/mcp/resources/templates/list/request" jsonpath "$.result.resources[38].name" == "request" jsonpath "$.result.resources[38].description" == "Request from a client to list MCP resource templates" jsonpath "$.result.resources[38].mimeType" == "application/schema+json" jsonpath "$.result.resources[38].size" == 922 +jsonpath "$.result.resources[38].annotations.priority" == 0 jsonpath "$.result.resources[39].uri" == "{{base}}/self/v1/schemas/mcp/resources/templates/list/response" jsonpath "$.result.resources[39].name" == "response" jsonpath "$.result.resources[39].description" == "Sourcemeta One's list of MCP resource templates" jsonpath "$.result.resources[39].mimeType" == "application/schema+json" jsonpath "$.result.resources[39].size" == 1915 +jsonpath "$.result.resources[39].annotations.priority" == 0 jsonpath "$.result.resources[40].uri" == "{{base}}/self/v1/schemas/mcp/response" jsonpath "$.result.resources[40].name" == "response" jsonpath "$.result.resources[40].description" == "Any outgoing MCP response the server returns" jsonpath "$.result.resources[40].mimeType" == "application/schema+json" jsonpath "$.result.resources[40].size" == 3279 +jsonpath "$.result.resources[40].annotations.priority" == 0 jsonpath "$.result.resources[41].uri" == "{{base}}/self/v1/schemas/mcp/tools/call/request" jsonpath "$.result.resources[41].name" == "request" jsonpath "$.result.resources[41].description" == "Request from a client to invoke an MCP tool by name" jsonpath "$.result.resources[41].mimeType" == "application/schema+json" jsonpath "$.result.resources[41].size" == 1161 +jsonpath "$.result.resources[41].annotations.priority" == 0 jsonpath "$.result.resources[42].uri" == "{{base}}/self/v1/schemas/mcp/tools/call/response" jsonpath "$.result.resources[42].name" == "response" jsonpath "$.result.resources[42].description" == "Sourcemeta One's response to a tool invocation" jsonpath "$.result.resources[42].mimeType" == "application/schema+json" jsonpath "$.result.resources[42].size" == 4706 +jsonpath "$.result.resources[42].annotations.priority" == 0 jsonpath "$.result.resources[43].uri" == "{{base}}/self/v1/schemas/mcp/tools/list/request" jsonpath "$.result.resources[43].name" == "request" jsonpath "$.result.resources[43].description" == "Request from a client to list MCP tools" jsonpath "$.result.resources[43].mimeType" == "application/schema+json" jsonpath "$.result.resources[43].size" == 853 +jsonpath "$.result.resources[43].annotations.priority" == 0 jsonpath "$.result.resources[44].uri" == "{{base}}/twins/foo" jsonpath "$.result.resources[44].name" == "foo" jsonpath "$.result.resources[44].description" == "A schema whose base name collides with a sibling directory" jsonpath "$.result.resources[44].mimeType" == "application/schema+json" jsonpath "$.result.resources[44].size" == 263 +jsonpath "$.result.resources[44].annotations.priority" == 1 jsonpath "$.result.resources[45].uri" == "{{base}}/twins/foo/inner" jsonpath "$.result.resources[45].name" == "inner" jsonpath "$.result.resources[45].description" == "A schema inside the foo directory whose name collides with a sibling schema" jsonpath "$.result.resources[45].mimeType" == "application/schema+json" jsonpath "$.result.resources[45].size" == 280 +jsonpath "$.result.resources[45].annotations.priority" == 1 jsonpath "$.result.resources[46].uri" == "{{base}}/self/v1/schemas/mcp/tools/list/response" jsonpath "$.result.resources[46].name" == "response" jsonpath "$.result.resources[46].description" == "Sourcemeta One's list of MCP tools" jsonpath "$.result.resources[46].mimeType" == "application/schema+json" jsonpath "$.result.resources[46].size" == 4074 +jsonpath "$.result.resources[46].annotations.priority" == 0 jsonpath "$.result.resources[47].uri" == "{{base}}/test/object" jsonpath "$.result.resources[47].name" == "object" jsonpath "$.result.resources[47].description" == "An Object Example" jsonpath "$.result.resources[47].mimeType" == "application/schema+json" jsonpath "$.result.resources[47].size" == 322 +jsonpath "$.result.resources[47].annotations.priority" == 1 jsonpath "$.result.resources[48].uri" == "{{base}}/test/full/01" jsonpath "$.result.resources[48].name" == "01" jsonpath "$.result.resources[48].description" == "A schema with both a title and a description (01)" jsonpath "$.result.resources[48].mimeType" == "application/schema+json" jsonpath "$.result.resources[48].size" == 222 +jsonpath "$.result.resources[48].annotations.priority" == 1 jsonpath "$.result.resources[49].uri" == "{{base}}/test/full/02" jsonpath "$.result.resources[49].name" == "02" jsonpath "$.result.resources[49].description" == "A schema with both a title and a description (02)" jsonpath "$.result.resources[49].mimeType" == "application/schema+json" jsonpath "$.result.resources[49].size" == 222 +jsonpath "$.result.resources[49].annotations.priority" == 1 jsonpath "$.result.nextCursor" == "50" POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}} @@ -308,251 +358,301 @@ jsonpath "$.result.resources[0].name" == "03" jsonpath "$.result.resources[0].description" == "A schema with both a title and a description (03)" jsonpath "$.result.resources[0].mimeType" == "application/schema+json" jsonpath "$.result.resources[0].size" == 222 +jsonpath "$.result.resources[0].annotations.priority" == 1 jsonpath "$.result.resources[1].uri" == "{{base}}/test/full/04" jsonpath "$.result.resources[1].name" == "04" jsonpath "$.result.resources[1].description" == "A schema with both a title and a description (04)" jsonpath "$.result.resources[1].mimeType" == "application/schema+json" jsonpath "$.result.resources[1].size" == 222 +jsonpath "$.result.resources[1].annotations.priority" == 1 jsonpath "$.result.resources[2].uri" == "{{base}}/test/full/05" jsonpath "$.result.resources[2].name" == "05" jsonpath "$.result.resources[2].description" == "A schema with both a title and a description (05)" jsonpath "$.result.resources[2].mimeType" == "application/schema+json" jsonpath "$.result.resources[2].size" == 222 +jsonpath "$.result.resources[2].annotations.priority" == 1 jsonpath "$.result.resources[3].uri" == "{{base}}/test/description-only/01" jsonpath "$.result.resources[3].name" == "01" jsonpath "$.result.resources[3].description" == "A schema with only a description (01)" jsonpath "$.result.resources[3].mimeType" == "application/schema+json" jsonpath "$.result.resources[3].size" == 200 +jsonpath "$.result.resources[3].annotations.priority" == 1 jsonpath "$.result.resources[4].uri" == "{{base}}/test/description-only/02" jsonpath "$.result.resources[4].name" == "02" jsonpath "$.result.resources[4].description" == "A schema with only a description (02)" jsonpath "$.result.resources[4].mimeType" == "application/schema+json" jsonpath "$.result.resources[4].size" == 200 +jsonpath "$.result.resources[4].annotations.priority" == 1 jsonpath "$.result.resources[5].uri" == "{{base}}/test/description-only/03" jsonpath "$.result.resources[5].name" == "03" jsonpath "$.result.resources[5].description" == "A schema with only a description (03)" jsonpath "$.result.resources[5].mimeType" == "application/schema+json" jsonpath "$.result.resources[5].size" == 200 +jsonpath "$.result.resources[5].annotations.priority" == 1 jsonpath "$.result.resources[6].uri" == "{{base}}/test/description-only/04" jsonpath "$.result.resources[6].name" == "04" jsonpath "$.result.resources[6].description" == "A schema with only a description (04)" jsonpath "$.result.resources[6].mimeType" == "application/schema+json" jsonpath "$.result.resources[6].size" == 200 +jsonpath "$.result.resources[6].annotations.priority" == 1 jsonpath "$.result.resources[7].uri" == "{{base}}/test/description-only/05" jsonpath "$.result.resources[7].name" == "05" jsonpath "$.result.resources[7].description" == "A schema with only a description (05)" jsonpath "$.result.resources[7].mimeType" == "application/schema+json" jsonpath "$.result.resources[7].size" == 200 +jsonpath "$.result.resources[7].annotations.priority" == 1 jsonpath "$.result.resources[8].uri" == "{{base}}/test/title-only/01" jsonpath "$.result.resources[8].name" == "01" jsonpath "$.result.resources[8].description" not exists jsonpath "$.result.resources[8].mimeType" == "application/schema+json" jsonpath "$.result.resources[8].size" == 164 +jsonpath "$.result.resources[8].annotations.priority" == 1 jsonpath "$.result.resources[9].uri" == "{{base}}/test/title-only/02" jsonpath "$.result.resources[9].name" == "02" jsonpath "$.result.resources[9].description" not exists jsonpath "$.result.resources[9].mimeType" == "application/schema+json" jsonpath "$.result.resources[9].size" == 164 +jsonpath "$.result.resources[9].annotations.priority" == 1 jsonpath "$.result.resources[10].uri" == "{{base}}/test/title-only/03" jsonpath "$.result.resources[10].name" == "03" jsonpath "$.result.resources[10].description" not exists jsonpath "$.result.resources[10].mimeType" == "application/schema+json" jsonpath "$.result.resources[10].size" == 164 +jsonpath "$.result.resources[10].annotations.priority" == 1 jsonpath "$.result.resources[11].uri" == "{{base}}/test/title-only/04" jsonpath "$.result.resources[11].name" == "04" jsonpath "$.result.resources[11].description" not exists jsonpath "$.result.resources[11].mimeType" == "application/schema+json" jsonpath "$.result.resources[11].size" == 164 +jsonpath "$.result.resources[11].annotations.priority" == 1 jsonpath "$.result.resources[12].uri" == "{{base}}/test/title-only/05" jsonpath "$.result.resources[12].name" == "05" jsonpath "$.result.resources[12].description" not exists jsonpath "$.result.resources[12].mimeType" == "application/schema+json" jsonpath "$.result.resources[12].size" == 164 +jsonpath "$.result.resources[12].annotations.priority" == 1 jsonpath "$.result.resources[13].uri" == "{{base}}/test/draft3/with-ref" jsonpath "$.result.resources[13].name" == "with-ref" jsonpath "$.result.resources[13].description" not exists jsonpath "$.result.resources[13].mimeType" == "application/schema+json" jsonpath "$.result.resources[13].size" == 197 +jsonpath "$.result.resources[13].annotations.priority" == 1 jsonpath "$.result.resources[14].uri" == "{{base}}/test/bare/01" jsonpath "$.result.resources[14].name" == "01" jsonpath "$.result.resources[14].description" not exists jsonpath "$.result.resources[14].mimeType" == "application/schema+json" jsonpath "$.result.resources[14].size" == 130 +jsonpath "$.result.resources[14].annotations.priority" == 1 jsonpath "$.result.resources[15].uri" == "{{base}}/test/bare/02" jsonpath "$.result.resources[15].name" == "02" jsonpath "$.result.resources[15].description" not exists jsonpath "$.result.resources[15].mimeType" == "application/schema+json" jsonpath "$.result.resources[15].size" == 130 +jsonpath "$.result.resources[15].annotations.priority" == 1 jsonpath "$.result.resources[16].uri" == "{{base}}/test/bare/03" jsonpath "$.result.resources[16].name" == "03" jsonpath "$.result.resources[16].description" not exists jsonpath "$.result.resources[16].mimeType" == "application/schema+json" jsonpath "$.result.resources[16].size" == 130 +jsonpath "$.result.resources[16].annotations.priority" == 1 jsonpath "$.result.resources[17].uri" == "{{base}}/test/bare/04" jsonpath "$.result.resources[17].name" == "04" jsonpath "$.result.resources[17].description" not exists jsonpath "$.result.resources[17].mimeType" == "application/schema+json" jsonpath "$.result.resources[17].size" == 130 +jsonpath "$.result.resources[17].annotations.priority" == 1 jsonpath "$.result.resources[18].uri" == "{{base}}/test/bare/05" jsonpath "$.result.resources[18].name" == "05" jsonpath "$.result.resources[18].description" not exists jsonpath "$.result.resources[18].mimeType" == "application/schema+json" jsonpath "$.result.resources[18].size" == 130 +jsonpath "$.result.resources[18].annotations.priority" == 1 jsonpath "$.result.resources[19].uri" == "{{base}}/test/bare/06" jsonpath "$.result.resources[19].name" == "06" jsonpath "$.result.resources[19].description" not exists jsonpath "$.result.resources[19].mimeType" == "application/schema+json" jsonpath "$.result.resources[19].size" == 130 +jsonpath "$.result.resources[19].annotations.priority" == 1 jsonpath "$.result.resources[20].uri" == "{{base}}/test/bare/07" jsonpath "$.result.resources[20].name" == "07" jsonpath "$.result.resources[20].description" not exists jsonpath "$.result.resources[20].mimeType" == "application/schema+json" jsonpath "$.result.resources[20].size" == 130 +jsonpath "$.result.resources[20].annotations.priority" == 1 jsonpath "$.result.resources[21].uri" == "{{base}}/test/bare/08" jsonpath "$.result.resources[21].name" == "08" jsonpath "$.result.resources[21].description" not exists jsonpath "$.result.resources[21].mimeType" == "application/schema+json" jsonpath "$.result.resources[21].size" == 130 +jsonpath "$.result.resources[21].annotations.priority" == 1 jsonpath "$.result.resources[22].uri" == "{{base}}/test/bare/09" jsonpath "$.result.resources[22].name" == "09" jsonpath "$.result.resources[22].description" not exists jsonpath "$.result.resources[22].mimeType" == "application/schema+json" jsonpath "$.result.resources[22].size" == 130 +jsonpath "$.result.resources[22].annotations.priority" == 1 jsonpath "$.result.resources[23].uri" == "{{base}}/test/bare/10" jsonpath "$.result.resources[23].name" == "10" jsonpath "$.result.resources[23].description" not exists jsonpath "$.result.resources[23].mimeType" == "application/schema+json" jsonpath "$.result.resources[23].size" == 130 +jsonpath "$.result.resources[23].annotations.priority" == 1 jsonpath "$.result.resources[24].uri" == "{{base}}/test/bare/11" jsonpath "$.result.resources[24].name" == "11" jsonpath "$.result.resources[24].description" not exists jsonpath "$.result.resources[24].mimeType" == "application/schema+json" jsonpath "$.result.resources[24].size" == 130 +jsonpath "$.result.resources[24].annotations.priority" == 1 jsonpath "$.result.resources[25].uri" == "{{base}}/test/bare/12" jsonpath "$.result.resources[25].name" == "12" jsonpath "$.result.resources[25].description" not exists jsonpath "$.result.resources[25].mimeType" == "application/schema+json" jsonpath "$.result.resources[25].size" == 130 +jsonpath "$.result.resources[25].annotations.priority" == 1 jsonpath "$.result.resources[26].uri" == "{{base}}/test/bare/13" jsonpath "$.result.resources[26].name" == "13" jsonpath "$.result.resources[26].description" not exists jsonpath "$.result.resources[26].mimeType" == "application/schema+json" jsonpath "$.result.resources[26].size" == 130 +jsonpath "$.result.resources[26].annotations.priority" == 1 jsonpath "$.result.resources[27].uri" == "{{base}}/test/bare/14" jsonpath "$.result.resources[27].name" == "14" jsonpath "$.result.resources[27].description" not exists jsonpath "$.result.resources[27].mimeType" == "application/schema+json" jsonpath "$.result.resources[27].size" == 130 +jsonpath "$.result.resources[27].annotations.priority" == 1 jsonpath "$.result.resources[28].uri" == "{{base}}/test/bare/15" jsonpath "$.result.resources[28].name" == "15" jsonpath "$.result.resources[28].description" not exists jsonpath "$.result.resources[28].mimeType" == "application/schema+json" jsonpath "$.result.resources[28].size" == 130 +jsonpath "$.result.resources[28].annotations.priority" == 1 jsonpath "$.result.resources[29].uri" == "{{base}}/test/bare/16" jsonpath "$.result.resources[29].name" == "16" jsonpath "$.result.resources[29].description" not exists jsonpath "$.result.resources[29].mimeType" == "application/schema+json" jsonpath "$.result.resources[29].size" == 130 +jsonpath "$.result.resources[29].annotations.priority" == 1 jsonpath "$.result.resources[30].uri" == "{{base}}/test/bare/17" jsonpath "$.result.resources[30].name" == "17" jsonpath "$.result.resources[30].description" not exists jsonpath "$.result.resources[30].mimeType" == "application/schema+json" jsonpath "$.result.resources[30].size" == 130 +jsonpath "$.result.resources[30].annotations.priority" == 1 jsonpath "$.result.resources[31].uri" == "{{base}}/test/bare/18" jsonpath "$.result.resources[31].name" == "18" jsonpath "$.result.resources[31].description" not exists jsonpath "$.result.resources[31].mimeType" == "application/schema+json" jsonpath "$.result.resources[31].size" == 130 +jsonpath "$.result.resources[31].annotations.priority" == 1 jsonpath "$.result.resources[32].uri" == "{{base}}/test/bare/19" jsonpath "$.result.resources[32].name" == "19" jsonpath "$.result.resources[32].description" not exists jsonpath "$.result.resources[32].mimeType" == "application/schema+json" jsonpath "$.result.resources[32].size" == 130 +jsonpath "$.result.resources[32].annotations.priority" == 1 jsonpath "$.result.resources[33].uri" == "{{base}}/test/bare/20" jsonpath "$.result.resources[33].name" == "20" jsonpath "$.result.resources[33].description" not exists jsonpath "$.result.resources[33].mimeType" == "application/schema+json" jsonpath "$.result.resources[33].size" == 130 +jsonpath "$.result.resources[33].annotations.priority" == 1 jsonpath "$.result.resources[34].uri" == "{{base}}/test/bare/21" jsonpath "$.result.resources[34].name" == "21" jsonpath "$.result.resources[34].description" not exists jsonpath "$.result.resources[34].mimeType" == "application/schema+json" jsonpath "$.result.resources[34].size" == 130 +jsonpath "$.result.resources[34].annotations.priority" == 1 jsonpath "$.result.resources[35].uri" == "{{base}}/test/bare/22" jsonpath "$.result.resources[35].name" == "22" jsonpath "$.result.resources[35].description" not exists jsonpath "$.result.resources[35].mimeType" == "application/schema+json" jsonpath "$.result.resources[35].size" == 130 +jsonpath "$.result.resources[35].annotations.priority" == 1 jsonpath "$.result.resources[36].uri" == "{{base}}/test/bare/23" jsonpath "$.result.resources[36].name" == "23" jsonpath "$.result.resources[36].description" not exists jsonpath "$.result.resources[36].mimeType" == "application/schema+json" jsonpath "$.result.resources[36].size" == 130 +jsonpath "$.result.resources[36].annotations.priority" == 1 jsonpath "$.result.resources[37].uri" == "{{base}}/test/bare/24" jsonpath "$.result.resources[37].name" == "24" jsonpath "$.result.resources[37].description" not exists jsonpath "$.result.resources[37].mimeType" == "application/schema+json" jsonpath "$.result.resources[37].size" == 130 +jsonpath "$.result.resources[37].annotations.priority" == 1 jsonpath "$.result.resources[38].uri" == "{{base}}/test/bare/25" jsonpath "$.result.resources[38].name" == "25" jsonpath "$.result.resources[38].description" not exists jsonpath "$.result.resources[38].mimeType" == "application/schema+json" jsonpath "$.result.resources[38].size" == 130 +jsonpath "$.result.resources[38].annotations.priority" == 1 jsonpath "$.result.resources[39].uri" == "{{base}}/test/bare/26" jsonpath "$.result.resources[39].name" == "26" jsonpath "$.result.resources[39].description" not exists jsonpath "$.result.resources[39].mimeType" == "application/schema+json" jsonpath "$.result.resources[39].size" == 130 +jsonpath "$.result.resources[39].annotations.priority" == 1 jsonpath "$.result.resources[40].uri" == "{{base}}/test/bare/27" jsonpath "$.result.resources[40].name" == "27" jsonpath "$.result.resources[40].description" not exists jsonpath "$.result.resources[40].mimeType" == "application/schema+json" jsonpath "$.result.resources[40].size" == 130 +jsonpath "$.result.resources[40].annotations.priority" == 1 jsonpath "$.result.resources[41].uri" == "{{base}}/test/bare/28" jsonpath "$.result.resources[41].name" == "28" jsonpath "$.result.resources[41].description" not exists jsonpath "$.result.resources[41].mimeType" == "application/schema+json" jsonpath "$.result.resources[41].size" == 130 +jsonpath "$.result.resources[41].annotations.priority" == 1 jsonpath "$.result.resources[42].uri" == "{{base}}/test/bare/29" jsonpath "$.result.resources[42].name" == "29" jsonpath "$.result.resources[42].description" not exists jsonpath "$.result.resources[42].mimeType" == "application/schema+json" jsonpath "$.result.resources[42].size" == 130 +jsonpath "$.result.resources[42].annotations.priority" == 1 jsonpath "$.result.resources[43].uri" == "{{base}}/test/bare/30" jsonpath "$.result.resources[43].name" == "30" jsonpath "$.result.resources[43].description" not exists jsonpath "$.result.resources[43].mimeType" == "application/schema+json" jsonpath "$.result.resources[43].size" == 130 +jsonpath "$.result.resources[43].annotations.priority" == 1 jsonpath "$.result.resources[44].uri" == "{{base}}/test/bare/31" jsonpath "$.result.resources[44].name" == "31" jsonpath "$.result.resources[44].description" not exists jsonpath "$.result.resources[44].mimeType" == "application/schema+json" jsonpath "$.result.resources[44].size" == 130 +jsonpath "$.result.resources[44].annotations.priority" == 1 jsonpath "$.result.resources[45].uri" == "{{base}}/test/bare/32" jsonpath "$.result.resources[45].name" == "32" jsonpath "$.result.resources[45].description" not exists jsonpath "$.result.resources[45].mimeType" == "application/schema+json" jsonpath "$.result.resources[45].size" == 130 +jsonpath "$.result.resources[45].annotations.priority" == 1 jsonpath "$.result.resources[46].uri" == "{{base}}/test/bare/33" jsonpath "$.result.resources[46].name" == "33" jsonpath "$.result.resources[46].description" not exists jsonpath "$.result.resources[46].mimeType" == "application/schema+json" jsonpath "$.result.resources[46].size" == 130 +jsonpath "$.result.resources[46].annotations.priority" == 1 jsonpath "$.result.resources[47].uri" == "{{base}}/test/bare/34" jsonpath "$.result.resources[47].name" == "34" jsonpath "$.result.resources[47].description" not exists jsonpath "$.result.resources[47].mimeType" == "application/schema+json" jsonpath "$.result.resources[47].size" == 130 +jsonpath "$.result.resources[47].annotations.priority" == 1 jsonpath "$.result.resources[48].uri" == "{{base}}/test/bare/35" jsonpath "$.result.resources[48].name" == "35" jsonpath "$.result.resources[48].description" not exists jsonpath "$.result.resources[48].mimeType" == "application/schema+json" jsonpath "$.result.resources[48].size" == 130 +jsonpath "$.result.resources[48].annotations.priority" == 1 jsonpath "$.result.resources[49].uri" == "{{base}}/test/bare/36" jsonpath "$.result.resources[49].name" == "36" jsonpath "$.result.resources[49].description" not exists jsonpath "$.result.resources[49].mimeType" == "application/schema+json" jsonpath "$.result.resources[49].size" == 130 +jsonpath "$.result.resources[49].annotations.priority" == 1 jsonpath "$.result.nextCursor" == "100" POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}} @@ -592,76 +692,91 @@ jsonpath "$.result.resources[0].name" == "37" jsonpath "$.result.resources[0].description" not exists jsonpath "$.result.resources[0].mimeType" == "application/schema+json" jsonpath "$.result.resources[0].size" == 130 +jsonpath "$.result.resources[0].annotations.priority" == 1 jsonpath "$.result.resources[1].uri" == "{{base}}/test/bare/38" jsonpath "$.result.resources[1].name" == "38" jsonpath "$.result.resources[1].description" not exists jsonpath "$.result.resources[1].mimeType" == "application/schema+json" jsonpath "$.result.resources[1].size" == 130 +jsonpath "$.result.resources[1].annotations.priority" == 1 jsonpath "$.result.resources[2].uri" == "{{base}}/test/bare/39" jsonpath "$.result.resources[2].name" == "39" jsonpath "$.result.resources[2].description" not exists jsonpath "$.result.resources[2].mimeType" == "application/schema+json" jsonpath "$.result.resources[2].size" == 130 +jsonpath "$.result.resources[2].annotations.priority" == 1 jsonpath "$.result.resources[3].uri" == "{{base}}/test/bare/40" jsonpath "$.result.resources[3].name" == "40" jsonpath "$.result.resources[3].description" not exists jsonpath "$.result.resources[3].mimeType" == "application/schema+json" jsonpath "$.result.resources[3].size" == 130 +jsonpath "$.result.resources[3].annotations.priority" == 1 jsonpath "$.result.resources[4].uri" == "{{base}}/test/bare/41" jsonpath "$.result.resources[4].name" == "41" jsonpath "$.result.resources[4].description" not exists jsonpath "$.result.resources[4].mimeType" == "application/schema+json" jsonpath "$.result.resources[4].size" == 130 +jsonpath "$.result.resources[4].annotations.priority" == 1 jsonpath "$.result.resources[5].uri" == "{{base}}/test/bare/42" jsonpath "$.result.resources[5].name" == "42" jsonpath "$.result.resources[5].description" not exists jsonpath "$.result.resources[5].mimeType" == "application/schema+json" jsonpath "$.result.resources[5].size" == 130 +jsonpath "$.result.resources[5].annotations.priority" == 1 jsonpath "$.result.resources[6].uri" == "{{base}}/test/bare/43" jsonpath "$.result.resources[6].name" == "43" jsonpath "$.result.resources[6].description" not exists jsonpath "$.result.resources[6].mimeType" == "application/schema+json" jsonpath "$.result.resources[6].size" == 130 +jsonpath "$.result.resources[6].annotations.priority" == 1 jsonpath "$.result.resources[7].uri" == "{{base}}/test/bare/44" jsonpath "$.result.resources[7].name" == "44" jsonpath "$.result.resources[7].description" not exists jsonpath "$.result.resources[7].mimeType" == "application/schema+json" jsonpath "$.result.resources[7].size" == 130 +jsonpath "$.result.resources[7].annotations.priority" == 1 jsonpath "$.result.resources[8].uri" == "{{base}}/test/bare/45" jsonpath "$.result.resources[8].name" == "45" jsonpath "$.result.resources[8].description" not exists jsonpath "$.result.resources[8].mimeType" == "application/schema+json" jsonpath "$.result.resources[8].size" == 130 +jsonpath "$.result.resources[8].annotations.priority" == 1 jsonpath "$.result.resources[9].uri" == "{{base}}/test/bare/46" jsonpath "$.result.resources[9].name" == "46" jsonpath "$.result.resources[9].description" not exists jsonpath "$.result.resources[9].mimeType" == "application/schema+json" jsonpath "$.result.resources[9].size" == 130 +jsonpath "$.result.resources[9].annotations.priority" == 1 jsonpath "$.result.resources[10].uri" == "{{base}}/test/bare/47" jsonpath "$.result.resources[10].name" == "47" jsonpath "$.result.resources[10].description" not exists jsonpath "$.result.resources[10].mimeType" == "application/schema+json" jsonpath "$.result.resources[10].size" == 130 +jsonpath "$.result.resources[10].annotations.priority" == 1 jsonpath "$.result.resources[11].uri" == "{{base}}/test/bare/48" jsonpath "$.result.resources[11].name" == "48" jsonpath "$.result.resources[11].description" not exists jsonpath "$.result.resources[11].mimeType" == "application/schema+json" jsonpath "$.result.resources[11].size" == 130 +jsonpath "$.result.resources[11].annotations.priority" == 1 jsonpath "$.result.resources[12].uri" == "{{base}}/test/bare/49" jsonpath "$.result.resources[12].name" == "49" jsonpath "$.result.resources[12].description" not exists jsonpath "$.result.resources[12].mimeType" == "application/schema+json" jsonpath "$.result.resources[12].size" == 130 +jsonpath "$.result.resources[12].annotations.priority" == 1 jsonpath "$.result.resources[13].uri" == "{{base}}/test/bare/50" jsonpath "$.result.resources[13].name" == "50" jsonpath "$.result.resources[13].description" not exists jsonpath "$.result.resources[13].mimeType" == "application/schema+json" jsonpath "$.result.resources[13].size" == 130 +jsonpath "$.result.resources[13].annotations.priority" == 1 jsonpath "$.result.resources[14].uri" == "{{base}}/test/draft3/string" jsonpath "$.result.resources[14].name" == "string" jsonpath "$.result.resources[14].description" not exists jsonpath "$.result.resources[14].mimeType" == "application/schema+json" jsonpath "$.result.resources[14].size" == 130 +jsonpath "$.result.resources[14].annotations.priority" == 1 jsonpath "$.result.nextCursor" not exists POST {{base}}/self/v1/api/schemas/evaluate{{schema_path}} diff --git a/enterprise/e2e/path/hurl/mcp-2025-11-25-resources.all.hurl b/enterprise/e2e/path/hurl/mcp-2025-11-25-resources.all.hurl index 40440e9f6..4f88df120 100644 --- a/enterprise/e2e/path/hurl/mcp-2025-11-25-resources.all.hurl +++ b/enterprise/e2e/path/hurl/mcp-2025-11-25-resources.all.hurl @@ -24,251 +24,301 @@ jsonpath "$.result.resources[0].name" == "error" jsonpath "$.result.resources[0].description" == "The error response format returned by the Sourcemeta One API endpoints" jsonpath "$.result.resources[0].mimeType" == "application/schema+json" jsonpath "$.result.resources[0].size" == 1046 +jsonpath "$.result.resources[0].annotations.priority" == 0 jsonpath "$.result.resources[1].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/list/response" jsonpath "$.result.resources[1].name" == "response" jsonpath "$.result.resources[1].description" == "The response format for the directory listing API endpoint" jsonpath "$.result.resources[1].mimeType" == "application/schema+json" jsonpath "$.result.resources[1].size" == 3896 +jsonpath "$.result.resources[1].annotations.priority" == 0 jsonpath "$.result.resources[2].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/list/rpc" jsonpath "$.result.resources[2].name" == "rpc" jsonpath "$.result.resources[2].description" == "List the contents of a directory in the catalog" jsonpath "$.result.resources[2].mimeType" == "application/schema+json" jsonpath "$.result.resources[2].size" == 535 +jsonpath "$.result.resources[2].annotations.priority" == 0 jsonpath "$.result.resources[3].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/dependencies/response" jsonpath "$.result.resources[3].name" == "response" jsonpath "$.result.resources[3].description" == "The response format for the schema dependencies API endpoint" jsonpath "$.result.resources[3].mimeType" == "application/schema+json" jsonpath "$.result.resources[3].size" == 1112 +jsonpath "$.result.resources[3].annotations.priority" == 0 jsonpath "$.result.resources[4].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/dependencies/rpc" jsonpath "$.result.resources[4].name" == "rpc" jsonpath "$.result.resources[4].description" == "Get all direct and indirect dependencies of a schema in the catalog" jsonpath "$.result.resources[4].mimeType" == "application/schema+json" jsonpath "$.result.resources[4].size" == 689 +jsonpath "$.result.resources[4].annotations.priority" == 0 jsonpath "$.result.resources[5].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/dependents/response" jsonpath "$.result.resources[5].name" == "response" jsonpath "$.result.resources[5].description" == "The response format for the schema dependents API endpoint" jsonpath "$.result.resources[5].mimeType" == "application/schema+json" jsonpath "$.result.resources[5].size" == 907 +jsonpath "$.result.resources[5].annotations.priority" == 0 jsonpath "$.result.resources[6].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/dependents/rpc" jsonpath "$.result.resources[6].name" == "rpc" jsonpath "$.result.resources[6].description" == "Get all direct and transitive dependents of a schema in the catalog" jsonpath "$.result.resources[6].mimeType" == "application/schema+json" jsonpath "$.result.resources[6].size" == 685 +jsonpath "$.result.resources[6].annotations.priority" == 0 jsonpath "$.result.resources[7].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/evaluate/request" jsonpath "$.result.resources[7].name" == "request" jsonpath "$.result.resources[7].description" == "The JSON instance to validate against a schema in the catalog" jsonpath "$.result.resources[7].mimeType" == "application/schema+json" jsonpath "$.result.resources[7].size" == 428 +jsonpath "$.result.resources[7].annotations.priority" == 0 jsonpath "$.result.resources[8].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/evaluate/response" jsonpath "$.result.resources[8].name" == "response" jsonpath "$.result.resources[8].description" == "The response format for the schema evaluation API endpoint" jsonpath "$.result.resources[8].mimeType" == "application/schema+json" jsonpath "$.result.resources[8].size" == 3288 +jsonpath "$.result.resources[8].annotations.priority" == 0 jsonpath "$.result.resources[9].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/evaluate/rpc" jsonpath "$.result.resources[9].name" == "rpc" jsonpath "$.result.resources[9].description" == "Evaluate a JSON instance against a schema in the catalog and return whether it is valid plus any errors" jsonpath "$.result.resources[9].mimeType" == "application/schema+json" jsonpath "$.result.resources[9].size" == 1572 +jsonpath "$.result.resources[9].annotations.priority" == 0 jsonpath "$.result.resources[10].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/health/response" jsonpath "$.result.resources[10].name" == "response" jsonpath "$.result.resources[10].description" == "The response format for the schema health API endpoint" jsonpath "$.result.resources[10].mimeType" == "application/schema+json" jsonpath "$.result.resources[10].size" == 1633 +jsonpath "$.result.resources[10].annotations.priority" == 0 jsonpath "$.result.resources[11].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/health/rpc" jsonpath "$.result.resources[11].name" == "rpc" jsonpath "$.result.resources[11].description" == "Get the health analysis and score of a schema in the catalog" jsonpath "$.result.resources[11].mimeType" == "application/schema+json" jsonpath "$.result.resources[11].size" == 670 +jsonpath "$.result.resources[11].annotations.priority" == 0 jsonpath "$.result.resources[12].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/locations/response" jsonpath "$.result.resources[12].name" == "response" jsonpath "$.result.resources[12].description" == "The response format for the schema frame locations API endpoint" jsonpath "$.result.resources[12].mimeType" == "application/schema+json" jsonpath "$.result.resources[12].size" == 2679 +jsonpath "$.result.resources[12].annotations.priority" == 0 jsonpath "$.result.resources[13].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/locations/rpc" jsonpath "$.result.resources[13].name" == "rpc" jsonpath "$.result.resources[13].description" == "Get metadata about every URI associated with a schema, including schema resources, subschemas, and anchors" jsonpath "$.result.resources[13].mimeType" == "application/schema+json" jsonpath "$.result.resources[13].size" == 722 +jsonpath "$.result.resources[13].annotations.priority" == 0 jsonpath "$.result.resources[14].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/metadata/response" jsonpath "$.result.resources[14].name" == "response" jsonpath "$.result.resources[14].description" == "The response format for the schema metadata API endpoint" jsonpath "$.result.resources[14].mimeType" == "application/schema+json" jsonpath "$.result.resources[14].size" == 2887 +jsonpath "$.result.resources[14].annotations.priority" == 0 jsonpath "$.result.resources[15].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/metadata/rpc" jsonpath "$.result.resources[15].name" == "rpc" jsonpath "$.result.resources[15].description" == "Get metadata information about a schema in the catalog" jsonpath "$.result.resources[15].mimeType" == "application/schema+json" jsonpath "$.result.resources[15].size" == 668 +jsonpath "$.result.resources[15].annotations.priority" == 0 jsonpath "$.result.resources[16].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/position" jsonpath "$.result.resources[16].name" == "position" jsonpath "$.result.resources[16].description" == "Represents a position in a JSON document as line start, column start, line end, and column end" jsonpath "$.result.resources[16].mimeType" == "application/schema+json" jsonpath "$.result.resources[16].size" == 457 +jsonpath "$.result.resources[16].annotations.priority" == 0 jsonpath "$.result.resources[17].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/positions/response" jsonpath "$.result.resources[17].name" == "response" jsonpath "$.result.resources[17].description" == "The response format for the schema positions API endpoint" jsonpath "$.result.resources[17].mimeType" == "application/schema+json" jsonpath "$.result.resources[17].size" == 446 +jsonpath "$.result.resources[17].annotations.priority" == 0 jsonpath "$.result.resources[18].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/positions/rpc" jsonpath "$.result.resources[18].name" == "rpc" jsonpath "$.result.resources[18].description" == "Get line and column position information for every token in a schema" jsonpath "$.result.resources[18].mimeType" == "application/schema+json" jsonpath "$.result.resources[18].size" == 684 +jsonpath "$.result.resources[18].annotations.priority" == 0 jsonpath "$.result.resources[19].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/search/response" jsonpath "$.result.resources[19].name" == "response" jsonpath "$.result.resources[19].description" == "The response format for the schema search API endpoint" jsonpath "$.result.resources[19].mimeType" == "application/schema+json" jsonpath "$.result.resources[19].size" == 1119 +jsonpath "$.result.resources[19].annotations.priority" == 0 jsonpath "$.result.resources[20].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/search/rpc" jsonpath "$.result.resources[20].name" == "rpc" jsonpath "$.result.resources[20].description" == "Search for schemas in the catalog by query term" jsonpath "$.result.resources[20].mimeType" == "application/schema+json" jsonpath "$.result.resources[20].size" == 1177 +jsonpath "$.result.resources[20].annotations.priority" == 0 jsonpath "$.result.resources[21].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/stats/response" jsonpath "$.result.resources[21].name" == "response" jsonpath "$.result.resources[21].description" == "The response format for the schema statistics API endpoint" jsonpath "$.result.resources[21].mimeType" == "application/schema+json" jsonpath "$.result.resources[21].size" == 2356 +jsonpath "$.result.resources[21].annotations.priority" == 0 jsonpath "$.result.resources[22].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/stats/rpc" jsonpath "$.result.resources[22].name" == "rpc" jsonpath "$.result.resources[22].description" == "Get keyword statistics by vocabulary about every URI associated with a schema in the catalog" jsonpath "$.result.resources[22].mimeType" == "application/schema+json" jsonpath "$.result.resources[22].size" == 705 +jsonpath "$.result.resources[22].annotations.priority" == 0 jsonpath "$.result.resources[23].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/trace/request" jsonpath "$.result.resources[23].name" == "request" jsonpath "$.result.resources[23].description" == "The JSON instance to trace evaluation against a schema in the catalog" jsonpath "$.result.resources[23].mimeType" == "application/schema+json" jsonpath "$.result.resources[23].size" == 430 +jsonpath "$.result.resources[23].annotations.priority" == 0 jsonpath "$.result.resources[24].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/trace/response" jsonpath "$.result.resources[24].name" == "response" jsonpath "$.result.resources[24].description" == "The response format for the schema trace API endpoint" jsonpath "$.result.resources[24].mimeType" == "application/schema+json" jsonpath "$.result.resources[24].size" == 2281 +jsonpath "$.result.resources[24].annotations.priority" == 0 jsonpath "$.result.resources[25].uri" == "{{base}}/v1/catalog/self/v1/schemas/api/schemas/trace/rpc" jsonpath "$.result.resources[25].name" == "rpc" jsonpath "$.result.resources[25].description" == "Trace step-by-step evaluation of a JSON instance against a schema in the catalog, exposing each step, rule application, and decision point" jsonpath "$.result.resources[25].mimeType" == "application/schema+json" jsonpath "$.result.resources[25].size" == 1730 +jsonpath "$.result.resources[25].annotations.priority" == 0 jsonpath "$.result.resources[26].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/error" jsonpath "$.result.resources[26].name" == "error" jsonpath "$.result.resources[26].description" == "The error response Sourcemeta One returns when an MCP request fails" jsonpath "$.result.resources[26].mimeType" == "application/schema+json" jsonpath "$.result.resources[26].size" == 6644 +jsonpath "$.result.resources[26].annotations.priority" == 0 jsonpath "$.result.resources[27].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/initialize/request" jsonpath "$.result.resources[27].name" == "request" jsonpath "$.result.resources[27].description" == "Connection handshake from a client" jsonpath "$.result.resources[27].mimeType" == "application/schema+json" jsonpath "$.result.resources[27].size" == 4538 +jsonpath "$.result.resources[27].annotations.priority" == 0 jsonpath "$.result.resources[28].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/initialize/response" jsonpath "$.result.resources[28].name" == "response" jsonpath "$.result.resources[28].description" == "Sourcemeta One's response to a client's initialization" jsonpath "$.result.resources[28].mimeType" == "application/schema+json" jsonpath "$.result.resources[28].size" == 2493 +jsonpath "$.result.resources[28].annotations.priority" == 0 jsonpath "$.result.resources[29].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/notifications/cancelled" jsonpath "$.result.resources[29].name" == "cancelled" jsonpath "$.result.resources[29].description" == "Cancellation hint from a client for an in-flight request. Sourcemeta One accepts and discards these" jsonpath "$.result.resources[29].mimeType" == "application/schema+json" jsonpath "$.result.resources[29].size" == 1174 +jsonpath "$.result.resources[29].annotations.priority" == 0 jsonpath "$.result.resources[30].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/notifications/initialized" jsonpath "$.result.resources[30].name" == "initialized" jsonpath "$.result.resources[30].description" == "Client signal that the handshake is complete and normal operation may begin" jsonpath "$.result.resources[30].mimeType" == "application/schema+json" jsonpath "$.result.resources[30].size" == 751 +jsonpath "$.result.resources[30].annotations.priority" == 0 jsonpath "$.result.resources[31].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/ping/request" jsonpath "$.result.resources[31].name" == "request" jsonpath "$.result.resources[31].description" == "Liveness check from a client" jsonpath "$.result.resources[31].mimeType" == "application/schema+json" jsonpath "$.result.resources[31].size" == 706 +jsonpath "$.result.resources[31].annotations.priority" == 0 jsonpath "$.result.resources[32].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/ping/response" jsonpath "$.result.resources[32].name" == "response" jsonpath "$.result.resources[32].description" == "Sourcemeta One's response to a liveness check" jsonpath "$.result.resources[32].mimeType" == "application/schema+json" jsonpath "$.result.resources[32].size" == 609 +jsonpath "$.result.resources[32].annotations.priority" == 0 jsonpath "$.result.resources[33].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/request" jsonpath "$.result.resources[33].name" == "request" jsonpath "$.result.resources[33].description" == "Any incoming MCP request the server accepts" jsonpath "$.result.resources[33].mimeType" == "application/schema+json" jsonpath "$.result.resources[33].size" == 1784 +jsonpath "$.result.resources[33].annotations.priority" == 0 jsonpath "$.result.resources[34].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/list/request" jsonpath "$.result.resources[34].name" == "request" jsonpath "$.result.resources[34].description" == "Request from a client to list MCP resources" jsonpath "$.result.resources[34].mimeType" == "application/schema+json" jsonpath "$.result.resources[34].size" == 1082 +jsonpath "$.result.resources[34].annotations.priority" == 0 jsonpath "$.result.resources[35].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/list/response" jsonpath "$.result.resources[35].name" == "response" jsonpath "$.result.resources[35].description" == "Sourcemeta One's list of MCP resources" jsonpath "$.result.resources[35].mimeType" == "application/schema+json" -jsonpath "$.result.resources[35].size" == 2547 +jsonpath "$.result.resources[35].size" == 3026 +jsonpath "$.result.resources[35].annotations.priority" == 0 jsonpath "$.result.resources[36].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/read/request" jsonpath "$.result.resources[36].name" == "request" jsonpath "$.result.resources[36].description" == "Request from a client to read an MCP resource" jsonpath "$.result.resources[36].mimeType" == "application/schema+json" jsonpath "$.result.resources[36].size" == 1342 +jsonpath "$.result.resources[36].annotations.priority" == 0 jsonpath "$.result.resources[37].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/read/response" jsonpath "$.result.resources[37].name" == "response" jsonpath "$.result.resources[37].description" == "Sourcemeta One's response containing an MCP resource" jsonpath "$.result.resources[37].mimeType" == "application/schema+json" jsonpath "$.result.resources[37].size" == 1803 +jsonpath "$.result.resources[37].annotations.priority" == 0 jsonpath "$.result.resources[38].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/templates/list/request" jsonpath "$.result.resources[38].name" == "request" jsonpath "$.result.resources[38].description" == "Request from a client to list MCP resource templates" jsonpath "$.result.resources[38].mimeType" == "application/schema+json" jsonpath "$.result.resources[38].size" == 933 +jsonpath "$.result.resources[38].annotations.priority" == 0 jsonpath "$.result.resources[39].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/resources/templates/list/response" jsonpath "$.result.resources[39].name" == "response" jsonpath "$.result.resources[39].description" == "Sourcemeta One's list of MCP resource templates" jsonpath "$.result.resources[39].mimeType" == "application/schema+json" jsonpath "$.result.resources[39].size" == 1926 +jsonpath "$.result.resources[39].annotations.priority" == 0 jsonpath "$.result.resources[40].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/response" jsonpath "$.result.resources[40].name" == "response" jsonpath "$.result.resources[40].description" == "Any outgoing MCP response the server returns" jsonpath "$.result.resources[40].mimeType" == "application/schema+json" jsonpath "$.result.resources[40].size" == 3290 +jsonpath "$.result.resources[40].annotations.priority" == 0 jsonpath "$.result.resources[41].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/tools/call/request" jsonpath "$.result.resources[41].name" == "request" jsonpath "$.result.resources[41].description" == "Request from a client to invoke an MCP tool by name" jsonpath "$.result.resources[41].mimeType" == "application/schema+json" jsonpath "$.result.resources[41].size" == 1172 +jsonpath "$.result.resources[41].annotations.priority" == 0 jsonpath "$.result.resources[42].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/tools/call/response" jsonpath "$.result.resources[42].name" == "response" jsonpath "$.result.resources[42].description" == "Sourcemeta One's response to a tool invocation" jsonpath "$.result.resources[42].mimeType" == "application/schema+json" jsonpath "$.result.resources[42].size" == 4717 +jsonpath "$.result.resources[42].annotations.priority" == 0 jsonpath "$.result.resources[43].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/tools/list/request" jsonpath "$.result.resources[43].name" == "request" jsonpath "$.result.resources[43].description" == "Request from a client to list MCP tools" jsonpath "$.result.resources[43].mimeType" == "application/schema+json" jsonpath "$.result.resources[43].size" == 864 +jsonpath "$.result.resources[43].annotations.priority" == 0 jsonpath "$.result.resources[44].uri" == "{{base}}/v1/catalog/self/v1/schemas/mcp/tools/list/response" jsonpath "$.result.resources[44].name" == "response" jsonpath "$.result.resources[44].description" == "Sourcemeta One's list of MCP tools" jsonpath "$.result.resources[44].mimeType" == "application/schema+json" jsonpath "$.result.resources[44].size" == 4085 +jsonpath "$.result.resources[44].annotations.priority" == 0 jsonpath "$.result.resources[45].uri" == "{{base}}/v1/catalog/example/full" jsonpath "$.result.resources[45].name" == "full" jsonpath "$.result.resources[45].description" == "A schema that has both a title and a description" jsonpath "$.result.resources[45].mimeType" == "application/schema+json" jsonpath "$.result.resources[45].size" == 242 +jsonpath "$.result.resources[45].annotations.priority" == 1 jsonpath "$.result.resources[46].uri" == "{{base}}/v1/catalog/example/description-only" jsonpath "$.result.resources[46].name" == "description-only" jsonpath "$.result.resources[46].description" == "A schema with only a description and no title" jsonpath "$.result.resources[46].mimeType" == "application/schema+json" jsonpath "$.result.resources[46].size" == 219 +jsonpath "$.result.resources[46].annotations.priority" == 1 jsonpath "$.result.resources[47].uri" == "{{base}}/v1/catalog/example/title-only" jsonpath "$.result.resources[47].name" == "title-only" jsonpath "$.result.resources[47].description" not exists jsonpath "$.result.resources[47].mimeType" == "application/schema+json" jsonpath "$.result.resources[47].size" == 185 +jsonpath "$.result.resources[47].annotations.priority" == 1 jsonpath "$.result.resources[48].uri" == "{{base}}/v1/catalog/draft3/object" jsonpath "$.result.resources[48].name" == "object" jsonpath "$.result.resources[48].description" not exists jsonpath "$.result.resources[48].mimeType" == "application/schema+json" jsonpath "$.result.resources[48].size" == 270 +jsonpath "$.result.resources[48].annotations.priority" == 1 jsonpath "$.result.resources[49].uri" == "{{base}}/v1/catalog/draft3/string" jsonpath "$.result.resources[49].name" == "string" jsonpath "$.result.resources[49].description" not exists jsonpath "$.result.resources[49].mimeType" == "application/schema+json" jsonpath "$.result.resources[49].size" == 136 +jsonpath "$.result.resources[49].annotations.priority" == 1 jsonpath "$.result.nextCursor" == "50" POST {{base}}/v1/catalog/self/v1/api/schemas/evaluate{{schema_path}} diff --git a/enterprise/index/enterprise_index.cc b/enterprise/index/enterprise_index.cc index 7748e8ed3..ae8a1d6c9 100644 --- a/enterprise/index/enterprise_index.cc +++ b/enterprise/index/enterprise_index.cc @@ -87,9 +87,15 @@ auto generate_mcp_resources(const std::filesystem::path &search_metapack_path, std::string uri{configuration.origin}; uri.append(entry.path); - entries.push_back(sourcemeta::core::mcp_make_resource( + auto resource{sourcemeta::core::mcp_make_resource( uri, name, "application/schema+json", entry.description, - static_cast(entry.bytes_raw))); + static_cast(entry.bytes_raw))}; + auto annotations{sourcemeta::core::JSON::make_object()}; + annotations.assign("priority", + sourcemeta::core::JSON{ + static_cast(entry.weight) / 100.0}); + resource.assign("annotations", std::move(annotations)); + entries.push_back(std::move(resource)); }); page.assign("resources", std::move(entries)); diff --git a/src/build/delta.cc b/src/build/delta.cc index 9e502f426..c6913d416 100644 --- a/src/build/delta.cc +++ b/src/build/delta.cc @@ -961,6 +961,14 @@ auto delta(const BuildPhase phase, const BuildPlan::Type build_type, } } break; + case DirectoryDependencyKind::AllSchemaMetadata: + for (const auto &schema_relative : all_relative_paths) { + rule_dependencies.push_back(append_filename( + make_base_string(output_string, EXPLORER_DIRECTORY, + schema_relative.native()), + SCHEMA_METADATA_RULE.filename)); + } + break; case DirectoryDependencyKind::ChildDirectories: for (const auto &other_directory : affected_directories) { auto other_relative{ diff --git a/src/build/rules.h b/src/build/rules.h index 7d73b3875..60de31a29 100644 --- a/src/build/rules.h +++ b/src/build/rules.h @@ -196,6 +196,7 @@ enum class DirectoryScope : std::uint8_t { AllDirectories, NonRoot, RootOnly }; enum class DirectoryDependencyKind : std::uint8_t { SchemaMetadata, + AllSchemaMetadata, ChildDirectories, AllDirectoryListings, SameDirectoryTarget, @@ -238,8 +239,10 @@ static constexpr std::array DIRECTORY_RULES{{ .scope = DirectoryScope::RootOnly, .only_full_rebuild = false, .dependencies = {{{.kind = DirectoryDependencyKind::AllDirectoryListings, + .filename = nullptr}, + {.kind = DirectoryDependencyKind::AllSchemaMetadata, .filename = nullptr}}}, - .dependency_count = 1}, + .dependency_count = 2}, {.action = BuildPlan::Action::Type::Mcp, .filename = "mcp.metapack", diff --git a/src/configuration/include/sourcemeta/one/configuration.h b/src/configuration/include/sourcemeta/one/configuration.h index bb3bbfb8c..14e19542a 100644 --- a/src/configuration/include/sourcemeta/one/configuration.h +++ b/src/configuration/include/sourcemeta/one/configuration.h @@ -26,8 +26,8 @@ struct Configuration { -> sourcemeta::core::JSON; static auto parse(const sourcemeta::core::JSON &data, const std::filesystem::path &configuration_path, - const std::filesystem::path &default_base_path) - -> Configuration; + const std::filesystem::path &default_base_path, + const std::filesystem::path &self_path) -> Configuration; sourcemeta::core::JSON::String url; sourcemeta::core::JSON::String base_path; @@ -61,6 +61,12 @@ struct Configuration { using Collection = sourcemeta::blaze::Configuration; + [[nodiscard]] static auto is_self_collection(const Collection &collection) + -> bool { + const auto *value{collection.extra.try_at("x-sourcemeta-one:is-self")}; + return value != nullptr && value->is_boolean() && value->to_boolean(); + } + [[nodiscard]] auto resolve_schema(const sourcemeta::core::URI &input) const -> std::optional; diff --git a/src/configuration/parse.cc b/src/configuration/parse.cc index 1a5e8b65d..f372d3cc8 100644 --- a/src/configuration/parse.cc +++ b/src/configuration/parse.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include "template.h" @@ -32,13 +33,14 @@ auto page_from_json(const sourcemeta::core::JSON &input) template auto entries_from_json(T &result, const std::filesystem::path &location, const sourcemeta::core::JSON &input, - const std::filesystem::path &default_base_path) -> void { + const std::filesystem::path &default_base_path, + const std::filesystem::path &self_path) -> void { // A heuristic to check if we are at the root or not if (input.defines("url")) { if (input.defines("contents")) { for (const auto &entry : input.at("contents").as_object()) { entries_from_json(result, location / entry.first, entry.second, - default_base_path); + default_base_path, self_path); } } } else { @@ -63,6 +65,14 @@ auto entries_from_json(T &result, const std::filesystem::path &location, // This URI is guaranteed to be canonicalised by the collection parser assert(collection.base == sourcemeta::core::URI::canonicalize(collection.base)); + if (collection_input.defines("x-sourcemeta-one:path") && + sourcemeta::core::is_under_path( + std::filesystem::path{ + collection_input.at("x-sourcemeta-one:path").to_string()}, + self_path)) { + collection.extra.assign("x-sourcemeta-one:is-self", + sourcemeta::core::JSON{true}); + } result.emplace(location, std::move(collection)); } else { result.emplace(location, page_from_json(input)); @@ -70,7 +80,7 @@ auto entries_from_json(T &result, const std::filesystem::path &location, if (input.defines("contents")) { for (const auto &entry : input.at("contents").as_object()) { entries_from_json(result, location / entry.first, entry.second, - default_base_path); + default_base_path, self_path); } } } @@ -83,7 +93,8 @@ namespace sourcemeta::one { auto Configuration::parse(const sourcemeta::core::JSON &data, const std::filesystem::path &configuration_path, - const std::filesystem::path &default_base_path) + const std::filesystem::path &default_base_path, + const std::filesystem::path &self_path) -> Configuration { const auto compiled_schema{sourcemeta::blaze::from_json( sourcemeta::core::parse_json(CONFIGURATION))}; @@ -140,7 +151,7 @@ auto Configuration::parse(const sourcemeta::core::JSON &data, } } - entries_from_json(result.entries, "", data, default_base_path); + entries_from_json(result.entries, "", data, default_base_path, self_path); return result; } diff --git a/src/index/explorer.h b/src/index/explorer.h index 832ce59e1..7653f7d18 100644 --- a/src/index/explorer.h +++ b/src/index/explorer.h @@ -117,6 +117,7 @@ struct MetapackExplorerSchemaExtension { std::int64_t bytes_bundled; std::int64_t dependencies; MetapackVersionInfo version; + std::uint8_t is_self; std::uint16_t path_length; std::uint16_t identifier_length; std::uint16_t base_dialect_length; @@ -292,11 +293,11 @@ explorer_extension_alert(const MetapackExplorerSchemaExtension *extension, static auto make_explorer_schema_extension( const std::int64_t health, const std::int64_t bytes, const std::int64_t bytes_bundled, const std::int64_t dependencies, - const MetapackVersionInfo &version, const std::string_view path, - const std::string_view identifier, const std::string_view base_dialect, - const std::string_view dialect, const std::string_view title, - const std::string_view description, const std::string_view alert) - -> std::vector { + const MetapackVersionInfo &version, const bool is_self, + const std::string_view path, const std::string_view identifier, + const std::string_view base_dialect, const std::string_view dialect, + const std::string_view title, const std::string_view description, + const std::string_view alert) -> std::vector { assert(path.size() <= std::numeric_limits::max()); assert(identifier.size() <= std::numeric_limits::max()); assert(base_dialect.size() <= std::numeric_limits::max()); @@ -317,6 +318,7 @@ static auto make_explorer_schema_extension( header.bytes_bundled = bytes_bundled; header.dependencies = dependencies; header.version = version; + header.is_self = is_self ? 1 : 0; header.path_length = static_cast(path.size()); header.identifier_length = static_cast(identifier.size()); header.base_dialect_length = static_cast(base_dialect.size()); @@ -454,6 +456,9 @@ struct GENERATE_EXPLORER_SCHEMA_METADATA { result.assign("alert", sourcemeta::core::JSON{nullptr}); } + const auto is_self{ + sourcemeta::one::Configuration::is_self_collection(collection)}; + result.assign("breadcrumb", make_breadcrumb(configuration.base_path, resolver_entry.relative_path, false)); @@ -467,7 +472,8 @@ struct GENERATE_EXPLORER_SCHEMA_METADATA { static_cast(schema_info.content_bytes), static_cast(bundle_info.content_bytes), result.at("dependencies").to_integer(), parse_version_info(schema_name), - result.at("path").to_string(), result.at("identifier").to_string(), + is_self, result.at("path").to_string(), + result.at("identifier").to_string(), result.at("baseDialect").to_string(), result.at("dialect").to_string(), result.defines("title") ? result.at("title").to_string() : "", result.defines("description") ? result.at("description").to_string() @@ -494,41 +500,34 @@ struct GENERATE_EXPLORER_SEARCH_INDEX { std::vector entries; for (const auto &dependency : action.dependencies) { - const auto directory_option{ - sourcemeta::one::metapack_read_json(dependency)}; - assert(directory_option.has_value()); - const auto &directory{directory_option.value()}; - assert(directory.is_object()); - assert(directory.defines("entries")); - - for (const auto &directory_entry : directory.at("entries").as_array()) { - if (!directory_entry.defines("type") || - directory_entry.at("type").to_string() != "schema") { - continue; - } - - entries.push_back( - {directory_entry.at("path").to_string(), - directory_entry.at("identifier").to_string(), - directory_entry.defines("title") - ? directory_entry.at("title").to_string() - : "", - directory_entry.defines("description") - ? directory_entry.at("description").to_string() - : "", - directory_entry.defines("health") - ? static_cast( - directory_entry.at("health").to_integer()) - : static_cast(0), - directory_entry.defines("bytes") - ? static_cast( - directory_entry.at("bytes").to_integer()) - : static_cast(0), - directory_entry.defines("bytesBundled") - ? static_cast( - directory_entry.at("bytesBundled").to_integer()) - : static_cast(0)}); + // We depend on every per-schema metapack under `explorer//%/` + // (AllSchemaMetadata) plus every directory listing + // (AllDirectoryListings, kept for wave ordering). Only the former + // carries schema entries. + if (dependency.filename() != "schema.metapack") { + continue; } + + sourcemeta::core::FileView schema_view{dependency}; + const auto *extension{ + sourcemeta::one::metapack_extension( + schema_view)}; + assert(extension != nullptr); + const auto schema_option{sourcemeta::one::metapack_read_json(dependency)}; + assert(schema_option.has_value()); + const auto &schema{schema_option.value()}; + assert(schema.is_object()); + + entries.push_back( + {schema.at("path").to_string(), schema.at("identifier").to_string(), + schema.defines("title") ? schema.at("title").to_string() : "", + schema.defines("description") ? schema.at("description").to_string() + : "", + static_cast(schema.at("health").to_integer()), + static_cast(schema.at("bytes").to_integer()), + static_cast(schema.at("bytesBundled").to_integer()), + extension->is_self != 0 ? static_cast(0) + : static_cast(100)}); } const auto payload{sourcemeta::one::make_search(std::move(entries))}; diff --git a/src/index/index.cc b/src/index/index.cc index fc17d55fb..13194550e 100644 --- a/src/index/index.cc +++ b/src/index/index.cc @@ -299,7 +299,8 @@ static auto index_main(const std::string_view &program, } auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SOURCEMETA_ONE_SELF)}; ///////////////////////////////////////////////////////////////////////////// // (3) Resolve a URI to a schema filesystem path diff --git a/src/search/include/sourcemeta/one/search.h b/src/search/include/sourcemeta/one/search.h index d8e216b18..17af978ea 100644 --- a/src/search/include/sourcemeta/one/search.h +++ b/src/search/include/sourcemeta/one/search.h @@ -27,6 +27,7 @@ struct SearchEntry { std::uint8_t health; std::uint64_t bytes_raw; std::uint64_t bytes_bundled; + std::uint8_t weight; }; struct SearchListEntry { @@ -36,6 +37,7 @@ struct SearchListEntry { std::string_view description; std::uint64_t bytes_raw; std::uint64_t bytes_bundled; + std::uint8_t weight; }; #pragma pack(push, 1) @@ -51,6 +53,7 @@ struct SearchRecordHeader { std::uint16_t description_length; std::uint64_t bytes_raw; std::uint64_t bytes_bundled; + std::uint8_t weight; }; #pragma pack(pop) diff --git a/src/search/search.cc b/src/search/search.cc index 944bf04df..f7e54da10 100644 --- a/src/search/search.cc +++ b/src/search/search.cc @@ -84,7 +84,8 @@ auto make_search(std::vector &&entries) .description_length = static_cast(entry.description.size()), .bytes_raw = entry.bytes_raw, - .bytes_bundled = entry.bytes_bundled}; + .bytes_bundled = entry.bytes_bundled, + .weight = entry.weight}; std::memcpy(payload.data() + record_position, &record_header, sizeof(SearchRecordHeader)); record_position += sizeof(SearchRecordHeader); @@ -302,7 +303,8 @@ auto SearchView::at(const std::size_t index) -> SearchListEntry { .title = title, .description = description, .bytes_raw = record_header->bytes_raw, - .bytes_bundled = record_header->bytes_bundled}; + .bytes_bundled = record_header->bytes_bundled, + .weight = record_header->weight}; } auto SearchView::for_each( @@ -379,7 +381,8 @@ auto SearchView::for_each( .title = title, .description = description, .bytes_raw = record_header->bytes_raw, - .bytes_bundled = record_header->bytes_bundled}); + .bytes_bundled = record_header->bytes_bundled, + .weight = record_header->weight}); } } diff --git a/src/self/v1/schemas/mcp/resources/list/response.json b/src/self/v1/schemas/mcp/resources/list/response.json index 2b06f527e..c45daf3b8 100644 --- a/src/self/v1/schemas/mcp/resources/list/response.json +++ b/src/self/v1/schemas/mcp/resources/list/response.json @@ -13,14 +13,20 @@ "name": "string", "description": "An example string schema", "mimeType": "application/schema+json", - "size": 143 + "size": 143, + "annotations": { + "priority": 1 + } }, { "uri": "https://example.com/v1/example/string?bundle=1", "name": "string", "description": "An example string schema", "mimeType": "application/schema+json", - "size": 143 + "size": 143, + "annotations": { + "priority": 1 + } }, { "uri": "https://example.com/v1/no-description", @@ -77,6 +83,17 @@ "size": { "type": "integer", "minimum": 0 + }, + "annotations": { + "type": "object", + "properties": { + "priority": { + "type": "number", + "maximum": 1, + "minimum": 0 + } + }, + "additionalProperties": true } }, "additionalProperties": false diff --git a/test/cli/index/common/search-index-nested-rebuild.sh b/test/cli/index/common/search-index-nested-rebuild.sh index 88c68a48b..acc9ac72b 100755 --- a/test/cli/index/common/search-index-nested-rebuild.sh +++ b/test/cli/index/common/search-index-nested-rebuild.sh @@ -54,9 +54,9 @@ EOF SEARCH="$TMP/output/explorer/%/search.metapack" extract_search_paths() { - strings "$1" | grep -E '^/(left|right)/' \ + strings "$1" | grep -oE '/(left|right)/[^[:space:]]*' \ | sed 's|https*://.*$||' \ - | LC_ALL=C sort + | LC_ALL=C sort -u } # Run 1: full build with two schemas in separate directories diff --git a/test/unit/build/build_delta_test.cc b/test/unit/build/build_delta_test.cc index 3f8d1e897..49ace979c 100644 --- a/test/unit/build/build_delta_test.cc +++ b/test/unit/build/build_delta_test.cc @@ -144,7 +144,8 @@ TEST(Build_delta, full_single_schema) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -315,7 +316,8 @@ TEST(Build_delta, incremental_missing_schema_metapack) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "bar" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -472,7 +474,9 @@ TEST(Build_delta, incremental_one_schema_added) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "bar" / "%" / "schema.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -603,7 +607,8 @@ TEST(Build_delta, full_stale_file_in_entries) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -725,7 +730,8 @@ TEST(Build_delta, full_stale_directory_in_entries) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -939,7 +945,8 @@ TEST(Build_delta, incremental_with_comment) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1057,7 +1064,8 @@ TEST(Build_delta, incremental_empty_comment_removes_existing) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1413,7 +1421,8 @@ TEST(Build_delta, full_single_schema_evaluate_false) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1526,7 +1535,8 @@ TEST(Build_delta, full_evaluate_false_removes_existing_blaze) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 7, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1637,7 +1647,8 @@ TEST(Build_delta, incremental_evaluate_false) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1711,7 +1722,8 @@ TEST(Build_delta, incremental_missing_blaze_exhaustive) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 1, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 2, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1812,7 +1824,8 @@ TEST(Build_delta, incremental_missing_bundle) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 3, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 4, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -1887,7 +1900,8 @@ TEST(Build_delta, incremental_missing_web_schema) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 1, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 2, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -2111,7 +2125,9 @@ TEST(Build_delta, mtime_source_newer) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "bar" / "%" / "schema.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -2251,7 +2267,9 @@ TEST(Build_delta, mtime_no_entry) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "bar" / "%" / "schema.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -2390,7 +2408,8 @@ TEST(Build_delta, mtime_no_file_mark) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -2568,7 +2587,9 @@ TEST(Build_delta, incremental_reverse_dep_direct) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "b" / "%" / "schema.metapack", + output / "explorer" / "a" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -2823,7 +2844,10 @@ TEST(Build_delta, incremental_reverse_dep_transitive) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "c" / "%" / "schema.metapack", + output / "explorer" / "b" / "%" / "schema.metapack", + output / "explorer" / "a" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3026,7 +3050,9 @@ TEST(Build_delta, mtime_reverse_dep) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "b" / "%" / "schema.metapack", + output / "explorer" / "a" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3150,7 +3176,8 @@ TEST(Build_delta, incremental_evaluate_false_removes_existing_blaze) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3296,7 +3323,8 @@ TEST(Build_delta, headless_full_single_schema) { EXPECT_ACTION(plan, 7, 0, 1, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3401,7 +3429,8 @@ TEST(Build_delta, headless_incremental) { EXPECT_ACTION(plan, 5, 0, 1, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3513,7 +3542,8 @@ TEST(Build_delta, full_to_headless_removes_web) { EXPECT_ACTION(plan, 6, 0, 1, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3695,7 +3725,8 @@ TEST(Build_delta, headless_to_full_incremental) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3841,7 +3872,8 @@ TEST(Build_delta, headless_to_full_full_rebuild) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 6, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 7, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -3958,7 +3990,8 @@ TEST(Build_delta, full_to_headless_full_rebuild) { EXPECT_ACTION(plan, 7, 0, 1, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -4084,10 +4117,11 @@ TEST(Build_delta, full_single_schema_nested_path_headless) { output / "explorer" / "%" / "directory.metapack", "", output / "explorer" / "example" / "%" / "directory.metapack"); - EXPECT_ACTION(plan, 8, 0, 1, SearchIndex, - output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "example" / "%" / "directory.metapack", - output / "explorer" / "%" / "directory.metapack"); + EXPECT_ACTION( + plan, 8, 0, 1, SearchIndex, output / "explorer" / "%" / "search.metapack", + "", output / "explorer" / "example" / "%" / "directory.metapack", + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "example" / "test" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 9, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -4293,7 +4327,13 @@ TEST(Build_delta, incremental_add_schema_preserves_intermediate_dirs) { output / "explorer" / "example" / "schemas" / "%" / "directory.metapack", output / "explorer" / "example" / "%" / "directory.metapack", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "example" / "schemas" / "c" / "%" / + "schema.metapack", + output / "explorer" / "example" / "schemas" / "b" / "%" / + "schema.metapack", + output / "explorer" / "example" / "schemas" / "a" / "%" / + "schema.metapack"); EXPECT_ACTION(plan, 8, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -4489,7 +4529,9 @@ TEST(Build_delta, incremental_directory_listing_includes_unchanged_siblings) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "bar" / "%" / "schema.metapack", + output / "explorer" / "foo" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", @@ -4634,7 +4676,10 @@ TEST(Build_delta, incremental_add_schema_rebuilds_all_dependents) { output / "explorer" / "%" / "directory.metapack"); EXPECT_ACTION(plan, 5, 1, 2, SearchIndex, output / "explorer" / "%" / "search.metapack", "", - output / "explorer" / "%" / "directory.metapack"); + output / "explorer" / "%" / "directory.metapack", + output / "explorer" / "c" / "%" / "schema.metapack", + output / "explorer" / "b" / "%" / "schema.metapack", + output / "explorer" / "a" / "%" / "schema.metapack"); EXPECT_ACTION(plan, 6, 0, 1, Mcp, output / "explorer" / "%" / "mcp.metapack", "", output / "explorer" / "%" / "search.metapack", diff --git a/test/unit/configuration/configuration_test.cc b/test/unit/configuration/configuration_test.cc index 41452fb4d..73a4a85f9 100644 --- a/test/unit/configuration/configuration_test.cc +++ b/test/unit/configuration/configuration_test.cc @@ -27,7 +27,8 @@ TEST(Configuration, valid_001) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -91,6 +92,13 @@ TEST(Configuration, valid_001) { EXPECT_COLLECTION(configuration, "example/extension", extra.at("x-sourcemeta-one:path"), sourcemeta::core::JSON{configuration_path.string()}); + + EXPECT_TRUE(sourcemeta::one::Configuration::is_self_collection( + std::get( + configuration.entries.at("self/v1/schemas")))); + EXPECT_FALSE(sourcemeta::one::Configuration::is_self_collection( + std::get( + configuration.entries.at("example/extension")))); } TEST(Configuration, valid_002) { @@ -99,7 +107,8 @@ TEST(Configuration, valid_002) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -124,7 +133,8 @@ TEST(Configuration, valid_003) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -165,7 +175,8 @@ TEST(Configuration, valid_004) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -216,7 +227,8 @@ TEST(Configuration, valid_005) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -267,7 +279,8 @@ TEST(Configuration, valid_006) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -318,7 +331,8 @@ TEST(Configuration, valid_007) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -369,7 +383,8 @@ TEST(Configuration, valid_008) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_TRUE(configuration.api); @@ -405,7 +420,8 @@ TEST(Configuration, base_path_none) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.base_path, ""); EXPECT_EQ(configuration.origin, "http://localhost:8000"); } @@ -416,7 +432,8 @@ TEST(Configuration, base_path_slash) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.base_path, ""); EXPECT_EQ(configuration.origin, "http://localhost:8000"); } @@ -427,7 +444,8 @@ TEST(Configuration, base_path_simple) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.base_path, "/v1/catalog"); EXPECT_EQ(configuration.origin, "http://localhost:8000"); } @@ -438,7 +456,8 @@ TEST(Configuration, base_path_trailing_slash) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.base_path, "/v1/catalog"); EXPECT_EQ(configuration.origin, "http://localhost:8000"); } @@ -449,7 +468,8 @@ TEST(Configuration, base_path_deep) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.base_path, "/api/v2/schemas"); EXPECT_EQ(configuration.origin, "http://localhost:8000"); } @@ -460,7 +480,8 @@ TEST(Configuration, origin_https_default_port) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "https://example.com/schemas"); EXPECT_EQ(configuration.base_path, "/schemas"); EXPECT_EQ(configuration.origin, "https://example.com"); @@ -472,7 +493,8 @@ TEST(Configuration, origin_custom_port) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "https://example.com:9443/api"); EXPECT_EQ(configuration.base_path, "/api"); EXPECT_EQ(configuration.origin, "https://example.com:9443"); @@ -484,7 +506,8 @@ TEST(Configuration, origin_with_userinfo) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.origin, "http://example.com"); } @@ -494,7 +517,8 @@ TEST(Configuration, origin_with_query) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.origin, "http://example.com"); } @@ -504,7 +528,8 @@ TEST(Configuration, origin_with_fragment) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.origin, "http://example.com"); } @@ -515,7 +540,8 @@ TEST(Configuration, origin_with_userinfo_query_fragment_port) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.origin, "http://example.com:8000"); } @@ -525,7 +551,8 @@ TEST(Configuration, is_collection_base_true) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_TRUE(configuration.is_collection_base("example/extension")); } @@ -535,7 +562,8 @@ TEST(Configuration, is_collection_base_false_for_page) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_FALSE(configuration.is_collection_base("example")); EXPECT_FALSE(configuration.is_collection_base("test")); } @@ -546,7 +574,8 @@ TEST(Configuration, is_collection_base_false_for_unknown) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_FALSE(configuration.is_collection_base("nonexistent")); EXPECT_FALSE(configuration.is_collection_base("example/nonexistent")); } @@ -557,7 +586,8 @@ TEST(Configuration, valid_009_api_enabled) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_EQ(configuration.base_path, ""); @@ -593,7 +623,8 @@ TEST(Configuration, valid_010_api_disabled) { const auto raw_configuration{ sourcemeta::one::Configuration::read(configuration_path, SELF_DIRECTORY)}; const auto configuration{sourcemeta::one::Configuration::parse( - raw_configuration, configuration_path, configuration_path.parent_path())}; + raw_configuration, configuration_path, configuration_path.parent_path(), + SELF_DIRECTORY)}; EXPECT_EQ(configuration.url, "http://localhost:8000"); EXPECT_EQ(configuration.base_path, ""); diff --git a/test/unit/resolver/resolver_test.cc b/test/unit/resolver/resolver_test.cc index d4c50bae0..124295698 100644 --- a/test/unit/resolver/resolver_test.cc +++ b/test/unit/resolver/resolver_test.cc @@ -16,7 +16,8 @@ class ResolverTest : public testing::Test { shared_configuration = std::make_unique( sourcemeta::one::Configuration::parse( raw_configuration, std::filesystem::path{CONFIGURATION_PATH}, - std::filesystem::path{CONFIGURATION_PATH}.parent_path())); + std::filesystem::path{CONFIGURATION_PATH}.parent_path(), + SELF_DIRECTORY)); } static auto TearDownTestSuite() -> void { shared_configuration.reset(); } diff --git a/test/unit/search/search_build_test.cc b/test/unit/search/search_build_test.cc index 1b2fab03d..3fd876bfe 100644 --- a/test/unit/search/search_build_test.cc +++ b/test/unit/search/search_build_test.cc @@ -16,7 +16,7 @@ TEST(Search_build, empty) { TEST(Search_build, single_entry) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "My Title", "A description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; EXPECT_FALSE(payload.empty()); EXPECT_GE(payload.size(), sizeof(sourcemeta::one::SearchIndexHeader)); @@ -24,7 +24,7 @@ TEST(Search_build, single_entry) { TEST(Search_build, header_single_entry) { std::vector entries{ - {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0}}; + {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -37,9 +37,9 @@ TEST(Search_build, header_single_entry) { TEST(Search_build, header_multiple_entries) { std::vector entries{ - {"/a", "http://example.com/a", "A", "Desc A", 80, 0, 0}, - {"/b", "http://example.com/b", "B", "Desc B", 80, 0, 0}, - {"/c", "http://example.com/c", "C", "Desc C", 80, 0, 0}}; + {"/a", "http://example.com/a", "A", "Desc A", 80, 0, 0, 100}, + {"/b", "http://example.com/b", "B", "Desc B", 80, 0, 0, 100}, + {"/c", "http://example.com/c", "C", "Desc C", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -52,8 +52,8 @@ TEST(Search_build, header_multiple_entries) { TEST(Search_build, offset_table) { std::vector entries{ - {"/a", "http://example.com/a", "A", "D", 80, 0, 0}, - {"/b", "http://example.com/b", "BB", "DD", 80, 0, 0}}; + {"/a", "http://example.com/a", "A", "D", 80, 0, 0, 100}, + {"/b", "http://example.com/b", "BB", "DD", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -81,7 +81,7 @@ TEST(Search_build, offset_table) { TEST(Search_build, record_fields) { std::vector entries{ {"/test/path", "http://example.com/test/path", "My Title", - "My Description", 80, 4096, 8192}}; + "My Description", 80, 4096, 8192, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -126,8 +126,8 @@ TEST(Search_build, record_fields) { TEST(Search_build, total_size) { std::vector entries{ - {"/a", "http://example.com/a", "T", "D", 80, 0, 0}, - {"/bb", "http://example.com/bb", "TT", "DD", 80, 0, 0}}; + {"/a", "http://example.com/a", "T", "D", 80, 0, 0, 100}, + {"/bb", "http://example.com/bb", "TT", "DD", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto first_fields{std::string{"/a"}.size() + @@ -147,8 +147,9 @@ TEST(Search_build, skips_entry_with_oversized_path) { const std::string oversized_path(70000, 'x'); std::vector entries{ {oversized_path, "http://example.com/oversized", "Title", "Desc", 80, 0, - 0}, - {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0}}; + 0, 100}, + {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -160,8 +161,9 @@ TEST(Search_build, skips_entry_with_oversized_path) { TEST(Search_build, skips_entry_with_oversized_identifier) { const std::string oversized_identifier(70000, 'x'); std::vector entries{ - {"/foo", oversized_identifier, "Title", "Desc", 80, 0, 0}, - {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0}}; + {"/foo", oversized_identifier, "Title", "Desc", 80, 0, 0, 100}, + {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -173,8 +175,10 @@ TEST(Search_build, skips_entry_with_oversized_identifier) { TEST(Search_build, skips_entry_with_oversized_title) { const std::string oversized_title(70000, 'x'); std::vector entries{ - {"/foo", "http://example.com/foo", oversized_title, "Desc", 80, 0, 0}, - {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0}}; + {"/foo", "http://example.com/foo", oversized_title, "Desc", 80, 0, 0, + 100}, + {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -187,8 +191,9 @@ TEST(Search_build, skips_entry_with_oversized_description) { const std::string oversized_description(70000, 'x'); std::vector entries{ {"/foo", "http://example.com/foo", "Title", oversized_description, 80, 0, - 0}, - {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0}}; + 0, 100}, + {"/normal", "http://example.com/normal", "Normal", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -200,7 +205,8 @@ TEST(Search_build, skips_entry_with_oversized_description) { TEST(Search_build, all_entries_oversized_returns_empty) { const std::string oversized(70000, 'x'); std::vector entries{ - {oversized, "http://example.com/oversized", "Title", "Desc", 80, 0, 0}}; + {oversized, "http://example.com/oversized", "Title", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; EXPECT_TRUE(payload.empty()); } @@ -208,7 +214,7 @@ TEST(Search_build, all_entries_oversized_returns_empty) { TEST(Search_build, entry_at_exact_uint16_max_is_kept) { const std::string max_path(65535, 'a'); std::vector entries{ - {max_path, "http://example.com/x", "", "", 80, 0, 0}}; + {max_path, "http://example.com/x", "", "", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; EXPECT_FALSE(payload.empty()); @@ -221,7 +227,7 @@ TEST(Search_build, entry_at_exact_uint16_max_is_kept) { TEST(Search_build, entry_at_uint16_max_plus_one_is_skipped) { const std::string too_long_path(65536, 'a'); std::vector entries{ - {too_long_path, "http://example.com/x", "", "", 80, 0, 0}}; + {too_long_path, "http://example.com/x", "", "", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; EXPECT_TRUE(payload.empty()); } diff --git a/test/unit/search/search_query_test.cc b/test/unit/search/search_query_test.cc index 972baac17..44fc6cf1f 100644 --- a/test/unit/search/search_query_test.cc +++ b/test/unit/search/search_query_test.cc @@ -42,7 +42,8 @@ TEST(Search_query, empty_payload_zero_size) { TEST(Search_query, no_match) { std::vector entries{ - {"/foo/bar", "http://example.com/foo/bar", "Title", "Desc", 80, 0, 0}}; + {"/foo/bar", "http://example.com/foo/bar", "Title", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "zzzzz", 10, @@ -54,7 +55,8 @@ TEST(Search_query, no_match) { TEST(Search_query, match_in_path) { std::vector entries{ - {"/foo/bar", "http://example.com/foo/bar", "Title", "Desc", 80, 0, 0}}; + {"/foo/bar", "http://example.com/foo/bar", "Title", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "foo", 10, @@ -68,7 +70,7 @@ TEST(Search_query, match_in_path) { TEST(Search_query, match_in_title) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "Special Title", "Desc", 80, 0, - 0}}; + 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "Special", 10, @@ -82,7 +84,7 @@ TEST(Search_query, match_in_title) { TEST(Search_query, match_in_description) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "Title", - "Unique description here", 80, 0, 0}}; + "Unique description here", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "Unique", 10, @@ -96,7 +98,7 @@ TEST(Search_query, match_in_description) { TEST(Search_query, case_insensitive) { std::vector entries_lower{ {"/foo/bar", "http://example.com/foo/bar", "Hello World", "desc", 80, 0, - 0}}; + 0, 100}}; const auto payload_lower{ sourcemeta::one::make_search(std::move(entries_lower))}; const auto result_lower{sourcemeta::one::search( @@ -109,7 +111,7 @@ TEST(Search_query, case_insensitive) { std::vector entries_upper{ {"/foo/bar", "http://example.com/foo/bar", "Hello World", "desc", 80, 0, - 0}}; + 0, 100}}; const auto payload_upper{ sourcemeta::one::make_search(std::move(entries_upper))}; const auto result_upper{sourcemeta::one::search( @@ -122,7 +124,7 @@ TEST(Search_query, case_insensitive) { std::vector entries_mixed{ {"/foo/bar", "http://example.com/foo/bar", "Hello World", "desc", 80, 0, - 0}}; + 0, 100}}; const auto payload_mixed{ sourcemeta::one::make_search(std::move(entries_mixed))}; const auto result_mixed{sourcemeta::one::search( @@ -137,11 +139,11 @@ TEST(Search_query, case_insensitive) { TEST(Search_query, multiple_matches) { std::vector entries{ {"/schemas/address", "http://example.com/schemas/address", - "Address Schema", "For addresses", 80, 0, 0}, + "Address Schema", "For addresses", 80, 0, 0, 100}, {"/schemas/person", "http://example.com/schemas/person", "Person Schema", - "For people", 80, 0, 0}, + "For people", 80, 0, 0, 100}, {"/schemas/email", "http://example.com/schemas/email", "Email Schema", - "For emails", 80, 0, 0}}; + "For emails", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schema", 10, @@ -162,35 +164,35 @@ TEST(Search_query, multiple_matches) { TEST(Search_query, limit_10) { std::vector entries{ {"/schemas/test0", "http://example.com/schemas/test0", "Test 0", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test1", "http://example.com/schemas/test1", "Test 1", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test2", "http://example.com/schemas/test2", "Test 2", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test3", "http://example.com/schemas/test3", "Test 3", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test4", "http://example.com/schemas/test4", "Test 4", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test5", "http://example.com/schemas/test5", "Test 5", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test6", "http://example.com/schemas/test6", "Test 6", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test7", "http://example.com/schemas/test7", "Test 7", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test8", "http://example.com/schemas/test8", "Test 8", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test9", "http://example.com/schemas/test9", "Test 9", "", 80, - 0, 0}, + 0, 0, 100}, {"/schemas/test10", "http://example.com/schemas/test10", "Test 10", "", - 80, 0, 0}, + 80, 0, 0, 100}, {"/schemas/test11", "http://example.com/schemas/test11", "Test 11", "", - 80, 0, 0}, + 80, 0, 0, 100}, {"/schemas/test12", "http://example.com/schemas/test12", "Test 12", "", - 80, 0, 0}, + 80, 0, 0, 100}, {"/schemas/test13", "http://example.com/schemas/test13", "Test 13", "", - 80, 0, 0}, + 80, 0, 0, 100}, {"/schemas/test14", "http://example.com/schemas/test14", "Test 14", "", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( @@ -223,9 +225,10 @@ TEST(Search_query, limit_10) { TEST(Search_query, round_trip_data_fidelity) { std::vector entries{ {"/a/b/c", "http://example.com/a/b/c", "My Title", "My Description", 80, - 0, 0}, - {"/x/y/z", "http://example.com/x/y/z", "", "Only description", 80, 0, 0}, - {"/p/q", "http://example.com/p/q", "Only title", "", 80, 0, 0}}; + 0, 0, 100}, + {"/x/y/z", "http://example.com/x/y/z", "", "Only description", 80, 0, 0, + 100}, + {"/p/q", "http://example.com/p/q", "Only title", "", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "/", 10, @@ -242,7 +245,7 @@ TEST(Search_query, round_trip_data_fidelity) { TEST(Search_query, single_entry_match) { std::vector entries{ - {"/only", "http://example.com/only", "One", "Entry", 80, 0, 0}}; + {"/only", "http://example.com/only", "One", "Entry", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "One", 10, @@ -255,7 +258,7 @@ TEST(Search_query, single_entry_match) { TEST(Search_query, single_entry_no_match) { std::vector entries{ - {"/only", "http://example.com/only", "One", "Entry", 80, 0, 0}}; + {"/only", "http://example.com/only", "One", "Entry", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "nope", 10, @@ -266,7 +269,7 @@ TEST(Search_query, single_entry_no_match) { TEST(Search_query, empty_title_and_description) { std::vector entries{ - {"/path/only", "http://example.com/path/only", "", "", 80, 0, 0}}; + {"/path/only", "http://example.com/path/only", "", "", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "path", 10, @@ -280,11 +283,11 @@ TEST(Search_query, empty_title_and_description) { TEST(Search_query, health_higher_scores_first) { std::vector entries{ {"/schemas/low", "http://example.com/schemas/low", "Low Health", "Desc", - 20, 0, 0}, + 20, 0, 0, 100}, {"/schemas/high", "http://example.com/schemas/high", "High Health", - "Desc", 100, 0, 0}, + "Desc", 100, 0, 0, 100}, {"/schemas/mid", "http://example.com/schemas/mid", "Mid Health", "Desc", - 60, 0, 0}}; + 60, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "Health", 10, @@ -303,9 +306,9 @@ TEST(Search_query, health_higher_scores_first) { TEST(Search_query, health_100_before_50) { std::vector entries{ {"/schemas/beta", "http://example.com/schemas/beta", "Beta", "Desc", 50, - 0, 0}, + 0, 0, 100}, {"/schemas/alpha", "http://example.com/schemas/alpha", "Alpha", "Desc", - 100, 0, 0}}; + 100, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -321,11 +324,11 @@ TEST(Search_query, health_100_before_50) { TEST(Search_query, health_0_ranks_last) { std::vector entries{ {"/schemas/zero", "http://example.com/schemas/zero", "Zero", "Desc", 0, 0, - 0}, + 0, 100}, {"/schemas/perfect", "http://example.com/schemas/perfect", "Perfect", - "Desc", 100, 0, 0}, + "Desc", 100, 0, 0, 100}, {"/schemas/okay", "http://example.com/schemas/okay", "Okay", "Desc", 50, - 0, 0}}; + 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -343,11 +346,11 @@ TEST(Search_query, health_0_ranks_last) { TEST(Search_query, health_same_score_sorts_by_path) { std::vector entries{ {"/schemas/zebra", "http://example.com/schemas/zebra", "Zebra", "Desc", - 75, 0, 0}, + 75, 0, 0, 100}, {"/schemas/apple", "http://example.com/schemas/apple", "Apple", "Desc", - 75, 0, 0}, + 75, 0, 0, 100}, {"/schemas/mango", "http://example.com/schemas/mango", "Mango", "Desc", - 75, 0, 0}}; + 75, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -365,9 +368,9 @@ TEST(Search_query, health_same_score_sorts_by_path) { TEST(Search_query, metadata_score_beats_health) { std::vector entries{ {"/schemas/healthy", "http://example.com/schemas/healthy", "", "", 100, 0, - 0}, + 0, 100}, {"/schemas/complete", "http://example.com/schemas/complete", "Title", - "Description", 30, 0, 0}}; + "Description", 30, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -384,9 +387,9 @@ TEST(Search_query, metadata_score_beats_health) { TEST(Search_query, metadata_score_beats_health_title_only) { std::vector entries{ {"/schemas/no-meta", "http://example.com/schemas/no-meta", "", "", 100, 0, - 0}, + 0, 100}, {"/schemas/has-title", "http://example.com/schemas/has-title", "A Title", - "", 10, 0, 0}}; + "", 10, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -402,11 +405,11 @@ TEST(Search_query, metadata_score_beats_health_title_only) { TEST(Search_query, health_tiebreaker_within_same_metadata) { std::vector entries{ {"/schemas/low-health", "http://example.com/schemas/low-health", "Title", - "", 25, 0, 0}, + "", 25, 0, 0, 100}, {"/schemas/high-health", "http://example.com/schemas/high-health", - "Title", "", 90, 0, 0}, + "Title", "", 90, 0, 0, 100}, {"/schemas/mid-health", "http://example.com/schemas/mid-health", "Title", - "", 50, 0, 0}}; + "", 50, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -423,13 +426,16 @@ TEST(Search_query, health_tiebreaker_within_same_metadata) { TEST(Search_query, health_fine_grained_ordering) { std::vector entries{ - {"/schemas/d", "http://example.com/schemas/d", "Title", "Desc", 70, 0, 0}, - {"/schemas/a", "http://example.com/schemas/a", "Title", "Desc", 100, 0, - 0}, - {"/schemas/c", "http://example.com/schemas/c", "Title", "Desc", 85, 0, 0}, - {"/schemas/e", "http://example.com/schemas/e", "Title", "Desc", 55, 0, 0}, - {"/schemas/b", "http://example.com/schemas/b", "Title", "Desc", 95, 0, - 0}}; + {"/schemas/d", "http://example.com/schemas/d", "Title", "Desc", 70, 0, 0, + 100}, + {"/schemas/a", "http://example.com/schemas/a", "Title", "Desc", 100, 0, 0, + 100}, + {"/schemas/c", "http://example.com/schemas/c", "Title", "Desc", 85, 0, 0, + 100}, + {"/schemas/e", "http://example.com/schemas/e", "Title", "Desc", 55, 0, 0, + 100}, + {"/schemas/b", "http://example.com/schemas/b", "Title", "Desc", 95, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -451,15 +457,15 @@ TEST(Search_query, health_fine_grained_ordering) { TEST(Search_query, health_mixed_metadata_and_health) { std::vector entries{ {"/schemas/full-low", "http://example.com/schemas/full-low", "Title", - "Desc", 30, 0, 0}, + "Desc", 30, 0, 0, 100}, {"/schemas/title-high", "http://example.com/schemas/title-high", "Title", - "", 95, 0, 0}, + "", 95, 0, 0, 100}, {"/schemas/full-high", "http://example.com/schemas/full-high", "Title", - "Desc", 90, 0, 0}, + "Desc", 90, 0, 0, 100}, {"/schemas/none-perfect", "http://example.com/schemas/none-perfect", "", - "", 100, 0, 0}, + "", 100, 0, 0, 100}, {"/schemas/title-low", "http://example.com/schemas/title-low", "Title", - "", 40, 0, 0}}; + "", 40, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 10, @@ -526,7 +532,7 @@ TEST(Search_query, invalid_payload_offset_points_beyond_payload) { TEST(Search_query, invalid_payload_record_field_lengths_exceed_payload) { std::vector entries{ - {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0}}; + {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0, 100}}; auto payload{sourcemeta::one::make_search(std::move(entries))}; sourcemeta::one::SearchIndexHeader header{}; @@ -588,7 +594,7 @@ TEST(Search_query, invalid_payload_random_garbage) { TEST(Search_query, invalid_payload_truncated_after_header) { std::vector entries{ - {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0}}; + {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0, 100}}; const auto full_payload{sourcemeta::one::make_search(std::move(entries))}; const auto truncated_size{sizeof(sourcemeta::one::SearchIndexHeader)}; const auto result{sourcemeta::one::search( @@ -601,7 +607,7 @@ TEST(Search_query, invalid_payload_truncated_after_header) { TEST(Search_query, invalid_payload_truncated_mid_record) { std::vector entries{ - {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0}}; + {"/foo", "http://example.com/foo", "Title", "Desc", 80, 0, 0, 100}}; const auto full_payload{sourcemeta::one::make_search(std::move(entries))}; const auto truncated_size{sizeof(sourcemeta::one::SearchIndexHeader) + sizeof(std::uint32_t) + @@ -616,11 +622,12 @@ TEST(Search_query, invalid_payload_truncated_mid_record) { TEST(Search_query, limit_1_returns_single_result) { std::vector entries{ - {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, - 0}, - {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0}, - {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, - 0}}; + {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, 0, + 100}, + {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0, + 100}, + {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 1, @@ -633,11 +640,12 @@ TEST(Search_query, limit_1_returns_single_result) { TEST(Search_query, limit_2_returns_two_results) { std::vector entries{ - {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, - 0}, - {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0}, - {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, - 0}}; + {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, 0, + 100}, + {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0, + 100}, + {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 2, @@ -652,9 +660,10 @@ TEST(Search_query, limit_2_returns_two_results) { TEST(Search_query, limit_larger_than_matches_returns_all) { std::vector entries{ - {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, - 0}, - {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0}}; + {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, 0, + 100}, + {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 100, @@ -669,8 +678,8 @@ TEST(Search_query, limit_larger_than_matches_returns_all) { TEST(Search_query, limit_0_returns_empty) { std::vector entries{ - {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, - 0}}; + {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 0, @@ -681,11 +690,12 @@ TEST(Search_query, limit_0_returns_empty) { TEST(Search_query, limit_exact_match_count) { std::vector entries{ - {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, - 0}, - {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0}, - {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, - 0}}; + {"/schemas/a", "http://example.com/schemas/a", "Alpha", "Desc", 100, 0, 0, + 100}, + {"/schemas/b", "http://example.com/schemas/b", "Beta", "Desc", 90, 0, 0, + 100}, + {"/schemas/c", "http://example.com/schemas/c", "Gamma", "Desc", 80, 0, 0, + 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 3, @@ -703,11 +713,11 @@ TEST(Search_query, limit_exact_match_count) { TEST(Search_query, limit_respects_health_ordering) { std::vector entries{ {"/schemas/low", "http://example.com/schemas/low", "Low", "Desc", 20, 0, - 0}, + 0, 100}, {"/schemas/high", "http://example.com/schemas/high", "High", "Desc", 100, - 0, 0}, + 0, 0, 100}, {"/schemas/mid", "http://example.com/schemas/mid", "Mid", "Desc", 60, 0, - 0}}; + 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas", 2, @@ -723,7 +733,7 @@ TEST(Search_query, limit_respects_health_ordering) { TEST(Search_query, scope_path_only_matches_path) { std::vector entries{ {"/unique/path", "http://example.com/unique/path", "Title", "Description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "unique", 10, @@ -737,7 +747,7 @@ TEST(Search_query, scope_path_only_matches_path) { TEST(Search_query, scope_path_only_misses_title) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "UniqueTitle", "Description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "UniqueTitle", 10, @@ -748,7 +758,7 @@ TEST(Search_query, scope_path_only_misses_title) { TEST(Search_query, scope_path_only_misses_description) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "Title", "UniqueDesc", 80, 0, - 0}}; + 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "UniqueDesc", 10, @@ -759,7 +769,7 @@ TEST(Search_query, scope_path_only_misses_description) { TEST(Search_query, scope_title_only_matches_title) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "UniqueTitle", "Description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "UniqueTitle", 10, @@ -772,7 +782,7 @@ TEST(Search_query, scope_title_only_matches_title) { TEST(Search_query, scope_title_only_misses_path) { std::vector entries{ {"/unique/path", "http://example.com/unique/path", "Title", "Description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "unique", 10, @@ -783,7 +793,7 @@ TEST(Search_query, scope_title_only_misses_path) { TEST(Search_query, scope_description_only_matches_description) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "Title", "UniqueDesc", 80, 0, - 0}}; + 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{ sourcemeta::one::search(payload.data(), payload.size(), "UniqueDesc", 10, @@ -796,7 +806,7 @@ TEST(Search_query, scope_description_only_matches_description) { TEST(Search_query, scope_description_only_misses_path) { std::vector entries{ {"/unique/path", "http://example.com/unique/path", "Title", "Description", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{ sourcemeta::one::search(payload.data(), payload.size(), "unique", 10, @@ -807,11 +817,11 @@ TEST(Search_query, scope_description_only_misses_path) { TEST(Search_query, scope_path_and_title) { std::vector entries{ {"/xyz/path", "http://example.com/xyz/path", "Needle In Title", "Other", - 80, 0, 0}, + 80, 0, 0, 100}, {"/needle/path", "http://example.com/needle/path", "Other", "Other", 80, - 0, 0}, + 0, 0, 100}, {"/abc/path", "http://example.com/abc/path", "Other", "Needle In Desc", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "Needle", 10, @@ -826,11 +836,11 @@ TEST(Search_query, scope_path_and_title) { TEST(Search_query, scope_title_and_description) { std::vector entries{ {"/abc/path", "http://example.com/abc/path", "Needle In Title", "Other", - 80, 0, 0}, + 80, 0, 0, 100}, {"/def/path", "http://example.com/def/path", "Other", "Needle In Desc", - 80, 0, 0}, + 80, 0, 0, 100}, {"/needle/path", "http://example.com/needle/path", "Other", "Other", 80, - 0, 0}}; + 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{ sourcemeta::one::search(payload.data(), payload.size(), "Needle", 10, @@ -846,11 +856,11 @@ TEST(Search_query, scope_title_and_description) { TEST(Search_query, scope_path_and_description) { std::vector entries{ {"/needle/path", "http://example.com/needle/path", "Other", "Other", 80, - 0, 0}, + 0, 0, 100}, {"/abc/path", "http://example.com/abc/path", "Needle In Title", "Other", - 80, 0, 0}, + 80, 0, 0, 100}, {"/def/path", "http://example.com/def/path", "Other", "Needle In Desc", - 80, 0, 0}}; + 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{ sourcemeta::one::search(payload.data(), payload.size(), "Needle", 10, @@ -866,7 +876,7 @@ TEST(Search_query, scope_path_and_description) { TEST(Search_query, scope_0_matches_nothing) { std::vector entries{ {"/foo/bar", "http://example.com/foo/bar", "Title", "Description", 80, 0, - 0}}; + 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{ sourcemeta::one::search(payload.data(), payload.size(), "foo", 10, 0)}; @@ -876,11 +886,11 @@ TEST(Search_query, scope_0_matches_nothing) { TEST(Search_query, scope_all_matches_any_field) { std::vector entries{ {"/unique/path", "http://example.com/unique/path", "NormalTitle", - "NormalDesc", 80, 0, 0}, + "NormalDesc", 80, 0, 0, 100}, {"/normal/path", "http://example.com/normal/path", "UniqueTitle", - "NormalDesc", 80, 0, 0}, + "NormalDesc", 80, 0, 0, 100}, {"/normal/path2", "http://example.com/normal/path2", "NormalTitle", - "UniqueDesc", 80, 0, 0}}; + "UniqueDesc", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "Unique", 10, @@ -900,9 +910,9 @@ TEST(Search_query, scope_all_matches_any_field) { TEST(Search_query, scope_combined_with_limit) { std::vector entries{ - {"/a", "http://example.com/a", "Match A", "Desc", 100, 0, 0}, - {"/b", "http://example.com/b", "Match B", "Desc", 90, 0, 0}, - {"/c", "http://example.com/c", "Match C", "Desc", 80, 0, 0}}; + {"/a", "http://example.com/a", "Match A", "Desc", 100, 0, 0, 100}, + {"/b", "http://example.com/b", "Match B", "Desc", 90, 0, 0, 100}, + {"/c", "http://example.com/c", "Match C", "Desc", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "Match", 2, @@ -918,7 +928,7 @@ TEST(Search_query, query_with_embedded_null_does_not_match) { using namespace std::string_view_literals; std::vector entries{ {"/schemas/test", "http://example.com/schemas/test", "Title", - "Description", 80, 0, 0}}; + "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "sche\0mas"sv, 10, @@ -930,7 +940,7 @@ TEST(Search_query, query_with_embedded_null_does_not_match) { TEST(Search_query, query_with_tab_does_not_match) { std::vector entries{ {"/schemas/test", "http://example.com/schemas/test", "Title", - "Description", 80, 0, 0}}; + "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas\ttest", 10, @@ -942,7 +952,7 @@ TEST(Search_query, query_with_tab_does_not_match) { TEST(Search_query, query_with_newline_does_not_match) { std::vector entries{ {"/schemas/test", "http://example.com/schemas/test", "Title", - "Description", 80, 0, 0}}; + "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "schemas\ntest", 10, @@ -954,7 +964,7 @@ TEST(Search_query, query_with_newline_does_not_match) { TEST(Search_query, entry_with_null_in_path_found_by_other_content) { std::vector entries{ {std::string("before\0after", 12), "http://example.com/null-path", - "Title", "Description", 80, 0, 0}}; + "Title", "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "after", 10, @@ -965,7 +975,7 @@ TEST(Search_query, entry_with_null_in_path_found_by_other_content) { TEST(Search_query, entry_with_null_in_title_found_by_path) { std::vector entries{ {"/schemas/test", "http://example.com/schemas/test", - std::string("Foo\0Bar", 7), "Description", 80, 0, 0}}; + std::string("Foo\0Bar", 7), "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search(payload.data(), payload.size(), "schemas", 10, @@ -977,7 +987,7 @@ TEST(Search_query, query_only_null_bytes_matches_nothing) { using namespace std::string_view_literals; std::vector entries{ {"/schemas/test", "http://example.com/schemas/test", "Title", - "Description", 80, 0, 0}}; + "Description", 80, 0, 0, 100}}; const auto payload{sourcemeta::one::make_search(std::move(entries))}; const auto result{sourcemeta::one::search( payload.data(), payload.size(), "\0\0\0"sv, 10, diff --git a/test/unit/search/search_view_for_each_test.cc b/test/unit/search/search_view_for_each_test.cc index 678fe394f..080d7446a 100644 --- a/test/unit/search/search_view_for_each_test.cc +++ b/test/unit/search/search_view_for_each_test.cc @@ -77,11 +77,11 @@ static auto collect(sourcemeta::one::SearchView &view, std::size_t offset, TEST(Search_view_for_each, visits_full_range) { const auto path{test_path("for_each_full.metapack")}; write_search_file(path, {{"/zebra", "http://example.com/zebra", "Zebra Title", - "Zebra Desc", 80, 11, 22}, + "Zebra Desc", 80, 11, 22, 100}, {"/apple", "http://example.com/apple", "Apple Title", - "Apple Desc", 80, 33, 44}, + "Apple Desc", 80, 33, 44, 100}, {"/mango", "http://example.com/mango", "Mango Title", - "Mango Desc", 80, 55, 66}}); + "Mango Desc", 80, 55, 66, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 0, 3), (std::vector{ {.path = "/apple", @@ -107,10 +107,11 @@ TEST(Search_view_for_each, visits_full_range) { TEST(Search_view_for_each, visits_subset_with_offset) { const auto path{test_path("for_each_offset.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}, - {"/c", "http://example.com/c", "C Title", "C Desc", 80, 5, 6}, - {"/d", "http://example.com/d", "D Title", "D Desc", 80, 7, 8}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}, + {"/c", "http://example.com/c", "C Title", "C Desc", 80, 5, 6, 100}, + {"/d", "http://example.com/d", "D Title", "D Desc", 80, 7, 8, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 1, 2), (std::vector{{.path = "/b", @@ -130,8 +131,9 @@ TEST(Search_view_for_each, visits_subset_with_offset) { TEST(Search_view_for_each, clamps_count_to_total) { const auto path{test_path("for_each_clamp.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 1, 100), (std::vector{{.path = "/b", @@ -145,16 +147,17 @@ TEST(Search_view_for_each, clamps_count_to_total) { TEST(Search_view_for_each, skips_when_offset_at_end) { const auto path{test_path("for_each_end.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 2, 10), std::vector{}); } TEST(Search_view_for_each, skips_when_offset_past_end) { const auto path{test_path("for_each_past_end.metapack")}; - write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}}); + write_search_file(path, {{"/a", "http://example.com/a", "A Title", "A Desc", + 80, 1, 2, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 99, 10), std::vector{}); } @@ -162,8 +165,9 @@ TEST(Search_view_for_each, skips_when_offset_past_end) { TEST(Search_view_for_each, skips_when_count_zero) { const auto path{test_path("for_each_zero.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 0, 0), std::vector{}); } @@ -171,9 +175,9 @@ TEST(Search_view_for_each, skips_when_count_zero) { TEST(Search_view_for_each, visit_order_matches_at) { const auto path{test_path("for_each_matches_at.metapack")}; write_search_file( - path, {{"/zebra", "http://example.com/zebra", "", "", 80, 11, 22}, - {"/apple", "http://example.com/apple", "", "", 80, 33, 44}, - {"/mango", "http://example.com/mango", "", "", 80, 55, 66}}); + path, {{"/zebra", "http://example.com/zebra", "", "", 80, 11, 22, 100}, + {"/apple", "http://example.com/apple", "", "", 80, 33, 44, 100}, + {"/mango", "http://example.com/mango", "", "", 80, 55, 66, 100}}); sourcemeta::one::SearchView view{path}; const auto from_for_each{collect(view, 0, view.count())}; std::vector from_at; @@ -191,8 +195,8 @@ TEST(Search_view_for_each, visit_order_matches_at) { TEST(Search_view_for_each, empty_strings_for_empty_metadata) { const auto path{test_path("for_each_empty_meta.metapack")}; - write_search_file( - path, {{"/only/path", "http://example.com/only/path", "", "", 80, 7, 8}}); + write_search_file(path, {{"/only/path", "http://example.com/only/path", "", + "", 80, 7, 8, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ( collect(view, 0, 1), @@ -207,8 +211,9 @@ TEST(Search_view_for_each, empty_strings_for_empty_metadata) { TEST(Search_view_for_each, count_size_max_does_not_overflow) { const auto path{test_path("for_each_count_max.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 0, std::numeric_limits::max()), (std::vector{{.path = "/a", @@ -228,8 +233,9 @@ TEST(Search_view_for_each, count_size_max_does_not_overflow) { TEST(Search_view_for_each, count_size_max_with_offset_does_not_overflow) { const auto path{test_path("for_each_count_max_offset.metapack")}; write_search_file( - path, {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2}, - {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4}}); + path, + {{"/a", "http://example.com/a", "A Title", "A Desc", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B Title", "B Desc", 80, 3, 4, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(collect(view, 1, std::numeric_limits::max()), (std::vector{{.path = "/b", @@ -278,7 +284,7 @@ TEST(Search_view_for_each, malformed_record_offset_out_of_bounds_stops) { TEST(Search_view_for_each, malformed_record_field_lengths_stops) { const auto path{test_path("for_each_malformed_record_field.metapack")}; auto payload{sourcemeta::one::make_search( - {{"/foo", "http://example.com/foo", "Title", "Desc", 80, 1, 2}})}; + {{"/foo", "http://example.com/foo", "Title", "Desc", 80, 1, 2, 100}})}; sourcemeta::one::SearchIndexHeader header{}; std::memcpy(&header, payload.data(), sizeof(sourcemeta::one::SearchIndexHeader)); diff --git a/test/unit/search/search_view_test.cc b/test/unit/search/search_view_test.cc index 14e3563ff..174328fd1 100644 --- a/test/unit/search/search_view_test.cc +++ b/test/unit/search/search_view_test.cc @@ -33,7 +33,7 @@ static auto write_search_file(const std::filesystem::path &path, TEST(Search_view, count_single_entry) { const auto path{test_path("count_single.metapack")}; write_search_file(path, {{"/foo", "http://example.com/foo", "Title", "Desc", - 80, 100, 200}}); + 80, 100, 200, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(view.count(), 1); } @@ -41,9 +41,9 @@ TEST(Search_view, count_single_entry) { TEST(Search_view, count_multiple_entries) { const auto path{test_path("count_multiple.metapack")}; write_search_file(path, - {{"/a", "http://example.com/a", "A", "Da", 80, 1, 2}, - {"/b", "http://example.com/b", "B", "Db", 80, 3, 4}, - {"/c", "http://example.com/c", "C", "Dc", 80, 5, 6}}); + {{"/a", "http://example.com/a", "A", "Da", 80, 1, 2, 100}, + {"/b", "http://example.com/b", "B", "Db", 80, 3, 4, 100}, + {"/c", "http://example.com/c", "C", "Dc", 80, 5, 6, 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(view.count(), 3); } @@ -51,7 +51,7 @@ TEST(Search_view, count_multiple_entries) { TEST(Search_view, at_returns_field_data) { const auto path{test_path("at_fields.metapack")}; write_search_file(path, {{"/foo/bar", "http://example.com/foo/bar", - "My Title", "My Description", 80, 100, 200}}); + "My Title", "My Description", 80, 100, 200, 100}}); sourcemeta::one::SearchView view{path}; const auto entry{view.at(0)}; EXPECT_EQ(entry.path, "/foo/bar"); @@ -66,9 +66,10 @@ TEST(Search_view, at_walks_in_sorted_order) { const auto path{test_path("at_sorted.metapack")}; write_search_file( path, - {{"/zebra", "http://example.com/zebra", "Title", "Desc", 80, 11, 22}, - {"/apple", "http://example.com/apple", "Title", "Desc", 80, 33, 44}, - {"/mango", "http://example.com/mango", "Title", "Desc", 80, 55, 66}}); + {{"/zebra", "http://example.com/zebra", "Title", "Desc", 80, 11, 22, 100}, + {"/apple", "http://example.com/apple", "Title", "Desc", 80, 33, 44, 100}, + {"/mango", "http://example.com/mango", "Title", "Desc", 80, 55, 66, + 100}}); sourcemeta::one::SearchView view{path}; EXPECT_EQ(view.count(), 3); EXPECT_EQ(view.at(0).path, "/apple"); @@ -87,8 +88,8 @@ TEST(Search_view, at_walks_in_sorted_order) { TEST(Search_view, at_returns_empty_strings_for_empty_metadata) { const auto path{test_path("at_empty_meta.metapack")}; - write_search_file( - path, {{"/only/path", "http://example.com/only/path", "", "", 80, 7, 8}}); + write_search_file(path, {{"/only/path", "http://example.com/only/path", "", + "", 80, 7, 8, 100}}); sourcemeta::one::SearchView view{path}; const auto entry{view.at(0)}; EXPECT_EQ(entry.path, "/only/path");