Skip to content

Commit

Permalink
test: add coalesce operator tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pwrightcertinia committed Feb 27, 2024
1 parent e991fe6 commit c6872c4
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 2 deletions.
47 changes: 47 additions & 0 deletions jvm/src/test/java/com/nawforce/apexparser/ApexParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;

import static com.nawforce.apexparser.SyntaxErrorCounter.createParser;
Expand All @@ -40,6 +41,52 @@ void testExpression() {
assertEquals(2, ((ApexParser.Arth1ExpressionContext) context).expression().size());
}

@Test
void testCoalesceExpression() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("a ?? 5");
ApexParser.ExpressionContext context = parserAndCounter.getKey().expression();
assertTrue(context instanceof ApexParser.CoalExpressionContext);
assertEquals(2, ((ApexParser.CoalExpressionContext) context).expression().size());
}

@Test
void testCoalescePrecedence() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("top ?? 100 - bottom ?? 0");
ApexParser.ExpressionContext context = parserAndCounter.getKey().expression();
assertTrue(context instanceof ApexParser.CoalExpressionContext);

List<ApexParser.ExpressionContext> outer = ((ApexParser.CoalExpressionContext) context).expression();
assertEquals(2, outer.size());

assertTrue(outer.get(0) instanceof ApexParser.CoalExpressionContext);
List<ApexParser.ExpressionContext> inner = ((ApexParser.CoalExpressionContext) outer.get(0)).expression();
assertEquals(2, inner.size());

assertTrue(inner.get(0) instanceof ApexParser.PrimaryExpressionContext);
assertTrue(inner.get(1) instanceof ApexParser.Arth2ExpressionContext);

assertTrue(outer.get(1) instanceof ApexParser.PrimaryExpressionContext);
}

@Test
void testCoalescePrecedenceBoolean() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("a ?? false || b ?? false");
ApexParser.ExpressionContext context = parserAndCounter.getKey().expression();
assertTrue(context instanceof ApexParser.CoalExpressionContext);

List<ApexParser.ExpressionContext> outer = ((ApexParser.CoalExpressionContext) context).expression();
assertEquals(2, outer.size());

assertTrue(outer.get(0) instanceof ApexParser.CoalExpressionContext);
List<ApexParser.ExpressionContext> inner = ((ApexParser.CoalExpressionContext) outer.get(0)).expression();
assertEquals(2, inner.size());

assertTrue(inner.get(0) instanceof ApexParser.PrimaryExpressionContext);
assertTrue(inner.get(1) instanceof ApexParser.LogOrExpressionContext);

assertTrue(outer.get(1) instanceof ApexParser.PrimaryExpressionContext);
}

@Test
void testClass() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("public class Hello {}");
Expand Down
65 changes: 63 additions & 2 deletions npm/src/__tests__/ApexParserTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
derived from this software without specific prior written permission.
*/
import {
LiteralContext, Arth1ExpressionContext, CompilationUnitContext,
StatementContext, TriggerUnitContext, QueryContext
LiteralContext,
Arth1ExpressionContext,
CompilationUnitContext,
StatementContext,
TriggerUnitContext,
QueryContext,
CoalExpressionContext,
PrimaryExpressionContext,
Arth2ExpressionContext,
LogOrExpressionContext
} from "../ApexParser";
import { ThrowingErrorListener, SyntaxException } from "../ThrowingErrorListener";
import { createParser } from "./SyntaxErrorCounter";
Expand All @@ -39,6 +47,59 @@ test('Expression', () => {
expect(arthExpression.expression().length).toBe(2)
})

test("Coalesce Expression", () => {
const [parser, errorCounter] = createParser("a ?? 5");
const context = parser.expression();

expect(errorCounter.getNumErrors()).toEqual(0);
expect(context).toBeInstanceOf(CoalExpressionContext);
const coalExpression = context as CoalExpressionContext;
expect(coalExpression.expression().length).toBe(2);
});

test("Coalesce Precedence - Arithmetic", () => {
// Based on the example in release notes / docs
// should NOT evaluate to (top ?? 100) - (bottom ?? 0) as you want
//
// left assoc = (top ?? (100 - bottom)) ?? 0
// right assoc = top ?? ((100 - bottom) ?? 0)
const [parser, errorCounter] = createParser("top ?? 100 - bottom ?? 0");
const context = parser.expression();

expect(errorCounter.getNumErrors()).toEqual(0);
expect(context).toBeInstanceOf(CoalExpressionContext);
const outer = (context as CoalExpressionContext).expression();
expect(outer.length).toBe(2);
expect(outer[0]).toBeInstanceOf(CoalExpressionContext);

const inner = (outer[0] as CoalExpressionContext).expression(); // top ?? 100 - bottom
expect(inner.length).toBe(2);
expect(inner[0]).toBeInstanceOf(PrimaryExpressionContext); // top
expect(inner[1]).toBeInstanceOf(Arth2ExpressionContext); // 100 - bottom

expect(outer[1]).toBeInstanceOf(PrimaryExpressionContext); // 0
});

test("Coalesce Precedence - Boolean", () => {
// This is more nonsense but using a much lower precedence op
// should NOT evaluate to (a ?? false) || (b ?? false)
const [parser, errorCounter] = createParser("a ?? false || b ?? false");
const context = parser.expression();

expect(errorCounter.getNumErrors()).toEqual(0);
expect(context).toBeInstanceOf(CoalExpressionContext);
const outer = (context as CoalExpressionContext).expression();
expect(outer.length).toBe(2);
expect(outer[0]).toBeInstanceOf(CoalExpressionContext);

const inner = (outer[0] as CoalExpressionContext).expression(); // a ?? false || b
expect(inner.length).toBe(2);
expect(inner[0]).toBeInstanceOf(PrimaryExpressionContext); // a
expect(inner[1]).toBeInstanceOf(LogOrExpressionContext); // false || b

expect(outer[1]).toBeInstanceOf(PrimaryExpressionContext); // false
});

test('Compilation Unit', () => {
const [parser, errorCounter] = createParser("public class Hello {}")

Expand Down

0 comments on commit c6872c4

Please sign in to comment.