-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #557 from jvalue/543-feature-enable-transforming-o…
…f-value-types feat(operators): Parse text into other Valuetypes with `asText`, `asDecimal`, `asBoolean`, `asInteger`
- Loading branch information
Showing
14 changed files
with
317 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
libs/language-server/src/lib/ast/expressions/evaluators/parse-operators-evaluators.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// SPDX-FileCopyrightText: 2024 Friedrich-Alexander-Universitat Erlangen-Nurnberg | ||
// | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
import { type InternalValueRepresentation } from '..'; | ||
import { executeDefaultTextToTextExpression } from '../test-utils'; | ||
|
||
async function expectSuccess<I extends InternalValueRepresentation>( | ||
op: string, | ||
input: string, | ||
expected: I, | ||
) { | ||
let result: InternalValueRepresentation | undefined = undefined; | ||
try { | ||
result = await executeDefaultTextToTextExpression( | ||
`${op} inputValue`, | ||
input, | ||
); | ||
} finally { | ||
expect(result).toEqual(expected); | ||
} | ||
} | ||
|
||
async function expectError(op: string, input: string) { | ||
let result: InternalValueRepresentation | undefined = undefined; | ||
try { | ||
result = await executeDefaultTextToTextExpression( | ||
`${op} inputValue`, | ||
input, | ||
); | ||
} catch { | ||
result = undefined; | ||
} finally { | ||
expect(result).toBeUndefined(); | ||
} | ||
} | ||
|
||
describe('The asText operator', () => { | ||
it('should parse text successfully', async () => { | ||
await expectSuccess('asText', 'someText', 'someText'); | ||
}); | ||
}); | ||
|
||
describe('The asDecimal operator', () => { | ||
it('should parse positive decimals successfully', async () => { | ||
await expectSuccess('asDecimal', '1.6', 1.6); | ||
}); | ||
|
||
it('should parse decimals with commas successfully', async () => { | ||
await expectSuccess('asDecimal', '1,6', 1.6); | ||
}); | ||
|
||
it('should parse negative decimals with commas successfully', async () => { | ||
await expectSuccess('asDecimal', '-1,6', -1.6); | ||
}); | ||
}); | ||
|
||
describe('The asInteger operator', () => { | ||
it('should parse positive integers successfully', async () => { | ||
await expectSuccess('asInteger', '32', 32); | ||
}); | ||
|
||
it('should parse negative integers successfully', async () => { | ||
await expectSuccess('asInteger', '-1', -1); | ||
}); | ||
|
||
it('should fail with decimal values', async () => { | ||
await expectError('asInteger', '32.5'); | ||
}); | ||
}); | ||
|
||
describe('The asBoolean operator', () => { | ||
it('should parse true and True successfully', async () => { | ||
await expectSuccess('asBoolean', 'true', true); | ||
await expectSuccess('asBoolean', 'True', true); | ||
}); | ||
|
||
it('should parse false and False successfully', async () => { | ||
await expectSuccess('asBoolean', 'false', false); | ||
await expectSuccess('asBoolean', 'False', false); | ||
}); | ||
|
||
it('should fail with 0 and 1', async () => { | ||
await expectError('asBoolean', '0'); | ||
await expectError('asBoolean', '1'); | ||
}); | ||
|
||
it('should fail on a arbitrary string', async () => { | ||
await expectError('asBoolean', 'notABoolean'); | ||
}); | ||
}); |
70 changes: 70 additions & 0 deletions
70
libs/language-server/src/lib/ast/expressions/evaluators/parse-operators-evaluators.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// SPDX-FileCopyrightText: 2024 Friedrich-Alexander-Universitat Erlangen-Nurnberg | ||
// | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import { type ValueTypeProvider } from '../../wrappers'; | ||
import { DefaultUnaryOperatorEvaluator } from '../operator-evaluator'; | ||
import { STRING_TYPEGUARD } from '../typeguards'; | ||
|
||
export class AsTextOperatorEvaluator extends DefaultUnaryOperatorEvaluator< | ||
string, | ||
string | ||
> { | ||
constructor(private readonly valueTypeProvider: ValueTypeProvider) { | ||
super('asText', STRING_TYPEGUARD); | ||
} | ||
override doEvaluate(operandValue: string): string { | ||
return this.valueTypeProvider.Primitives.Text.fromString(operandValue); | ||
} | ||
} | ||
|
||
export class AsDecimalOperatorEvaluator extends DefaultUnaryOperatorEvaluator< | ||
string, | ||
number | ||
> { | ||
constructor(private readonly valueTypeProvider: ValueTypeProvider) { | ||
super('asDecimal', STRING_TYPEGUARD); | ||
} | ||
override doEvaluate(operandValue: string): number { | ||
const dec = | ||
this.valueTypeProvider.Primitives.Decimal.fromString(operandValue); | ||
if (dec === undefined) { | ||
throw new Error(`Could not parse "${operandValue}" into a Decimal`); | ||
} | ||
return dec; | ||
} | ||
} | ||
|
||
export class AsIntegerOperatorEvaluator extends DefaultUnaryOperatorEvaluator< | ||
string, | ||
number | ||
> { | ||
constructor(private readonly valueTypeProvider: ValueTypeProvider) { | ||
super('asInteger', STRING_TYPEGUARD); | ||
} | ||
override doEvaluate(operandValue: string): number { | ||
const int = | ||
this.valueTypeProvider.Primitives.Integer.fromString(operandValue); | ||
if (int === undefined) { | ||
throw new Error(`Could not parse "${operandValue}" into an Integer`); | ||
} | ||
return int; | ||
} | ||
} | ||
|
||
export class AsBooleanOperatorEvaluator extends DefaultUnaryOperatorEvaluator< | ||
string, | ||
boolean | ||
> { | ||
constructor(private readonly valueTypeProvider: ValueTypeProvider) { | ||
super('asBoolean', STRING_TYPEGUARD); | ||
} | ||
override doEvaluate(operandValue: string): boolean { | ||
const bool = | ||
this.valueTypeProvider.Primitives.Boolean.fromString(operandValue); | ||
if (bool === undefined) { | ||
throw new Error(`Could not parse "${operandValue}" into a Boolean`); | ||
} | ||
return bool; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
.../language-server/src/lib/ast/expressions/type-computers/parse-opterators-type-computer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// SPDX-FileCopyrightText: 2024 Friedrich-Alexander-Universitat Erlangen-Nurnberg | ||
// | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
import { | ||
type ValueType, | ||
type ValueTypeProvider, | ||
} from '../../wrappers/value-type'; | ||
import { DefaultUnaryOperatorTypeComputer } from '../operator-type-computer'; | ||
|
||
export class AsDecimalOperatorTypeComputer extends DefaultUnaryOperatorTypeComputer { | ||
constructor(protected readonly valueTypeProvider: ValueTypeProvider) { | ||
super(valueTypeProvider.Primitives.Text); | ||
} | ||
|
||
override doComputeType(): ValueType { | ||
return this.valueTypeProvider.Primitives.Decimal; | ||
} | ||
} | ||
|
||
export class AsTextOperatorTypeComputer extends DefaultUnaryOperatorTypeComputer { | ||
constructor(protected readonly valueTypeProvider: ValueTypeProvider) { | ||
super(valueTypeProvider.Primitives.Text); | ||
} | ||
|
||
override doComputeType(): ValueType { | ||
return this.valueTypeProvider.Primitives.Text; | ||
} | ||
} | ||
|
||
export class AsIntegerOperatorTypeComputer extends DefaultUnaryOperatorTypeComputer { | ||
constructor(protected readonly valueTypeProvider: ValueTypeProvider) { | ||
super(valueTypeProvider.Primitives.Text); | ||
} | ||
|
||
override doComputeType(): ValueType { | ||
return this.valueTypeProvider.Primitives.Integer; | ||
} | ||
} | ||
|
||
export class AsBooleanOperatorTypeComputer extends DefaultUnaryOperatorTypeComputer { | ||
constructor(protected readonly valueTypeProvider: ValueTypeProvider) { | ||
super(valueTypeProvider.Primitives.Text); | ||
} | ||
|
||
override doComputeType(): ValueType { | ||
return this.valueTypeProvider.Primitives.Boolean; | ||
} | ||
} |
Oops, something went wrong.