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

Support convertCurrency() function in SOQL and SOSL #53

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions antlr/ApexLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ STANDARD : 'standard';
DISTANCE : 'distance';
GEOLOCATION : 'geolocation';
GROUPING : 'grouping';
CONVERT_CURRENCY : 'convertcurrency'; // used in both SOQL and SOSL

// SOQL Date functions
CALENDAR_MONTH : 'calendar_month';
Expand Down
9 changes: 7 additions & 2 deletions antlr/ApexParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ soqlFunction
| MAX LPAREN fieldName RPAREN
| SUM LPAREN fieldName RPAREN
| TOLABEL LPAREN fieldName RPAREN
| FORMAT LPAREN fieldName RPAREN
| FORMAT LPAREN ( fieldName | soqlFunction ) RPAREN
| CALENDAR_MONTH LPAREN dateFieldName RPAREN
| CALENDAR_QUARTER LPAREN dateFieldName RPAREN
| CALENDAR_YEAR LPAREN dateFieldName RPAREN
Expand All @@ -637,6 +637,7 @@ soqlFunction
| FIELDS LPAREN soqlFieldsParameter RPAREN
| DISTANCE LPAREN locationValue COMMA locationValue COMMA StringLiteral RPAREN
| GROUPING LPAREN fieldName RPAREN
| CONVERT_CURRENCY LPAREN fieldName RPAREN
;

dateFieldName
Expand Down Expand Up @@ -865,7 +866,9 @@ fieldSpec

fieldList
: soslId (COMMA fieldList)*
| TOLABEL LPAREN soslId RPAREN
| TOLABEL LPAREN soslId RPAREN soslId?
| CONVERT_CURRENCY LPAREN soslId RPAREN soslId?
| FORMAT LPAREN (soslId | soqlFunction) RPAREN soslId?
;

updateList
Expand Down Expand Up @@ -965,6 +968,7 @@ id
| DISTANCE
| GEOLOCATION
| GROUPING
| CONVERT_CURRENCY
// SOQL date functions
| CALENDAR_MONTH
| CALENDAR_QUARTER
Expand Down Expand Up @@ -1164,6 +1168,7 @@ anyId
| DISTANCE
| GEOLOCATION
| GROUPING
| CONVERT_CURRENCY
// SOQL date functions
| CALENDAR_MONTH
| CALENDAR_QUARTER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,38 @@ void testGroupingFunction() {
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testConvertCurrency() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[ SELECT convertCurrency(Amount) FROM Opportunity ]"
);
ApexParser.SoqlLiteralContext context = parserAndCounter.getKey().soqlLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testConvertCurrencyWithFormat() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[\n" +
"SELECT Amount, FORMAT(amount) Amt, convertCurrency(amount) convertedAmount,\n" +
" FORMAT(convertCurrency(amount)) convertedCurrency\n" +
"FROM Opportunity where id = '006R00000024gDtIAI'\n" +
"]"
);
ApexParser.SoqlLiteralContext context = parserAndCounter.getKey().soqlLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testFormatWithAggregate() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[ SELECT FORMAT(MIN(closedate)) Amt FROM opportunity ]"
);
ApexParser.SoqlLiteralContext context = parserAndCounter.getKey().soqlLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,43 @@ void testToLabel() {
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testToLabelWithAlias() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[FIND :searchTerm IN ALL FIELDS RETURNING Account(Id, toLabel(Name) AliasName) LIMIT 10]");
ApexParser.SoslLiteralContext context = parserAndCounter.getKey().soslLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testConvertCurrency() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[ FIND 'test' RETURNING Opportunity(Name, convertCurrency(Amount), convertCurrency(Amount) AliasCurrency) ]"
);
ApexParser.SoslLiteralContext context = parserAndCounter.getKey().soslLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testConvertCurrencyWithFormat() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[ FIND 'Acme' RETURNING Account(AnnualRevenue, FORMAT(convertCurrency(AnnualRevenue)) convertedCurrency) ]"
);
ApexParser.SoslLiteralContext context = parserAndCounter.getKey().soslLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}

@Test
void testFormatWithAggregate() {
Map.Entry<ApexParser, SyntaxErrorCounter> parserAndCounter = createParser(
"[ FIND 'Acme' RETURNING Account(AnnualRevenue, FORMAT(MIN(CloseDate))) ]"
);
ApexParser.SoslLiteralContext context = parserAndCounter.getKey().soslLiteral();
assertNotNull(context);
assertEquals(0, parserAndCounter.getValue().getNumErrors());
}
}
36 changes: 35 additions & 1 deletion npm/src/__tests__/SOQLParserTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
*/
import { QueryContext, StatementContext } from "../ApexParser";
import { QueryContext, StatementContext, SoqlLiteralContext } from "../ApexParser";
import { createParser } from "./SyntaxErrorCounter";

test("SOQL Query", () => {
Expand Down Expand Up @@ -138,3 +138,37 @@ test("Grouping function", () => {
expect(context).toBeInstanceOf(QueryContext);
expect(errorCounter.getNumErrors()).toEqual(0);
});

test("Convert Currency function", () => {
const [parser, errorCounter] = createParser(
'[ SELECT convertCurrency(Amount) FROM Opportunity ]'
);
const context = parser.soqlLiteral();

expect(context).toBeInstanceOf(SoqlLiteralContext);
expect(errorCounter.getNumErrors()).toEqual(0);
});

test("Convert Currency with format", () => {
const [parser, errorCounter] = createParser(
`[
SELECT Amount, FORMAT(amount) Amt, convertCurrency(amount) convertedAmount,
FORMAT(convertCurrency(amount)) convertedCurrency
FROM Opportunity where id = '006R00000024gDtIAI'
]`
);
const context = parser.soqlLiteral();

expect(context).toBeInstanceOf(SoqlLiteralContext);
expect(errorCounter.getNumErrors()).toEqual(0);
});

test("Format function with aggregate", () => {
const [parser, errorCounter] = createParser(
'[ SELECT FORMAT(MIN(closedate)) Amt FROM opportunity ]'
)
const context = parser.soqlLiteral();

expect(context).toBeInstanceOf(SoqlLiteralContext);
expect(errorCounter.getNumErrors()).toEqual(0);
});
48 changes: 48 additions & 0 deletions npm/src/__tests__/SOSLParserTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,51 @@ test('testToLabel', () => {
expect(context).toBeInstanceOf(SoslLiteralContext)
expect(errorCounter.getNumErrors()).toEqual(0)
})

test('testToLabelWithAlias', () => {
const [parser, errorCounter] = createParser(
"[FIND :searchTerm IN ALL FIELDS RETURNING Account(Id, toLabel(Name) AliasName) LIMIT 10]")
const context = parser.soslLiteral()

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

test('testConvertCurrency', () => {
const [parser, errorCounter] = createParser(
`[
FIND 'test' RETURNING Opportunity(
Name,
convertCurrency(Amount),
convertCurrency(Amount) AliasCurrency
)
]`)
const context = parser.soslLiteral()

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

test('testConvertCurrencyWithFormat', () => {
const [parser, errorCounter] = createParser(
`[
FIND 'Acme' RETURNING Account(
AnnualRevenue,
FORMAT(convertCurrency(AnnualRevenue)) convertedCurrency
)
]`)
const context = parser.soslLiteral()

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

test('testFormatWithAggregate', () => {
const [parser, errorCounter] = createParser(
"[ FIND 'Acme' RETURNING Account(AnnualRevenue, FORMAT(MIN(CloseDate))) ]"
)
const context = parser.soslLiteral()

expect(context).toBeInstanceOf(SoslLiteralContext)
expect(errorCounter.getNumErrors()).toEqual(0)
})
Loading