Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOPE-239: implemented all objectFunctions with extensions for cm and added tests #64

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

class ObjectAddExpression(
objectExpression: TypeExpression<ObjectType>,
newAttributeKey: TypeExpression<StringType>,
newAttributeValue: TypeExpression<out ValidType>,
Comment on lines +12 to +13
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be a ObjectEntryPrimitive?

) : FunctionExpression<ObjectType>("OBJECT_ADD", objectExpression, newAttributeKey, newAttributeValue)

fun TypeExpression<ObjectType>.addAttribute(key: TypeExpression<StringType>, value: TypeExpression<out ValidType>) =
ObjectAddExpression(this, key, value)

fun TypeExpression<ObjectType>.addAttribute(key: String, value: TypeExpression<out ValidType>) = addAttribute(key.toDopeType(), value)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ObjectType

class ObjectConcatExpression(
firstObjectExpression: TypeExpression<ObjectType>,
secondObjectExpression: TypeExpression<ObjectType>,
vararg additionalObjectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ObjectType>("OBJECT_CONCAT", firstObjectExpression, secondObjectExpression, *additionalObjectExpression)

fun TypeExpression<ObjectType>.concat(
secondObjectExpression: TypeExpression<ObjectType>,
vararg additionalObjectExpression: TypeExpression<ObjectType>,
) = ObjectConcatExpression(this, secondObjectExpression, *additionalObjectExpression)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

class ObjectFieldExpression(
objectExpression: TypeExpression<ObjectType>,
jansigi marked this conversation as resolved.
Show resolved Hide resolved
attributeKey: TypeExpression<StringType>,
jansigi marked this conversation as resolved.
Show resolved Hide resolved
) : FunctionExpression<ValidType>("OBJECT_FIELD", objectExpression, attributeKey)

fun TypeExpression<ObjectType>.objectField(key: TypeExpression<StringType>) =
ObjectFieldExpression(this, key)
jansigi marked this conversation as resolved.
Show resolved Hide resolved

fun TypeExpression<ObjectType>.objectField(key: String) = objectField(key.toDopeType())
jansigi marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType

class ObjectInnerPairsExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ArrayType<ObjectType>>("OBJECT_INNER_PAIRS", objectExpression)

fun TypeExpression<ObjectType>.innerPairs() = ObjectInnerPairsExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.ValidType

class ObjectInnerValuesExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ArrayType<ValidType>>("OBJECT_INNER_VALUES", objectExpression)

fun TypeExpression<ObjectType>.innerValues() = ObjectInnerValuesExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.NumberType
import ch.ergon.dope.validtype.ObjectType

class ObjectLengthExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<NumberType>("OBJECT_LENGTH", objectExpression)

fun TypeExpression<ObjectType>.length() = ObjectLengthExpression(this)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be consistent with arrays. Using arrays we don't use extension-functions and name it arrayLength. It's confusing for the user if we change the syntax always

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comment is for all the object-functions)

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType

class ObjectNamesExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ArrayType<StringType>>("OBJECT_NAMES", objectExpression)

fun TypeExpression<ObjectType>.names() = ObjectNamesExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType

class ObjectPairsExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ArrayType<ObjectType>>("OBJECT_PAIRS", objectExpression)

fun TypeExpression<ObjectType>.pairs() = ObjectPairsExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType

class ObjectPairsNestedExpression(
objectExpression: TypeExpression<ObjectType>,
options: TypeExpression<ObjectType>? = null,
) : FunctionExpression<ArrayType<ObjectType>>("OBJECT_PAIRS_NESTED", objectExpression, options)

fun TypeExpression<ObjectType>.pairsNested(options: TypeExpression<ObjectType>? = null) = ObjectPairsNestedExpression(this, options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType

class ObjectPathsExpression(
objectExpression: TypeExpression<ObjectType>,
options: TypeExpression<ObjectType>? = null,
) : FunctionExpression<ArrayType<StringType>>("OBJECT_PATHS", objectExpression, options)

fun TypeExpression<ObjectType>.paths(options: TypeExpression<ObjectType>? = null) = ObjectPathsExpression(this, options)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType
import ch.ergon.dope.validtype.ValidType

class ObjectPutExpression(
objectExpression: TypeExpression<ObjectType>,
attributeKey: TypeExpression<StringType>,
attributeValue: TypeExpression<out ValidType>,
) : FunctionExpression<ObjectType>("OBJECT_PUT", objectExpression, attributeKey, attributeValue)

fun TypeExpression<ObjectType>.putAttribute(key: TypeExpression<StringType>, value: TypeExpression<out ValidType>) =
ObjectPutExpression(this, key, value)

fun TypeExpression<ObjectType>.putAttribute(key: String, value: TypeExpression<out ValidType>) = putAttribute(key.toDopeType(), value)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType

class ObjectRemoveExpression(
objectExpression: TypeExpression<ObjectType>,
attributeKey: TypeExpression<StringType>,
) : FunctionExpression<ObjectType>("OBJECT_REMOVE", objectExpression, attributeKey)

fun TypeExpression<ObjectType>.removeAttribute(key: TypeExpression<StringType>) = ObjectRemoveExpression(this, key)

fun TypeExpression<ObjectType>.removeAttribute(key: String) = removeAttribute(key.toDopeType())
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType

class ObjectRenameExpression(
objectExpression: TypeExpression<ObjectType>,
oldField: TypeExpression<StringType>,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would go for oldFieldName and newFieldName

newField: TypeExpression<StringType>,
) : FunctionExpression<ObjectType>("OBJECT_RENAME", objectExpression, oldField, newField)

fun TypeExpression<ObjectType>.renameAttribute(
oldField: TypeExpression<StringType>,
newField: TypeExpression<StringType>,
) = ObjectRenameExpression(this, oldField, newField)

fun TypeExpression<ObjectType>.renameAttribute(
oldField: String,
newField: String,
) = renameAttribute(oldField.toDopeType(), newField.toDopeType())
jansigi marked this conversation as resolved.
Show resolved Hide resolved

fun TypeExpression<ObjectType>.renameAttribute(
jansigi marked this conversation as resolved.
Show resolved Hide resolved
oldField: TypeExpression<StringType>,
newField: String,
) = renameAttribute(oldField, newField.toDopeType())

fun TypeExpression<ObjectType>.renameAttribute(
jansigi marked this conversation as resolved.
Show resolved Hide resolved
oldField: String,
newField: TypeExpression<StringType>,
) = renameAttribute(oldField.toDopeType(), newField)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.ValidType

class ObjectReplaceExpression(
objectExpression: TypeExpression<ObjectType>,
oldValue: TypeExpression<out ValidType>,
newValue: TypeExpression<out ValidType>,
) : FunctionExpression<ObjectType>("OBJECT_REPLACE", objectExpression, oldValue, newValue)

fun TypeExpression<ObjectType>.replace(oldValue: TypeExpression<out ValidType>, newValue: TypeExpression<out ValidType>) =
ObjectReplaceExpression(this, oldValue, newValue)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.ValidType

class ObjectUnwrapExpression(
objectExpression: TypeExpression<ObjectType>,
jansigi marked this conversation as resolved.
Show resolved Hide resolved
) : FunctionExpression<ValidType>("OBJECT_UNWRAP", objectExpression)

fun TypeExpression<ObjectType>.unwrap() = ObjectUnwrapExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.resolvable.expression.TypeExpression
import ch.ergon.dope.resolvable.expression.unaliased.type.function.FunctionExpression
import ch.ergon.dope.validtype.ArrayType
import ch.ergon.dope.validtype.ObjectType
import ch.ergon.dope.validtype.StringType

class ObjectValuesExpression(
objectExpression: TypeExpression<ObjectType>,
) : FunctionExpression<ArrayType<StringType>>("OBJECT_VALUES", objectExpression)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not correct right? I guess it returns an array of ValidType


fun TypeExpression<ObjectType>.values() = ObjectValuesExpression(this)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.DopeQueryManager
import ch.ergon.dope.helper.ManagerDependentTest
import ch.ergon.dope.helper.someObjectField
import ch.ergon.dope.resolvable.expression.unaliased.type.toDopeType
import kotlin.test.Test
import kotlin.test.assertEquals

class ObjectAddExpressionTest : ManagerDependentTest {
override lateinit var manager: DopeQueryManager

@Test
fun `should support object add expression`() {
val expected = DopeQuery(
queryString = "OBJECT_ADD(`objectField`, \"key\", \"value\")",
)
val underTest = ObjectAddExpression(someObjectField(), "key".toDopeType(), "value".toDopeType())

val actual = underTest.toDopeQuery(manager)

assertEquals(expected, actual)
}

@Test
fun `should support object add function`() {
val objectExpression = someObjectField()
val newAttributeKey = "key".toDopeType()
val newAttributeValue = "value".toDopeType()
val expected = ObjectAddExpression(objectExpression, newAttributeKey, newAttributeValue)

val actual = objectExpression.addAttribute(newAttributeKey, newAttributeValue)

assertEquals(expected.toDopeQuery(manager), actual.toDopeQuery(manager))
}

@Test
fun `should support object add function string`() {
val objectExpression = someObjectField()
val newAttributeKey = "key"
val newAttributeValue = "value".toDopeType()
val expected = ObjectAddExpression(objectExpression, newAttributeKey.toDopeType(), newAttributeValue)

val actual = objectExpression.addAttribute(newAttributeKey, newAttributeValue)

assertEquals(expected.toDopeQuery(manager), actual.toDopeQuery(manager))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ch.ergon.dope.resolvable.expression.unaliased.type.function.`object`

import ch.ergon.dope.DopeQuery
import ch.ergon.dope.DopeQueryManager
import ch.ergon.dope.helper.ManagerDependentTest
import ch.ergon.dope.helper.someObjectField
import kotlin.test.Test
import kotlin.test.assertEquals

class ObjectConcatExpressionTest : ManagerDependentTest {
override lateinit var manager: DopeQueryManager

@Test
fun `should support object concat expression`() {
val expected = DopeQuery(
queryString = "OBJECT_CONCAT(`field1`, `field2`, `field3`)",
)
val underTest = ObjectConcatExpression(someObjectField("field1"), someObjectField("field2"), someObjectField("field3"))

val actual = underTest.toDopeQuery(manager)

assertEquals(expected, actual)
}

@Test
fun `should support object concat function`() {
val firstObjectExpression = someObjectField("field1")
val secondObjectExpression = someObjectField("field2")
val additionalObjectExpression = someObjectField("field3")
val expected = ObjectConcatExpression(firstObjectExpression, secondObjectExpression, additionalObjectExpression)

val actual = firstObjectExpression.concat(secondObjectExpression, additionalObjectExpression)

assertEquals(expected.toDopeQuery(manager), actual.toDopeQuery(manager))
}
}
Loading
Loading