Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
f363428
added neo4j functions tests
Feb 15, 2026
2376022
fixed factory
Feb 15, 2026
cdec6bb
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Feb 15, 2026
44d0c39
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Feb 15, 2026
be84308
added elementid() (uses ID())
Feb 15, 2026
1ba12c7
Revert "added elementid() (uses ID())"
Feb 15, 2026
1d0342e
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Feb 15, 2026
6488c38
fixed some tests (expect 64bit, not 32)
Feb 15, 2026
e8375db
more 64bit fixes
Feb 15, 2026
a41ff64
fixed some errors
Feb 15, 2026
ca38e62
more errors fixes
Feb 15, 2026
703eba0
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Feb 16, 2026
a8f9dcd
Update engine/src/test/java/com/arcadedb/query/opencypher/functions/O…
ExtReMLapin Feb 16, 2026
ddc6dbf
Update engine/src/test/java/com/arcadedb/query/opencypher/functions/O…
ExtReMLapin Feb 16, 2026
99aa587
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Feb 16, 2026
c454c1c
fixed compilation error
Feb 18, 2026
c826fe5
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Mar 19, 2026
16af5f2
fixed exception not being detected
Mar 19, 2026
00afff9
fixed missing exceptions
Mar 19, 2026
64e2abd
updated tests
Mar 19, 2026
8280281
updated tests
Mar 20, 2026
3b6fd79
Coll insert/remove force second arg
Mar 20, 2026
6a23fdf
point.distance cypher
Mar 20, 2026
9dff309
cypher point use map like cypher, not like sql
Mar 20, 2026
0762c40
geo utils support map xy or longitude latitude
Mar 20, 2026
91407e5
left support two args error and neg len error
Mar 20, 2026
2c5f0f0
two args and neg len
Mar 20, 2026
6275cb2
force 3 args for Replace function
Mar 20, 2026
69e265d
lTrim support two args
Mar 20, 2026
50ec604
rtrim two args
Mar 20, 2026
28f6a6e
substring better errors handling
Mar 20, 2026
87e67e6
sync
Mar 20, 2026
2f591d6
Round added precision and mode
Mar 20, 2026
3266b9b
added timezones
Mar 20, 2026
7e9e0c6
updated vectors
Mar 20, 2026
ce445f6
sync
Mar 20, 2026
f7b0fb0
SQLFunctionStandardDeviation now returns 0.0 instead of null
Mar 20, 2026
34c5150
Update engine/src/main/java/com/arcadedb/function/geo/CypherPointFunc…
ExtReMLapin Mar 20, 2026
ef55e43
updated old test
Mar 20, 2026
14fa415
Merge branch 'ArcadeData:main' into more_tests
ExtReMLapin Apr 18, 2026
8e79172
sync
Apr 18, 2026
f8f942c
sync
Apr 18, 2026
cbc1491
fixed codacy being a crybaby
Apr 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
/*
* Copyright 2021-present Arcade Data Ltd ([email protected])
*
* 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
*
* http://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.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.query.opencypher.functions;

import com.arcadedb.database.Database;
import com.arcadedb.database.DatabaseFactory;
import com.arcadedb.query.sql.executor.ResultSet;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import org.assertj.core.api.Assertions;
import static org.assertj.core.api.Assertions.within;

/**
* Comprehensive tests for OpenCypher Mathematical Logarithmic functions based on Neo4j Cypher documentation.
* Tests cover: e(), exp(), log(), log10(), sqrt()
*/
class OpenCypherMathLogarithmicFunctionsComprehensiveTest {
private Database database;

@BeforeEach
void setUp() {
final DatabaseFactory factory = new DatabaseFactory("./databases/test-cypher-math-log");
if (factory.exists())
factory.open().drop();
database = factory.create();
}

@AfterEach
void tearDown() {
if (database != null)
database.drop();
}

// ==================== e() Tests ====================

@Test
void eBasic() {
final ResultSet result = database.command("opencypher", "RETURN e() AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(Math.E, within(0.0000001));
}

@Test
void eConstant() {
final ResultSet result = database.command("opencypher", "RETURN e() AS e1, e() AS e2");
Assertions.assertThat(result.hasNext() != false).isTrue();
final var row = result.next();
assertThat((Double) row.getProperty("e1")).isEqualTo((Double) row.getProperty("e2"));
}

// ==================== exp() Tests ====================

@Test
void expZero() {
final ResultSet result = database.command("opencypher", "RETURN exp(0.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(1.0, within(0.0001));
}

@Test
void expOne() {
final ResultSet result = database.command("opencypher", "RETURN exp(1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(Math.E, within(0.0001));
}

@Test
void expNegative() {
final ResultSet result = database.command("opencypher", "RETURN exp(-1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(1.0 / Math.E, within(0.0001));
}

@Test
void expLargeValue() {
final ResultSet result = database.command("opencypher", "RETURN exp(10.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isGreaterThan(20000.0);
}

@Test
void expOverflowReturnsInfinity() {
final ResultSet result = database.command("opencypher", "RETURN exp(1000.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
final Double value = (Double) result.next().getProperty("result");
assertThat(value.isInfinite()).isTrue();
}

@Test
void expNull() {
final ResultSet result = database.command("opencypher", "RETURN exp(null) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
Assertions.assertThat(result.next().getProperty("result") == null).isTrue();
}

// ==================== log() Tests ====================

@Test
void logOne() {
final ResultSet result = database.command("opencypher", "RETURN log(1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(0.0, within(0.0001));
}

@Test
void logE() {
final ResultSet result = database.command("opencypher", "RETURN log(e()) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(1.0, within(0.0001));
}

@Test
void logPositive() {
final ResultSet result = database.command("opencypher", "RETURN log(10.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(Math.log(10.0), within(0.0001));
}

@Test
void logZeroReturnsNegativeInfinity() {
final ResultSet result = database.command("opencypher", "RETURN log(0.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
final Double value = (Double) result.next().getProperty("result");
assertThat(value).isEqualTo(Double.NEGATIVE_INFINITY);
}

@Test
void logNegativeReturnsNaN() {
final ResultSet result = database.command("opencypher", "RETURN log(-1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isNaN();
}

@Test
void logNull() {
final ResultSet result = database.command("opencypher", "RETURN log(null) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
Assertions.assertThat(result.next().getProperty("result") == null).isTrue();
}

// ==================== log10() Tests ====================

@Test
void log10One() {
final ResultSet result = database.command("opencypher", "RETURN log10(1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(0.0, within(0.0001));
}

@Test
void log10Ten() {
final ResultSet result = database.command("opencypher", "RETURN log10(10.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(1.0, within(0.0001));
}

@Test
void log10Hundred() {
final ResultSet result = database.command("opencypher", "RETURN log10(100.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(2.0, within(0.0001));
}

@Test
void log10Thousand() {
final ResultSet result = database.command("opencypher", "RETURN log10(1000.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(3.0, within(0.0001));
}

@Test
void log10ZeroReturnsNegativeInfinity() {
final ResultSet result = database.command("opencypher", "RETURN log10(0.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
final Double value = (Double) result.next().getProperty("result");
assertThat(value).isEqualTo(Double.NEGATIVE_INFINITY);
}

@Test
void log10NegativeReturnsNaN() {
final ResultSet result = database.command("opencypher", "RETURN log10(-1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isNaN();
}

@Test
void log10Null() {
final ResultSet result = database.command("opencypher", "RETURN log10(null) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
Assertions.assertThat(result.next().getProperty("result") == null).isTrue();
}

// ==================== sqrt() Tests ====================

@Test
void sqrtZero() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(0.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(0.0, within(0.0001));
}

@Test
void sqrtOne() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(1.0, within(0.0001));
}

@Test
void sqrtFour() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(4.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(2.0, within(0.0001));
}

@Test
void sqrtNine() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(9.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(3.0, within(0.0001));
}

@Test
void sqrtTwo() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(2.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(Math.sqrt(2.0), within(0.0001));
}

@Test
void sqrtNegativeReturnsNaN() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(-1.0) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isNaN();
}

@Test
void sqrtNull() {
final ResultSet result = database.command("opencypher", "RETURN sqrt(null) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
Assertions.assertThat(result.next().getProperty("result") == null).isTrue();
}

// ==================== Combined/Integration Tests ====================

@Test
void logExpIdentity() {
// log(exp(x)) = x
final ResultSet result = database.command("opencypher",
"RETURN log(exp(2.0)) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(2.0, within(0.0001));
}

@Test
void expLogIdentity() {
// exp(log(x)) = x
final ResultSet result = database.command("opencypher",
"RETURN exp(log(5.0)) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(5.0, within(0.0001));
}

@Test
void sqrtSquareIdentity() {
// sqrt(x²) = x
final ResultSet result = database.command("opencypher",
"WITH 7.0 AS x RETURN sqrt(x * x) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
assertThat((Double) result.next().getProperty("result")).isCloseTo(7.0, within(0.0001));
}

@Test
void log10ConversionFromLog() {
// log10(x) = log(x) / log(10)
final ResultSet result = database.command("opencypher",
"WITH 100.0 AS x RETURN log10(x) AS log10_val, log(x) / log(10.0) AS log_ratio");
Assertions.assertThat(result.hasNext() != false).isTrue();
final var row = result.next();
final Double log10Val = (Double) row.getProperty("log10_val");
final Double logRatio = (Double) row.getProperty("log_ratio");
assertThat(log10Val).isCloseTo(logRatio, within(0.0001));
}

@Test
void sqrtExp() {
// sqrt(x) = exp(log(x) / 2)
final ResultSet result = database.command("opencypher",
"WITH 16.0 AS x RETURN sqrt(x) AS sqrt_val, exp(log(x) / 2.0) AS exp_val");
Assertions.assertThat(result.hasNext() != false).isTrue();
final var row = result.next();
final Double sqrtVal = (Double) row.getProperty("sqrt_val");
final Double expVal = (Double) row.getProperty("exp_val");
assertThat(sqrtVal).isCloseTo(expVal, within(0.0001));
}

@Test
void exponentialGrowth() {
// Test exponential growth formula
final ResultSet result = database.command("opencypher",
"WITH 100.0 AS initial, 0.05 AS rate, 10.0 AS time " +
"RETURN initial * exp(rate * time) AS result");
Assertions.assertThat(result.hasNext() != false).isTrue();
final Double growth = (Double) result.next().getProperty("result");
assertThat(growth).isGreaterThan(100.0);
assertThat(growth).isCloseTo(164.87, within(0.1));
}
}
Loading
Loading