Skip to content

Commit 990d2e1

Browse files
committed
refactor: simplify numeric value generation and add currency-specific method
- Refactored buildNumericRecipeValueWithPrecisionAndScale in FakerJS and Snowfakery services to remove redundant calculations and improve readability. - Added buildCurrencyRecipeValueWithPrecisionAndScale method to handle currency fields separately, ensuring full precision usage. - Updated IRecipeFakerService interface to include the new currency method.
1 parent 02dad19 commit 990d2e1

File tree

6 files changed

+36
-30
lines changed

6 files changed

+36
-30
lines changed

src/treecipe/src/RecipeFakerService.ts/FakerJSRecipeFakerService/FakerJSRecipeFakerService.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -513,25 +513,25 @@ ${this.generateTabs(5)}${randomChoicesBreakdown}`;
513513
}
514514

515515
buildNumericRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string {
516-
// Handle all numeric fields (number, currency, percent) with precision and optional scale
516+
517517
const effectiveScale = scale ?? 0;
518+
const maxValueByPrecision = '9'.repeat(precision);
518519

519520
if (effectiveScale === 0) {
520-
// Integer fields (number with scale=0, or scale not specified)
521-
// Cap precision at 15 to get accurate all-9's result (JavaScript can't represent larger integers)
522-
const safePrecision = Math.min(precision, 18);
523-
const maxValueString = '9'.repeat(safePrecision);
524-
const maxValue = parseInt(maxValueString, 10);
525-
return `${this.openingRecipeSyntax} faker.number.int({min: 0, max: ${maxValue}}) ${this.closingRecipeSyntax}`;
521+
return `${this.openingRecipeSyntax} faker.number.int({min: 0, max: ${maxValueByPrecision}}) ${this.closingRecipeSyntax}`;
526522
} else {
527-
// Decimal fields (currency, percent with scale > 0)
528-
// For decimal fields, precision includes decimal places, so max integer part is precision - scale
529-
const integerPrecision = precision - effectiveScale;
530-
const safeIntegerPrecision = Math.min(integerPrecision, 18);
531-
const maxValueString = '9'.repeat(safeIntegerPrecision);
532-
const maxValue = parseInt(maxValueString, 10);
533-
return `${this.openingRecipeSyntax} faker.finance.amount({min: 0, max: ${maxValue}, dec: ${effectiveScale}}) ${this.closingRecipeSyntax}`;
523+
return `${this.openingRecipeSyntax} faker.finance.amount({min: 0, max: ${maxValueByPrecision}, dec: ${effectiveScale}}) ${this.closingRecipeSyntax}`;
534524
}
525+
526+
}
527+
528+
buildCurrencyRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string {
529+
// Special handling for currency fields - use full precision as left_digits
530+
const effectiveScale = scale ?? 0;
531+
const maxValueByPrecision = '9'.repeat(precision);
532+
533+
return `${this.openingRecipeSyntax} faker.finance.amount({min: 0, max: ${maxValueByPrecision}, dec: ${effectiveScale}}) ${this.closingRecipeSyntax}`;
534+
535535
}
536536

537537
}

src/treecipe/src/RecipeFakerService.ts/IRecipeFakerService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ export interface IRecipeFakerService {
3030
getStandardAndGlobalValueSetTODOPlaceholderWithExample(): string
3131
buildTextRecipeValueWithLength(length: number): string
3232
buildNumericRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string
33+
buildCurrencyRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string
3334
}

src/treecipe/src/RecipeFakerService.ts/SnowfakeryRecipeFakerService/SnowfakeryRecipeFakerService.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -407,21 +407,19 @@ ${this.generateTabs(5)}${randomChoicesBreakdown}`;
407407
buildNumericRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string {
408408
// Handle all numeric fields (number, currency, percent) with precision and optional scale
409409
const effectiveScale = scale ?? 0;
410+
const maxValuePrecision = '9'.repeat(precision);
410411

411412
if (effectiveScale === 0) {
412-
// Integer fields (number with scale=0, or scale not specified)
413-
// Create max value by repeating '9' precision times, avoiding Math.pow precision issues
414-
const maxValueString = '9'.repeat(precision);
415-
const maxValue = parseInt(maxValueString, 10);
416-
return `${this.openingRecipeSyntax}fake.random_int(min=0, max=${maxValue})${this.closingRecipeSyntax}`;
413+
return `${this.openingRecipeSyntax}fake.random_int(min=0, max=${maxValuePrecision})${this.closingRecipeSyntax}`;
417414
} else {
418-
// Decimal fields (currency, percent with scale > 0)
419-
// For decimal fields, precision includes decimal places, so max integer part is precision - scale
420-
const integerPrecision = precision - effectiveScale;
421-
const maxValueString = '9'.repeat(integerPrecision);
422-
const maxValue = parseInt(maxValueString, 10);
423-
return `${this.openingRecipeSyntax}fake.pydecimal(left_digits=${integerPrecision}, right_digits=${effectiveScale}, positive=True)${this.closingRecipeSyntax}`;
415+
return `${this.openingRecipeSyntax}fake.pydecimal(left_digits=${maxValuePrecision}, right_digits=${effectiveScale}, positive=True)${this.closingRecipeSyntax}`;
424416
}
425417
}
426418

419+
buildCurrencyRecipeValueWithPrecisionAndScale(precision: number, scale?: number): string {
420+
// Special handling for currency fields - use full precision as left_digits
421+
const effectiveScale = scale ?? 0;
422+
return `${this.openingRecipeSyntax}fake.pydecimal(left_digits=${precision}, right_digits=${effectiveScale}, positive=True)${this.closingRecipeSyntax}`;
423+
}
424+
427425
}

src/treecipe/src/RecipeService/RecipeService.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ export class RecipeService {
121121
// Fall through to default if no length
122122

123123
case 'number':
124-
case 'currency':
125124
case 'percent':
126125

127126
if (xmlFieldDetail.precision) {
@@ -130,6 +129,14 @@ export class RecipeService {
130129
}
131130
// Fall through to default if no precision
132131

132+
case 'currency':
133+
134+
if (xmlFieldDetail.precision) {
135+
fakeRecipeValue = this.fakerService.buildCurrencyRecipeValueWithPrecisionAndScale(xmlFieldDetail.precision, xmlFieldDetail.scale);
136+
return fakeRecipeValue;
137+
}
138+
// Fall through to default if no precision
139+
133140
default:
134141

135142
fakeRecipeValue = this.getFakeValueIfExpectedSalesforceFieldType(fieldType);

src/treecipe/src/RecipeService/tests/FakerJSRecipeService.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ describe('FakerJSRecipeService IRecipeService Implementation Shared Intstance Te
191191
test('given expected number XMLFieldDetail, returns the expected fakerJS YAML recipe value', () => {
192192

193193
const expectedXMLDetailForNumber:XMLFieldDetail = XMLMarkupMockService.getNumberXMLFieldDetail();
194-
const expectedFakerJSExpressionForNumber = `\${{ faker.number.int({min: 0, max: 999999999999999}) }}`;
194+
const expectedFakerJSExpressionForNumber = `\${{ faker.number.int({min: 0, max: 999999999999999999}) }}`;
195195
const recordTypeNameByRecordTypeNameToXMLMarkup = {};
196196

197197
const actualFakerJSForNumber = recipeServiceWithFakerJS.getRecipeFakeValueByXMLFieldDetail(expectedXMLDetailForNumber, recordTypeNameByRecordTypeNameToXMLMarkup);
@@ -202,7 +202,7 @@ describe('FakerJSRecipeService IRecipeService Implementation Shared Intstance Te
202202
test('given expected currency XMLFieldDetail, returns the expected fakerJS YAML recipe value', () => {
203203

204204
const expectedXMLDetailForCurrency:XMLFieldDetail = XMLMarkupMockService.getCurrencyFieldDetail();
205-
const expectedFakerJSExpressionForCurrency = "\${{ faker.finance.amount({min: 0, max: 999999999999999, dec: 2}) }}";
205+
const expectedFakerJSExpressionForCurrency = "\${{ faker.finance.amount({min: 0, max: 999999999999999999, dec: 2}) }}";
206206
const recordTypeNameByRecordTypeNameToXMLMarkup = {};
207207
const actualFakerJSForCurrency = recipeServiceWithFakerJS.getRecipeFakeValueByXMLFieldDetail(expectedXMLDetailForCurrency, recordTypeNameByRecordTypeNameToXMLMarkup);
208208

src/treecipe/src/RecipeService/tests/RecipeService.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ describe('SnowfakeryRecipeService IRecipeService Implementation Shared Intstance
124124
test('given expected number XMLFieldDetail, returns the expected snowfakery YAML recipe value', () => {
125125

126126
const expectedXMLDetailForNumber:XMLFieldDetail = XMLMarkupMockService.getNumberXMLFieldDetail();
127-
const expectedSnowfakeryValueForNumber = '${{fake.random_int(min=0, max=999999999999999)}}';
127+
const expectedSnowfakeryValueForNumber = '${{fake.random_int(min=0, max=999999999999999999)}}';
128128
const recordTypeNameByRecordTypeNameToXMLMarkup = {};
129129

130130
const actualSnowfakeryValueForNumber = recipeServiceWithSnow.getRecipeFakeValueByXMLFieldDetail(expectedXMLDetailForNumber, recordTypeNameByRecordTypeNameToXMLMarkup);
@@ -136,7 +136,7 @@ describe('SnowfakeryRecipeService IRecipeService Implementation Shared Intstance
136136
test('given expected currency XMLFieldDetail, returns the expected snowfakery YAML recipe value', () => {
137137

138138
const expectedXMLDetailForCurrency:XMLFieldDetail = XMLMarkupMockService.getCurrencyFieldDetail();
139-
const expectedSnowfakeryValueForCurrency = '${{fake.pydecimal(left_digits=16, right_digits=2, positive=True)}}';
139+
const expectedSnowfakeryValueForCurrency = '${{fake.pydecimal(left_digits=18, right_digits=2, positive=True)}}';
140140
const recordTypeNameByRecordTypeNameToXMLMarkup = {};
141141
const actualSnowfakeryValueForCurrency = recipeServiceWithSnow.getRecipeFakeValueByXMLFieldDetail(expectedXMLDetailForCurrency, recordTypeNameByRecordTypeNameToXMLMarkup);
142142

0 commit comments

Comments
 (0)