diff --git a/modules/library/src/test/scala/zio/elasticsearch/ElasticSortSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/ElasticSortSpec.scala new file mode 100644 index 000000000..78867520c --- /dev/null +++ b/modules/library/src/test/scala/zio/elasticsearch/ElasticSortSpec.scala @@ -0,0 +1,435 @@ +package zio.elasticsearch + +import zio.Scope +import zio.elasticsearch.ElasticSort._ +import zio.elasticsearch.domain._ +import zio.elasticsearch.query.sort.Missing._ +import zio.elasticsearch.query.sort.NumericType.{Long => NumTypeLong} +import zio.elasticsearch.query.sort.SortMode._ +import zio.elasticsearch.query.sort.SortOrder._ +import zio.elasticsearch.query.sort.SourceType.NumberType +import zio.elasticsearch.query.sort._ +import zio.elasticsearch.script.Script +import zio.elasticsearch.utils._ +import zio.test.Assertion.equalTo +import zio.test._ + +object ElasticSortSpec extends ZIOSpecDefault { + def spec: Spec[Environment with TestEnvironment with Scope, Any] = { + suite("ElasticSort")( + suite("constructing")( + test("sortByField") { + val sort = sortBy("day_of_week") + val sortTs = sortBy(TestDocument.intField) + val sortTsWithFormat = sortBy(TestDocument.dateField).format("strict_date_optional_time_nanos") + val sortTsWithMissing = sortBy(TestDocument.intField).missing(First) + val sortTsWithMode = sortBy(TestSubDocument.intFieldList).mode(Avg) + val sortTsWithNumericType = sortBy(TestDocument.intField).numericType(NumTypeLong) + val sortTsWithOrder = sortBy(TestDocument.intField).order(Desc) + val sortTsWithUnmappedType = sortBy(TestDocument.intField).unmappedType("long") + val sortTsWithAllParams = sortBy(TestDocument.dateField) + .format("strict_date_optional_time_nanos") + .missing(First) + .mode(Avg) + .numericType(NumTypeLong) + .order(Desc) + .unmappedType("long") + val sortByCount = SortByField.byCount + val sortByDoc = SortByField.byDoc + val sortByKey = SortByField.byKey + val sortByScore = SortByField.byScore + + assert(sort)( + equalTo( + SortByFieldOptions( + field = "day_of_week", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && + assert(sortTs)( + equalTo( + SortByFieldOptions( + field = "intField", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortTsWithFormat)( + equalTo( + SortByFieldOptions( + field = "dateField", + format = Some("strict_date_optional_time_nanos"), + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortTsWithMissing)( + equalTo( + SortByFieldOptions( + field = "intField", + format = None, + missing = Some(First), + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortTsWithMode)( + equalTo( + SortByFieldOptions( + field = "intFieldList", + format = None, + missing = None, + mode = Some(Avg), + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortTsWithNumericType)( + equalTo( + SortByFieldOptions( + field = "intField", + format = None, + missing = None, + mode = None, + numericType = Some(NumTypeLong), + order = None, + unmappedType = None + ) + ) + ) && assert(sortTsWithOrder)( + equalTo( + SortByFieldOptions( + field = "intField", + format = None, + missing = None, + mode = None, + numericType = None, + order = Some(Desc), + unmappedType = None + ) + ) + ) && assert(sortTsWithUnmappedType)( + equalTo( + SortByFieldOptions( + field = "intField", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = Some("long") + ) + ) + ) && assert(sortTsWithAllParams)( + equalTo( + SortByFieldOptions( + field = "dateField", + format = Some("strict_date_optional_time_nanos"), + missing = Some(First), + mode = Some(Avg), + numericType = Some(NumTypeLong), + order = Some(Desc), + unmappedType = Some("long") + ) + ) + ) && assert(sortByCount)( + equalTo( + SortByFieldOptions( + field = "_count", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortByDoc)( + equalTo( + SortByFieldOptions( + field = "_doc", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortByKey)( + equalTo( + SortByFieldOptions( + field = "_key", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) && assert(sortByScore)( + equalTo( + SortByFieldOptions( + field = "_score", + format = None, + missing = None, + mode = None, + numericType = None, + order = None, + unmappedType = None + ) + ) + ) + }, + test("sortByScript") { + val sort = sortBy(script = Script("doc['day_of_week'].value"), sourceType = NumberType) + val sortWithMode = + sortBy(Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2), NumberType) + .mode(Avg) + val sortWithOrder = + sortBy(Script(source = "doc['day_of_week'].value").lang("painless"), NumberType).order(Desc) + val sortWithModeAndOrder = sortBy( + Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2).lang("painless"), + NumberType + ).mode(Avg).order(Asc) + + assert(sort)( + equalTo( + SortByScriptOptions( + script = Script(source = "doc['day_of_week'].value", params = Map.empty, lang = None), + sourceType = NumberType, + mode = None, + order = None + ) + ) + ) && assert(sortWithMode)( + equalTo( + SortByScriptOptions( + script = Script( + source = "doc['day_of_week'].value * params['factor']", + params = Map("factor" -> 2), + lang = None + ), + sourceType = NumberType, + mode = Some(Avg), + order = None + ) + ) + ) && assert(sortWithOrder)( + equalTo( + SortByScriptOptions( + script = Script(source = "doc['day_of_week'].value", params = Map.empty, lang = Some("painless")), + sourceType = NumberType, + mode = None, + order = Some(Desc) + ) + ) + ) && assert(sortWithModeAndOrder)( + equalTo( + SortByScriptOptions( + script = Script( + source = "doc['day_of_week'].value * params['factor']", + params = Map("factor" -> 2), + lang = Some("painless") + ), + sourceType = NumberType, + mode = Some(Avg), + order = Some(Asc) + ) + ) + ) + } + ), + suite("encoding as JSON")( + test("sortByField") { + val sort = sortBy(TestDocument.intField) + val sortWithFormat = sortBy(TestDocument.dateField).format("strict_date_optional_time_nanos") + val sortWithMissing = sortBy(TestDocument.intField).missing(First) + val sortWithMode = sortBy(TestSubDocument.intFieldList).mode(Avg) + val sortWithNumericType = sortBy(TestDocument.intField).numericType(NumTypeLong) + val sortWithOrder = sortBy(TestDocument.intField).order(Desc) + val sortWithUnmappedType = sortBy(TestDocument.intField).unmappedType("long") + val sortWithAllParams = sortBy(TestDocument.dateField) + .format("strict_date_optional_time_nanos") + .missing(First) + .mode(Avg) + .numericType(NumTypeLong) + .order(Desc) + .unmappedType("long") + + val expected = + """ + |"intField" + |""".stripMargin + + val expectedWithFormat = + """ + |{ + | "dateField": { + | "format": "strict_date_optional_time_nanos" + | } + |} + |""".stripMargin + + val expectedWithMissing = + """ + |{ + | "intField": { + | "missing": "_first" + | } + |} + |""".stripMargin + + val expectedWithMode = + """ + |{ + | "intFieldList": { + | "mode": "avg" + | } + |} + |""".stripMargin + + val expectedWithNumericType = + """ + |{ + | "intField": { + | "numeric_type": "long" + | } + |} + |""".stripMargin + + val expectedWithOrder = + """ + |{ + | "intField": { + | "order": "desc" + | } + |} + |""".stripMargin + + val expectedWithUnmappedType = + """ + |{ + | "intField": { + | "unmapped_type": "long" + | } + |} + |""".stripMargin + + val expectedWithAllParams = + """ + |{ + | "dateField": { + | "format": "strict_date_optional_time_nanos", "missing": "_first", "mode": "avg", "numeric_type": "long", "order": "desc", "unmapped_type": "long" + | } + |} + |""".stripMargin + + assert(sort.paramsToJson)(equalTo(expected.toJson)) && + assert(sortWithFormat.paramsToJson)(equalTo(expectedWithFormat.toJson)) && + assert(sortWithMissing.paramsToJson)(equalTo(expectedWithMissing.toJson)) && + assert(sortWithMode.paramsToJson)(equalTo(expectedWithMode.toJson)) && + assert(sortWithNumericType.paramsToJson)(equalTo(expectedWithNumericType.toJson)) && + assert(sortWithOrder.paramsToJson)(equalTo(expectedWithOrder.toJson)) && + assert(sortWithUnmappedType.paramsToJson)(equalTo(expectedWithUnmappedType.toJson)) && + assert(sortWithAllParams.paramsToJson)(equalTo(expectedWithAllParams.toJson)) + }, + test("sortByScript") { + val sort = sortBy(script = Script("doc['day_of_week'].value"), sourceType = NumberType) + val sortWithMode = sortBy( + script = Script("doc['day_of_week'].value * params['factor']").params("factor" -> 2), + sourceType = NumberType + ).mode(Avg) + val sortWithOrder = + sortBy(script = Script("doc['day_of_week'].value").lang("painless"), sourceType = NumberType).order(Desc) + val sortWithModeAndOrder = sortBy( + Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2).lang("painless"), + NumberType + ).mode(Avg).order(Asc) + + val expected = + """ + |{ + | "_script": { + | "type": "number", + | "script": { + | "source": "doc['day_of_week'].value" + | } + | } + |} + |""".stripMargin + + val expectedWithMode = + """ + |{ + | "_script": { + | "type": "number", + | "script": { + | "source": "doc['day_of_week'].value * params['factor']", + | "params": { + | "factor": 2 + | } + | }, + | "mode": "avg" + | } + |} + |""".stripMargin + + val expectedWithOrder = + """ + |{ + | "_script": { + | "type": "number", + | "script": { + | "lang": "painless", + | "source": "doc['day_of_week'].value" + | }, + | "order": "desc" + | } + |} + |""".stripMargin + + val expectedWithModeAndOrder = + """ + |{ + | "_script": { + | "type": "number", + | "script": { + | "lang": "painless", + | "source": "doc['day_of_week'].value * params['factor']", + | "params": { + | "factor": 2 + | } + | }, + | "mode": "avg", + | "order": "asc" + | } + |} + |""".stripMargin + + assert(sort.paramsToJson)(equalTo(expected.toJson)) && + assert(sortWithMode.paramsToJson)(equalTo(expectedWithMode.toJson)) && + assert(sortWithOrder.paramsToJson)(equalTo(expectedWithOrder.toJson)) && + assert(sortWithModeAndOrder.paramsToJson)(equalTo(expectedWithModeAndOrder.toJson)) + } + ) + ) + } +} diff --git a/modules/library/src/test/scala/zio/elasticsearch/SortSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/SortSpec.scala deleted file mode 100644 index 07c118076..000000000 --- a/modules/library/src/test/scala/zio/elasticsearch/SortSpec.scala +++ /dev/null @@ -1,529 +0,0 @@ -package zio.elasticsearch - -import zio.elasticsearch.ElasticSort._ -import zio.elasticsearch.domain._ -import zio.elasticsearch.query.sort.Missing._ -import zio.elasticsearch.query.sort.NumericType.{Long => NumTypeLong} -import zio.elasticsearch.query.sort.SortMode._ -import zio.elasticsearch.query.sort.SortOrder._ -import zio.elasticsearch.query.sort.SourceType.NumberType -import zio.elasticsearch.query.sort._ -import zio.elasticsearch.script.Script -import zio.elasticsearch.utils._ -import zio.json.ast.Json -import zio.json.ast.Json.{Arr, Obj} -import zio.test.Assertion.equalTo -import zio.test._ -import zio.{Chunk, Scope} - -object SortSpec extends ZIOSpecDefault { - def spec: Spec[Environment with TestEnvironment with Scope, Any] = - suite("Sort by")( - suite("creating SortByField")( - test("successfully create SortByField with only field given") { - assert(sortBy("day_of_week"))( - equalTo( - SortByFieldOptions( - field = "day_of_week", - format = None, - missing = None, - mode = None, - numericType = None, - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with only field given") { - assert(sortBy(TestDocument.intField))( - equalTo( - SortByFieldOptions( - field = "intField", - format = None, - missing = None, - mode = None, - numericType = None, - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `format`") { - assert(sortBy(TestDocument.dateField).format("strict_date_optional_time_nanos"))( - equalTo( - SortByFieldOptions( - field = "dateField", - format = Some("strict_date_optional_time_nanos"), - missing = None, - mode = None, - numericType = None, - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `missing`") { - assert(sortBy(TestDocument.intField).missing(First))( - equalTo( - SortByFieldOptions( - field = "intField", - format = None, - missing = Some(First), - mode = None, - numericType = None, - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `mode`") { - assert(sortBy(TestSubDocument.intFieldList).mode(Avg))( - equalTo( - SortByFieldOptions( - field = "intFieldList", - format = None, - missing = None, - mode = Some(Avg), - numericType = None, - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `numericType`") { - assert(sortBy(TestDocument.intField).numericType(NumTypeLong))( - equalTo( - SortByFieldOptions( - field = "intField", - format = None, - missing = None, - mode = None, - numericType = Some(NumTypeLong), - order = None, - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `order`") { - assert(sortBy(TestDocument.intField).order(Desc))( - equalTo( - SortByFieldOptions( - field = "intField", - format = None, - missing = None, - mode = None, - numericType = None, - order = Some(Desc), - unmappedType = None - ) - ) - ) - }, - test("successfully create type-safe SortByField with given `unmappedType`") { - assert(sortBy(TestDocument.intField).unmappedType("long"))( - equalTo( - SortByFieldOptions( - field = "intField", - format = None, - missing = None, - mode = None, - numericType = None, - order = None, - unmappedType = Some("long") - ) - ) - ) - }, - test("successfully create type-safe SortByField with given all params") { - assert( - sortBy(TestDocument.dateField) - .format("strict_date_optional_time_nanos") - .missing(First) - .mode(Avg) - .numericType(NumTypeLong) - .order(Desc) - .unmappedType("long") - )( - equalTo( - SortByFieldOptions( - field = "dateField", - format = Some("strict_date_optional_time_nanos"), - missing = Some(First), - mode = Some(Avg), - numericType = Some(NumTypeLong), - order = Some(Desc), - unmappedType = Some("long") - ) - ) - ) - }, - test("successfully create SortByScript without additional fields") { - assert(sortBy(script = Script("doc['day_of_week'].value"), sourceType = NumberType))( - equalTo( - SortByScriptOptions( - script = Script(source = "doc['day_of_week'].value", params = Map.empty, lang = None), - sourceType = NumberType, - mode = None, - order = None - ) - ) - ) - }, - test("successfully create SortByScript with given `mode`") { - assert( - sortBy(Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2), NumberType) - .mode(Avg) - )( - equalTo( - SortByScriptOptions( - script = Script( - source = "doc['day_of_week'].value * params['factor']", - params = Map("factor" -> 2), - lang = None - ), - sourceType = NumberType, - mode = Some(Avg), - order = None - ) - ) - ) - }, - test("successfully create SortByScript with given `order`") { - assert(sortBy(Script(source = "doc['day_of_week'].value").lang("painless"), NumberType).order(Desc))( - equalTo( - SortByScriptOptions( - script = Script(source = "doc['day_of_week'].value", params = Map.empty, lang = Some("painless")), - sourceType = NumberType, - mode = None, - order = Some(Desc) - ) - ) - ) - }, - test("successfully create SortByScript with given `mode` and `order`") { - assert( - sortBy( - Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2).lang("painless"), - NumberType - ) - .mode(Avg) - .order(Asc) - )( - equalTo( - SortByScriptOptions( - script = Script( - source = "doc['day_of_week'].value * params['factor']", - params = Map("factor" -> 2), - lang = Some("painless") - ), - sourceType = NumberType, - mode = Some(Avg), - order = Some(Asc) - ) - ) - ) - } - ), - suite("encoding SortBy as JSON")( - test("properly encode SortByField with only field") { - val sort = sortBy(TestDocument.intField) - val expected = - """ - |{ - | "sort": [ - | "intField" - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `format` given") { - val sort = sortBy(TestDocument.dateField).format("strict_date_optional_time_nanos") - val expected = - """ - |{ - | "sort": [ - | { - | "dateField": { - | "format": "strict_date_optional_time_nanos" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `missing` given") { - val sort = sortBy(TestDocument.intField).missing(First) - val expected = - """ - |{ - | "sort": [ - | { - | "intField": { - | "missing": "_first" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `mode` given") { - val sort = sortBy(TestSubDocument.intFieldList).mode(Avg) - val expected = - """ - |{ - | "sort": [ - | { - | "intFieldList": { - | "mode": "avg" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `numericType` given") { - val sort = sortBy(TestDocument.intField).numericType(NumTypeLong) - val expected = - """ - |{ - | "sort": [ - | { - | "intField": { - | "numeric_type": "long" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `order` given") { - val sort = sortBy(TestDocument.intField).order(Desc) - val expected = - """ - |{ - | "sort": [ - | { - | "intField": { - | "order": "desc" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with `unmappedType` given") { - val sort = sortBy(TestDocument.intField).unmappedType("long") - val expected = - """ - |{ - | "sort": [ - | { - | "intField": { - | "unmapped_type": "long" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField with all params given") { - val sort = sortBy(TestDocument.dateField) - .format("strict_date_optional_time_nanos") - .missing(First) - .mode(Avg) - .numericType(NumTypeLong) - .order(Desc) - .unmappedType("long") - val expected = - """ - |{ - | "sort": [ - | { - | "dateField": { - | "format": "strict_date_optional_time_nanos", "missing": "_first", "mode": "avg", "numeric_type": "long", "order": "desc", "unmapped_type": "long" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode multiple SortByField") { - val sort1 = sortBy(TestDocument.intField).order(Desc) - val sort2 = sortBy("day_of_month").missing(First) - val expected = - """ - |{ - | "sort": [ - | { - | "intField": { - | "order": "desc" - | } - | }, - | { - | "day_of_month": { - | "missing": "_first" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort1, sort2))(equalTo(expected.toJson)) - }, - test("properly encode SortByScript without additional params") { - val sort = sortBy(script = Script("doc['day_of_week'].value"), sourceType = NumberType) - val expected = - """ - |{ - | "sort": [ - | { - | "_script": { - | "type": "number", - | "script": { - | "source": "doc['day_of_week'].value" - | } - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByScript with given `mode`") { - val sort = sortBy( - script = Script("doc['day_of_week'].value * params['factor']").params("factor" -> 2), - sourceType = NumberType - ) - .mode(Avg) - val expected = - """ - |{ - | "sort": [ - | { - | "_script": { - | "type": "number", - | "script": { - | "source": "doc['day_of_week'].value * params['factor']", - | "params": { - | "factor": 2 - | } - | }, - | "mode": "avg" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByScript with given `order`") { - val sort = - sortBy(script = Script("doc['day_of_week'].value").lang("painless"), sourceType = NumberType).order(Desc) - val expected = - """ - |{ - | "sort": [ - | { - | "_script": { - | "type": "number", - | "script": { - | "lang": "painless", - | "source": "doc['day_of_week'].value" - | }, - | "order": "desc" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByScript with `mode` and `order`") { - val sort = sortBy( - Script(source = "doc['day_of_week'].value * params['factor']").params("factor" -> 2).lang("painless"), - NumberType - ) - .mode(Avg) - .order(Asc) - val expected = - """ - |{ - | "sort": [ - | { - | "_script": { - | "type": "number", - | "script": { - | "lang": "painless", - | "source": "doc['day_of_week'].value * params['factor']", - | "params": { - | "factor": 2 - | } - | }, - | "mode": "avg", - | "order": "asc" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort))(equalTo(expected.toJson)) - }, - test("properly encode SortByField and SortByScript") { - val sort1 = sortBy("day_of_month").order(Desc) - val sort2 = sortBy(Script(source = "doc['day_of_week'].value").lang("painless"), NumberType).order(Asc) - val expected = - """ - |{ - | "sort": [ - | { - | "day_of_month": { - | "order": "desc" - | } - | }, - | { - | "_script": { - | "type": "number", - | "script": { - | "lang": "painless", - | "source": "doc['day_of_week'].value" - | }, - | "order": "asc" - | } - | } - | ] - |} - |""".stripMargin - - assert(sortsToJson(sort1, sort2))(equalTo(expected.toJson)) - } - ) - ) - - private def sortsToJson(sorts: Sort*): Json = Obj("sort" -> Arr(Chunk.fromIterable(sorts).map(_.paramsToJson))) -}