Skip to content

Commit

Permalink
Merge branch 'main' into fix/datatype/datatime-seeding
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinigami92 authored Mar 23, 2022
2 parents b4f6d73 + 1b08de8 commit ef583dd
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 15 deletions.
4 changes: 4 additions & 0 deletions .github/.codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ coverage:
default:
target: 95%
threshold: 2%
patch:
default:
target: 95%
threshold: 1%
35 changes: 23 additions & 12 deletions docs/.vitepress/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,10 @@ const sidebar = {
],
};

// grab from process.env once this is building on netlify
const algolia = {
apiKey: '',
indexName: '',
searchParameters: {
facetFilters: [''],
},
apiKey: process.env.API_KEY,
appId: process.env.APP_ID,
indexName: 'fakerjs',
};

const description =
Expand All @@ -62,27 +59,42 @@ export default defineConfig({
[
'meta',
{
property: 'og:description',
name: 'og:description',
content: description,
},
],
[
'meta',
{
name: 'twitter:description',
content: description,
},
],
[
'meta',
{
name: 'description',
content: description,
},
],
[
'meta',
{
property: 'og:image',
name: 'og:image',
content: image,
},
],
[
'meta',
{
property: 'twitter:image',
name: 'twitter:image',
content: image,
},
],
[
'meta',
{
property: 'twitter:card',
name: 'twitter:card',
content: 'summary_large_image',
},
],
Expand All @@ -96,7 +108,6 @@ export default defineConfig({
editLinkText: 'Suggest changes to this page',
nav,
sidebar,
// TODO 2022-03-06: https://github.com/faker-js/faker/issues/222
// algolia,
algolia,
},
});
15 changes: 15 additions & 0 deletions scripts/apidoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import * as TypeDoc from 'typedoc';
import { writeApiPagesIndex } from './apidoc/apiDocsWriter';
import { processDirectMethods } from './apidoc/directMethods';
import { processModuleMethods } from './apidoc/moduleMethods';
import {
DefaultParameterAwareSerializer,
parameterDefaultReader,
patchProjectParameterDefaults,
} from './apidoc/parameterDefaults';
import type { PageIndex } from './apidoc/utils';
import { pathOutputDir } from './apidoc/utils';

Expand All @@ -15,6 +20,14 @@ async function build(): Promise<void> {
// If you want TypeDoc to load typedoc.json files
//app.options.addReader(new TypeDoc.TypeDocReader());

// Read parameter defaults
app.converter.on(
TypeDoc.Converter.EVENT_CREATE_DECLARATION,
parameterDefaultReader
);
// Add to debug json output
app.serializer.addSerializer(new DefaultParameterAwareSerializer(undefined));

app.bootstrap({
entryPoints: ['src/index.ts'],
pretty: true,
Expand All @@ -31,6 +44,8 @@ async function build(): Promise<void> {
await app.generateJson(project, pathOutputJson);
console.log(pathOutputDir);

patchProjectParameterDefaults(project);

const modulesPages: PageIndex = [];
modulesPages.push({ text: 'Localization', link: '/api/localization.html' });
modulesPages.push(...processModuleMethods(project));
Expand Down
130 changes: 130 additions & 0 deletions scripts/apidoc/parameterDefaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import type {
Context,
DeclarationReflection,
EventCallback,
JSONOutput,
ProjectReflection,
SignatureReflection,
} from 'typedoc';
import {
Reflection,
ReflectionKind,
SerializerComponent,
TypeScript,
} from 'typedoc';

const reflectionKindFunctionOrMethod =
ReflectionKind.Function | ReflectionKind.Method;

interface ParameterDefaultsAware extends Reflection {
implementationDefaultParameters: string[];
}

/**
* TypeDoc EventCallback for EVENT_CREATE_DECLARATION events that reads the default parameters from the implementation.
*/
export const parameterDefaultReader: EventCallback = (
context: Context,
reflection: Reflection
): void => {
const symbol = context.project.getSymbolFromReflection(reflection);
if (!symbol) return;

if (
reflection.kindOf(reflectionKindFunctionOrMethod) &&
symbol.declarations?.length
) {
const lastDeclaration = symbol.declarations[symbol.declarations.length - 1];
if (TypeScript.isFunctionLike(lastDeclaration)) {
(reflection as ParameterDefaultsAware).implementationDefaultParameters =
lastDeclaration.parameters.map((param) =>
cleanParameterDefault(param.initializer?.getText())
);
}
}
};

/**
* Removes compile expressions that don't add any value for readers.
*
* @param value The default value to clean.
* @returns The cleaned default value.
*/
function cleanParameterDefault(value?: string): string {
if (value == null) {
return undefined;
}
// Strip type casts: "'foobar' as unknown as T" => "'foobar'"
return value.replace(/ as unknown as [A-Za-z<>]+/, '');
}

/**
* Serializer that adds the `implementationDefaultParameters` to the JSON output.
*/
export class DefaultParameterAwareSerializer extends SerializerComponent<Reflection> {
serializeGroup(instance: unknown): boolean {
return instance instanceof Reflection;
}

supports(item: unknown): boolean {
return true;
}

toObject(item: Reflection, obj?: object): Partial<JSONOutput.Reflection> {
(obj as ParameterDefaultsAware).implementationDefaultParameters = (
item as ParameterDefaultsAware
).implementationDefaultParameters;
return obj;
}
}

/**
* Replaces all methods' last signature's parameter's default value with the default value read from the implementation.
*
* @param project The project to patch.
*/
export function patchProjectParameterDefaults(
project: ProjectReflection
): void {
const functionOrMethods = project.getReflectionsByKind(
reflectionKindFunctionOrMethod
) as DeclarationReflection[];
for (const functionOrMethod of functionOrMethods) {
patchMethodParameterDefaults(functionOrMethod);
}
}

/**
* Replaces the last signature's parameter's default value with the default value read from the implementation.
*
* @param method The method to patch.
*/
function patchMethodParameterDefaults(method: DeclarationReflection): void {
const signatures = method.signatures;
const signature = signatures[signatures.length - 1];
const parameterDefaults = (method as unknown as ParameterDefaultsAware)
.implementationDefaultParameters;
if (parameterDefaults) {
patchSignatureParameterDefaults(signature, parameterDefaults);
}
}

/**
* Replaces the given signature's parameter's default value with the given default values.
*
* @param signature The signature to patch.
* @param parameterDefaults The defaults to add.
*/
function patchSignatureParameterDefaults(
signature: SignatureReflection,
parameterDefaults: string[]
): void {
const signatureParameters = signature.parameters;
if (signatureParameters.length !== parameterDefaults.length) {
throw new Error('Unexpected parameter length mismatch');
}
signatureParameters.forEach(
(param, index) =>
(param.defaultValue = parameterDefaults[index] || param.defaultValue)
);
}
26 changes: 25 additions & 1 deletion scripts/apidoc/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ function analyzeParameter(parameter: ParameterReflection): {
const name = parameter.name;
const declarationName = name + (isOptional(parameter) ? '?' : '');
const type = parameter.type;
const defaultValue = parameter.defaultValue;
const commentDefault = extractDefaultFromComment(parameter.comment);
const defaultValue = parameter.defaultValue ?? commentDefault;

let signatureText = '';
if (defaultValue) {
Expand Down Expand Up @@ -200,6 +201,7 @@ function analyzeParameterOptions(
return properties.map((property) => ({
name: `${name}.${property.name}${isOptional(property) ? '?' : ''}`,
type: declarationTypeToText(property),
default: extractDefaultFromComment(property.comment),
description: mdToHtml(
toBlock(property.comment ?? property.signatures?.[0].comment)
),
Expand Down Expand Up @@ -284,3 +286,25 @@ function signatureTypeToText(signature: SignatureReflection): string {
.map((p) => `${p.name}: ${typeToText(p.type)}`)
.join(', ')}) => ${typeToText(signature.type)}`;
}

/**
* Extracts and removed the parameter default from the comments.
*
* @param comment The comment to extract the default from.
* @returns The extracted default value.
*/
function extractDefaultFromComment(comment?: Comment): string {
if (!comment) {
return;
}
const text = comment.shortText;
if (!text || text.trim() === '') {
return;
}
const result = /(.*)[ \n]Defaults to `([^`]+)`./.exec(text);
if (!result) {
return;
}
comment.shortText = result[1];
return result[2];
}
8 changes: 6 additions & 2 deletions src/iban.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,12 @@ export = {
},
{
country: 'CR',
total: 21,
total: 22,
bban: [
{
type: 'n',
count: 1,
},
{
type: 'n',
count: 3,
Expand All @@ -217,7 +221,7 @@ export = {
count: 14,
},
],
format: 'CRkk bbbc cccc cccc cccc c',
format: 'CRkk xbbb cccc cccc cccc cc',
},
{
country: 'HR',
Expand Down
44 changes: 44 additions & 0 deletions test/finance_iban.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,50 @@ describe('finance_iban', () => {
'the result should be equal to 1'
).toBe(1);
});

it('IBAN for Costa Rica is correct', () => {
// Costa Rica
// https://wise.com/us/iban/costa-rica
// Length 22
// BBAN 1n,3n,14n
// CRkk xbbb cccc cccc cccc cccc cccc
// x = reserve digit
// b = National bank code (digits)
// c = Account number (digits)

// example IBAN CR05 0152 0200 1026 2840 66

const iban = faker.finance.iban(false, 'CR');

expect(iban).satisfy(validator.isIBAN);

const ibanFormated = iban.match(/.{1,4}/g).join(' ');
const bban = iban.substring(4) + iban.substring(0, 4);

expect(
22,
`CR IBAN would be 22 chars length, given is ${iban.length}`
).toBe(iban.length);

expect(
iban.substring(0, 2),
iban.substring(0, 2) +
"must start with 'CR' in CR IBAN " +
ibanFormated
).to.eq('CR');

expect(
iban.substring(2, 22),
iban.substring(2, 22) +
' must contains only digit in AZ IBAN ' +
ibanFormated
).match(/^\d{20}$/);

expect(
ibanLib.mod97(ibanLib.toDigitString(bban)),
'the result should be equal to 1'
).toBe(1);
});
});
}
});
Expand Down

0 comments on commit ef583dd

Please sign in to comment.