Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #44 from nawforce/41-member-declarations-missing-f…
Browse files Browse the repository at this point in the history
…rom-triggerunit-rule

Add triggerUnit2 for trigger parsing fixes
  • Loading branch information
nawforce authored Dec 24, 2023
2 parents da2e247 + 021dcc5 commit 160f3ff
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
23 changes: 23 additions & 0 deletions antlr/ApexParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,24 @@ triggerUnit
: TRIGGER id ON id LPAREN triggerCase (COMMA triggerCase)* RPAREN block EOF
;

// v2 entry point for Apex trigger files, see README.md for details
triggerUnit2
: TRIGGER id ON id LPAREN triggerCase (COMMA triggerCase)* RPAREN triggerBlock EOF
;

triggerCase
: (BEFORE|AFTER) (INSERT|UPDATE|DELETE|UNDELETE)
;

triggerBlock
: LBRACE triggerBlockMember* RBRACE
;

triggerBlockMember
: modifier* triggerMemberDeclaration
| statement
;

// entry point for Apex class files
compilationUnit
: typeDeclaration EOF
Expand Down Expand Up @@ -133,6 +147,15 @@ memberDeclaration
| propertyDeclaration
;

triggerMemberDeclaration
: methodDeclaration
| fieldDeclaration
| interfaceDeclaration
| classDeclaration
| enumDeclaration
| propertyDeclaration
;

/* We use rule this even for void methods which cannot have [] after parameters.
This simplifies grammar and we can consider void to be a type, which
renders the [] matching as a context-sensitive issue or a semantic check
Expand Down
77 changes: 77 additions & 0 deletions jvm/src/test/java/com/nawforce/apexparser/ApexTrigger2Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.nawforce.apexparser;

import org.junit.jupiter.api.Test;

import java.util.Map;

import static com.nawforce.apexparser.SyntaxErrorCounter.createParser;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class ApexTrigger2Test {

@Test
void testEmptyTrigger() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithStatement() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {System.debug('');}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithMethod() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {public void func() {}}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithField() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {String a;}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithInterface() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {interface Foo {}}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithClass() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {class Foo {}}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithEnum() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) {enum Foo {}}");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testTriggerWithProperty() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser("trigger test on Account (before update, after update) { String a {get { return a; } set { a = value; }} }");
ApexParser.TriggerUnit2Context context = parserAndCounter.getKey().triggerUnit2();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

}
66 changes: 66 additions & 0 deletions npm/src/__tests__/ApexTrigger2Test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {TriggerUnit2Context} from "../ApexParser";
import { createParser } from "./SyntaxErrorCounter";

test('Empty Trigger', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with statement', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {System.debug('');}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with method', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {public void func() {}}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with field', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {String a;}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with interface', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {interface Foo {}}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with class', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {class Foo {}}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with enum', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) {enum Foo {}}")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('Trigger with property', () => {
const [parser, errorCounter] = createParser("test.trigger", "trigger test on Account (before update, after update) { String a {get { return a; } set { a = value; }} }")
const context = parser.triggerUnit2()

expect(context).toBeInstanceOf(TriggerUnit2Context)
expect(errorCounter.getNumErrors()).toEqual(0)
})

0 comments on commit 160f3ff

Please sign in to comment.