diff --git a/common/src/main/java/dev/cel/common/values/BUILD.bazel b/common/src/main/java/dev/cel/common/values/BUILD.bazel index 8dbdbe95..38160882 100644 --- a/common/src/main/java/dev/cel/common/values/BUILD.bazel +++ b/common/src/main/java/dev/cel/common/values/BUILD.bazel @@ -7,6 +7,45 @@ package( ], ) +# keep sorted +CEL_VALUES_SOURCES = [ + "BoolValue.java", + "BytesValue.java", + "DoubleValue.java", + "DurationValue.java", + "EnumValue.java", + "IntValue.java", + "NullValue.java", + "StringValue.java", + "TimestampValue.java", + "UintValue.java", +] + +java_library( + name = "cel_value", + srcs = ["CelValue.java"], + tags = [ + ], + deps = [ + "//common/annotations", + "@maven//:com_google_errorprone_error_prone_annotations", + ], +) + +java_library( + name = "values", + srcs = CEL_VALUES_SOURCES, + tags = [ + ], + deps = [ + ":cel_byte_string", + ":cel_value", + "//:auto_value", + "@maven//:com_google_errorprone_error_prone_annotations", + "@maven//:com_google_guava_guava", + ], +) + java_library( name = "cel_byte_string", srcs = ["CelByteString.java"], diff --git a/common/src/main/java/dev/cel/common/values/BoolValue.java b/common/src/main/java/dev/cel/common/values/BoolValue.java new file mode 100644 index 00000000..0fe868cc --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/BoolValue.java @@ -0,0 +1,36 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; + +/** BoolValue is a simple CelValue wrapper around Java booleans. */ +@AutoValue +@Immutable +public abstract class BoolValue extends CelValue { + + @Override + public abstract Boolean value(); + + @Override + public boolean isZeroValue() { + return !value(); + } + + public static BoolValue create(Boolean value) { + return new AutoValue_BoolValue(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/BytesValue.java b/common/src/main/java/dev/cel/common/values/BytesValue.java new file mode 100644 index 00000000..dad78736 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/BytesValue.java @@ -0,0 +1,36 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; + +/** BytesValue is a simple CelValue wrapper around CelByteString (immutable byte string). */ +@AutoValue +@Immutable +public abstract class BytesValue extends CelValue { + + @Override + public abstract CelByteString value(); + + @Override + public boolean isZeroValue() { + return value().isEmpty(); + } + + public static BytesValue create(CelByteString value) { + return new AutoValue_BytesValue(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/CelValue.java b/common/src/main/java/dev/cel/common/values/CelValue.java new file mode 100644 index 00000000..582338d9 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/CelValue.java @@ -0,0 +1,42 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.errorprone.annotations.Immutable; +import dev.cel.common.annotations.Internal; + +/** + * A representation of a CEL value for the runtime. Clients should never directly extend from + * CelValue. Clients may extend some subclasses of CelValue, such as StructValue if it has been + * explicitly designed and documented for extension. + */ +@Immutable +@Internal +public abstract class CelValue { + + /** + * The underlying value. This is typically the Java native value or a derived instance of CelValue + * (ex: an element in lists or key/value pair in maps). + */ + public abstract Object value(); + + /** Returns true if the {@link #value()} is a zero value for its type. */ + public abstract boolean isZeroValue(); + + // TOOD(b/309695452): Add CelEquals method + // TODO: Add a getter for CelType + + public CelValue() {} +} diff --git a/common/src/main/java/dev/cel/common/values/DoubleValue.java b/common/src/main/java/dev/cel/common/values/DoubleValue.java new file mode 100644 index 00000000..952d27c3 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/DoubleValue.java @@ -0,0 +1,67 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.errorprone.annotations.Immutable; + +/** DoubleValue is a simple CelValue wrapper around Java doubles. */ +@Immutable +public final class DoubleValue extends CelValue { + private final double value; + + @Override + public Double value() { + return value; + } + + public double doubleValue() { + return value; + } + + @Override + public boolean isZeroValue() { + return value() == 0; + } + + public static DoubleValue create(double value) { + return new DoubleValue(value); + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Double.hashCode(value); + return h; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof DoubleValue)) { + return false; + } + + return Double.doubleToLongBits(((DoubleValue) o).doubleValue()) + == Double.doubleToLongBits(this.doubleValue()); + } + + private DoubleValue(double value) { + this.value = value; + } +} diff --git a/common/src/main/java/dev/cel/common/values/DurationValue.java b/common/src/main/java/dev/cel/common/values/DurationValue.java new file mode 100644 index 00000000..f706d30a --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/DurationValue.java @@ -0,0 +1,37 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; +import java.time.Duration; + +/** DurationValue is a simple CelValue wrapper around {@link java.time.Duration} */ +@AutoValue +@Immutable +public abstract class DurationValue extends CelValue { + + @Override + public abstract Duration value(); + + @Override + public boolean isZeroValue() { + return value().isZero(); + } + + public static DurationValue create(Duration value) { + return new AutoValue_DurationValue(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/EnumValue.java b/common/src/main/java/dev/cel/common/values/EnumValue.java new file mode 100644 index 00000000..9aeaacd7 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/EnumValue.java @@ -0,0 +1,41 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; + +/** + * EnumValue is a simple CelValue wrapper around Java enums. + * + *

Note: CEL-Java currently does not support strongly typed enum. This value class will not be + * used until the said support is added in. + */ +@AutoValue +@Immutable(containerOf = "E") +public abstract class EnumValue> extends CelValue { + + @Override + public abstract Enum value(); + + @Override + public boolean isZeroValue() { + return false; + } + + public static > EnumValue create(Enum value) { + return new AutoValue_EnumValue<>(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/IntValue.java b/common/src/main/java/dev/cel/common/values/IntValue.java new file mode 100644 index 00000000..c094826f --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/IntValue.java @@ -0,0 +1,66 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.errorprone.annotations.Immutable; + +/** IntValue is a simple CelValue wrapper around Java longs. */ +@Immutable +public final class IntValue extends CelValue { + private final long value; + + @Override + public Long value() { + return value; + } + + public long longValue() { + return value; + } + + @Override + public boolean isZeroValue() { + return value() == 0; + } + + public static IntValue create(long value) { + return new IntValue(value); + } + + @Override + public int hashCode() { + int h = 1; + h *= 1000003; + h ^= Long.hashCode(value); + return h; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + + if (!(o instanceof IntValue)) { + return false; + } + + return ((IntValue) o).value == this.value; + } + + private IntValue(long value) { + this.value = value; + } +} diff --git a/common/src/main/java/dev/cel/common/values/NullValue.java b/common/src/main/java/dev/cel/common/values/NullValue.java new file mode 100644 index 00000000..5fa7924a --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/NullValue.java @@ -0,0 +1,38 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.errorprone.annotations.Immutable; + +/** + * NullValue represents the value 'null' of 'null_type' according to the CEL specification. One of + * its primary uses is to represent nulls in JSON data. + */ +@Immutable +public final class NullValue extends CelValue { + + /** Sentinel value for representing NULL. */ + public static final NullValue NULL_VALUE = new NullValue(); + + @Override + public NullValue value() { + return NULL_VALUE; + } + + @Override + public boolean isZeroValue() { + return true; + } +} diff --git a/common/src/main/java/dev/cel/common/values/StringValue.java b/common/src/main/java/dev/cel/common/values/StringValue.java new file mode 100644 index 00000000..217f2cd5 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/StringValue.java @@ -0,0 +1,36 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; + +/** StringValue is a simple CelValue wrapper around Java strings. */ +@AutoValue +@Immutable +public abstract class StringValue extends CelValue { + + @Override + public abstract String value(); + + @Override + public boolean isZeroValue() { + return value().isEmpty(); + } + + public static StringValue create(String value) { + return new AutoValue_StringValue(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/TimestampValue.java b/common/src/main/java/dev/cel/common/values/TimestampValue.java new file mode 100644 index 00000000..34f36604 --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/TimestampValue.java @@ -0,0 +1,37 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.errorprone.annotations.Immutable; +import java.time.Instant; + +/** TimestampValue is a simple CelValue wrapper around {@link java.time.Instant} */ +@AutoValue +@Immutable +public abstract class TimestampValue extends CelValue { + + @Override + public abstract Instant value(); + + @Override + public boolean isZeroValue() { + return Instant.EPOCH.equals(value()); + } + + public static TimestampValue create(Instant value) { + return new AutoValue_TimestampValue(value); + } +} diff --git a/common/src/main/java/dev/cel/common/values/UintValue.java b/common/src/main/java/dev/cel/common/values/UintValue.java new file mode 100644 index 00000000..0252373d --- /dev/null +++ b/common/src/main/java/dev/cel/common/values/UintValue.java @@ -0,0 +1,43 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import com.google.auto.value.AutoValue; +import com.google.common.primitives.UnsignedLong; +import com.google.errorprone.annotations.Immutable; + +/** + * UintValue represents CelValue for unsigned longs, leveraging Guava's implementation of {@link + * UnsignedLong}. + * + *

TODO: Look into potentially accepting a primitive `long` to avoid boxing/unboxing + * when the interpreter is augmented to work directly on CelValue. + */ +@AutoValue +@Immutable +public abstract class UintValue extends CelValue { + + @Override + public abstract UnsignedLong value(); + + @Override + public boolean isZeroValue() { + return UnsignedLong.ZERO.equals(value()); + } + + public static UintValue create(UnsignedLong value) { + return new AutoValue_UintValue(value); + } +} diff --git a/common/src/test/java/dev/cel/common/values/BUILD.bazel b/common/src/test/java/dev/cel/common/values/BUILD.bazel index e60b124c..844004ac 100644 --- a/common/src/test/java/dev/cel/common/values/BUILD.bazel +++ b/common/src/test/java/dev/cel/common/values/BUILD.bazel @@ -8,7 +8,9 @@ java_library( srcs = glob(["*.java"]), deps = [ "//:java_truth", + "//common/values", "//common/values:cel_byte_string", + "@maven//:com_google_guava_guava", "@maven//:com_google_guava_guava_testlib", "@maven//:junit_junit", ], diff --git a/common/src/test/java/dev/cel/common/values/BoolValueTest.java b/common/src/test/java/dev/cel/common/values/BoolValueTest.java new file mode 100644 index 00000000..ada0e442 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/BoolValueTest.java @@ -0,0 +1,47 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class BoolValueTest { + + @Test + public void falseBool() { + BoolValue boolValue = BoolValue.create(false); + + assertThat(boolValue.value()).isFalse(); + assertThat(boolValue.isZeroValue()).isTrue(); + } + + @Test + public void trueBool() { + BoolValue boolValue = BoolValue.create(true); + + assertThat(boolValue.value()).isTrue(); + assertThat(boolValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> BoolValue.create(null)); + } +} diff --git a/common/src/test/java/dev/cel/common/values/BytesValueTest.java b/common/src/test/java/dev/cel/common/values/BytesValueTest.java new file mode 100644 index 00000000..019dfc8e --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/BytesValueTest.java @@ -0,0 +1,47 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class BytesValueTest { + + @Test + public void emptyBytes() { + BytesValue bytesValue = BytesValue.create(CelByteString.EMPTY); + + assertThat(bytesValue.value()).isEqualTo(CelByteString.of(new byte[0])); + assertThat(bytesValue.isZeroValue()).isTrue(); + } + + @Test + public void constructBytes() { + BytesValue bytesValue = BytesValue.create(CelByteString.of(new byte[] {0x1, 0x5, 0xc})); + + assertThat(bytesValue.value()).isEqualTo(CelByteString.of(new byte[] {0x1, 0x5, 0xc})); + assertThat(bytesValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> BytesValue.create(null)); + } +} diff --git a/common/src/test/java/dev/cel/common/values/DoubleValueTest.java b/common/src/test/java/dev/cel/common/values/DoubleValueTest.java new file mode 100644 index 00000000..9d0f3263 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/DoubleValueTest.java @@ -0,0 +1,76 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.ClassSanityTester; +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DoubleValueTest { + + @Test + public void emptyDouble() { + DoubleValue doubleValue = DoubleValue.create(0.0d); + + assertThat(doubleValue.value()).isEqualTo(0.0d); + assertThat(doubleValue.isZeroValue()).isTrue(); + } + + @Test + public void constructDouble() { + DoubleValue doubleValue = DoubleValue.create(5.0d); + + assertThat(doubleValue.value()).isEqualTo(5.0d); + assertThat(doubleValue.isZeroValue()).isFalse(); + } + + @Test + public void equalityTest() { + new EqualsTester() + .addEqualityGroup(DoubleValue.create(10.5)) + .addEqualityGroup(DoubleValue.create(0.0d), DoubleValue.create(0)) + .addEqualityGroup(DoubleValue.create(15.3), DoubleValue.create(15.3)) + .addEqualityGroup( + DoubleValue.create(Double.MAX_VALUE), DoubleValue.create(Double.MAX_VALUE)) + .addEqualityGroup( + DoubleValue.create(Double.MIN_VALUE), DoubleValue.create(Double.MIN_VALUE)) + .testEquals(); + } + + @Test + public void sanityTest() throws Exception { + new ClassSanityTester() + .setDefault(DoubleValue.class, DoubleValue.create(100.94d)) + .setDistinctValues(DoubleValue.class, DoubleValue.create(0.0d), DoubleValue.create(100.0d)) + .forAllPublicStaticMethods(DoubleValue.class) + .thatReturn(DoubleValue.class) + .testEquals() + .testNulls(); + } + + @Test + public void hashCode_smokeTest() { + assertThat(DoubleValue.create(0).hashCode()).isEqualTo(1000003); + assertThat(DoubleValue.create(0.0d).hashCode()).isEqualTo(1000003); + assertThat(DoubleValue.create(100.5d).hashCode()).isEqualTo(1079403075); + assertThat(DoubleValue.create(Double.MAX_VALUE).hashCode()).isEqualTo(-2145435069); + assertThat(DoubleValue.create(Double.MIN_VALUE).hashCode()).isEqualTo(1000002); + } +} diff --git a/common/src/test/java/dev/cel/common/values/DurationValueTest.java b/common/src/test/java/dev/cel/common/values/DurationValueTest.java new file mode 100644 index 00000000..8ad721cb --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/DurationValueTest.java @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import java.time.Duration; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class DurationValueTest { + + @Test + public void emptyDuration() { + DurationValue durationValue = DurationValue.create(Duration.ZERO); + + assertThat(durationValue.value()).isEqualTo(Duration.ofSeconds(0)); + assertThat(durationValue.isZeroValue()).isTrue(); + } + + @Test + public void constructDuration() { + DurationValue durationValue = DurationValue.create(Duration.ofSeconds(10000)); + + assertThat(durationValue.value()).isEqualTo(Duration.ofSeconds(10000)); + assertThat(durationValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> DurationValue.create(null)); + } +} diff --git a/common/src/test/java/dev/cel/common/values/EnumValueTest.java b/common/src/test/java/dev/cel/common/values/EnumValueTest.java new file mode 100644 index 00000000..d10c6cf3 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/EnumValueTest.java @@ -0,0 +1,45 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class EnumValueTest { + + private enum TestKind { + ONE, + TWO + } + + @Test + public void enumValue_construct() { + EnumValue one = EnumValue.create(TestKind.ONE); + EnumValue two = EnumValue.create(TestKind.TWO); + + assertThat(one.value()).isEqualTo(TestKind.ONE); + assertThat(two.value()).isEqualTo(TestKind.TWO); + } + + @Test + public void enumValue_isZeroValue_returnsFalse() { + assertThat(EnumValue.create(TestKind.ONE).isZeroValue()).isFalse(); + assertThat(EnumValue.create(TestKind.TWO).isZeroValue()).isFalse(); + } +} diff --git a/common/src/test/java/dev/cel/common/values/IntValueTest.java b/common/src/test/java/dev/cel/common/values/IntValueTest.java new file mode 100644 index 00000000..404a2a06 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/IntValueTest.java @@ -0,0 +1,73 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.testing.ClassSanityTester; +import com.google.common.testing.EqualsTester; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class IntValueTest { + + @Test + public void emptyInt() { + IntValue intValue = IntValue.create(0L); + + assertThat(intValue.value()).isEqualTo(0L); + assertThat(intValue.isZeroValue()).isTrue(); + } + + @Test + public void constructInt() { + IntValue uintValue = IntValue.create(5L); + + assertThat(uintValue.value()).isEqualTo(5L); + assertThat(uintValue.isZeroValue()).isFalse(); + } + + @Test + public void equalityTest() { + new EqualsTester() + .addEqualityGroup(IntValue.create(10)) + .addEqualityGroup(IntValue.create(0), IntValue.create(0)) + .addEqualityGroup(IntValue.create(15), IntValue.create(15)) + .addEqualityGroup(IntValue.create(Long.MAX_VALUE), IntValue.create(Long.MAX_VALUE)) + .addEqualityGroup(IntValue.create(Long.MIN_VALUE), IntValue.create(Long.MIN_VALUE)) + .testEquals(); + } + + @Test + public void sanityTest() throws Exception { + new ClassSanityTester() + .setDefault(IntValue.class, IntValue.create(100)) + .setDistinctValues(IntValue.class, IntValue.create(0), IntValue.create(100)) + .forAllPublicStaticMethods(IntValue.class) + .thatReturn(IntValue.class) + .testEquals() + .testNulls(); + } + + @Test + public void hashCode_smokeTest() { + assertThat(IntValue.create(0).hashCode()).isEqualTo(1000003); + assertThat(IntValue.create(100).hashCode()).isEqualTo(999975); + assertThat(IntValue.create(Long.MAX_VALUE).hashCode()).isEqualTo(-2146483645); + assertThat(IntValue.create(Long.MIN_VALUE).hashCode()).isEqualTo(-2146483645); + } +} diff --git a/common/src/test/java/dev/cel/common/values/NullValueTest.java b/common/src/test/java/dev/cel/common/values/NullValueTest.java new file mode 100644 index 00000000..2f05aca0 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/NullValueTest.java @@ -0,0 +1,31 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class NullValueTest { + + @Test + public void nullValueTest() { + assertThat(NullValue.NULL_VALUE.value()).isEqualTo(NullValue.NULL_VALUE); + assertThat(NullValue.NULL_VALUE.isZeroValue()).isTrue(); + } +} diff --git a/common/src/test/java/dev/cel/common/values/StringValueTest.java b/common/src/test/java/dev/cel/common/values/StringValueTest.java new file mode 100644 index 00000000..6cae3f62 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/StringValueTest.java @@ -0,0 +1,55 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class StringValueTest { + + @Test + public void emptyString() { + StringValue stringValue = StringValue.create(""); + + assertThat(stringValue.value()).isEmpty(); + assertThat(stringValue.isZeroValue()).isTrue(); + } + + @Test + public void blankString() { + StringValue stringValue = StringValue.create(" "); + + assertThat(stringValue.value()).isEqualTo(" "); + assertThat(stringValue.isZeroValue()).isFalse(); + } + + @Test + public void constructString() { + StringValue stringValue = StringValue.create("Hello World"); + + assertThat(stringValue.value()).isEqualTo("Hello World"); + assertThat(stringValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> StringValue.create(null)); + } +} diff --git a/common/src/test/java/dev/cel/common/values/TimestampValueTest.java b/common/src/test/java/dev/cel/common/values/TimestampValueTest.java new file mode 100644 index 00000000..ad82bad6 --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/TimestampValueTest.java @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import java.time.Instant; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class TimestampValueTest { + + @Test + public void emptyTimestamp() { + TimestampValue timestampValue = TimestampValue.create(Instant.ofEpochSecond(0)); + + assertThat(timestampValue.value()).isEqualTo(Instant.EPOCH); + assertThat(timestampValue.isZeroValue()).isTrue(); + } + + @Test + public void constructTimestamp() { + TimestampValue timestampValue = TimestampValue.create(Instant.ofEpochMilli(100000)); + + assertThat(timestampValue.value()).isEqualTo(Instant.ofEpochMilli(100000)); + assertThat(timestampValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> TimestampValue.create(null)); + } +} diff --git a/common/src/test/java/dev/cel/common/values/UintValueTest.java b/common/src/test/java/dev/cel/common/values/UintValueTest.java new file mode 100644 index 00000000..e3ddc96d --- /dev/null +++ b/common/src/test/java/dev/cel/common/values/UintValueTest.java @@ -0,0 +1,48 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.common.values; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import com.google.common.primitives.UnsignedLong; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class UintValueTest { + + @Test + public void emptyUint() { + UintValue uintValue = UintValue.create(UnsignedLong.valueOf(0L)); + + assertThat(uintValue.value()).isEqualTo(UnsignedLong.valueOf(0L)); + assertThat(uintValue.isZeroValue()).isTrue(); + } + + @Test + public void constructUint() { + UintValue uintValue = UintValue.create(UnsignedLong.valueOf(5L)); + + assertThat(uintValue.value()).isEqualTo(UnsignedLong.valueOf(5L)); + assertThat(uintValue.isZeroValue()).isFalse(); + } + + @Test + public void create_nullValue_throws() { + assertThrows(NullPointerException.class, () -> UintValue.create(null)); + } +} diff --git a/common/values/BUILD.bazel b/common/values/BUILD.bazel index 79b73472..bac42e64 100644 --- a/common/values/BUILD.bazel +++ b/common/values/BUILD.bazel @@ -3,6 +3,16 @@ package( default_visibility = ["//visibility:public"], # TODO: Expose to public when ready ) +java_library( + name = "cel_value", + exports = ["//common/src/main/java/dev/cel/common/values:cel_value"], +) + +java_library( + name = "values", + exports = ["//common/src/main/java/dev/cel/common/values"], +) + java_library( name = "cel_byte_string", exports = ["//common/src/main/java/dev/cel/common/values:cel_byte_string"],