Skip to content

Commit

Permalink
test: convert compound objects into CnabRegistros
Browse files Browse the repository at this point in the history
  • Loading branch information
yxuo committed Feb 22, 2024
1 parent 4f70610 commit 08fe640
Show file tree
Hide file tree
Showing 10 changed files with 360 additions and 29 deletions.
195 changes: 194 additions & 1 deletion src/cnab/cnab-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import { getRegistroLine, validateRegistroPosition } from './cnab-utils';
import {
getPlainRegistros,
getRegistroLine,
validateRegistroPosition,
} from './cnab-utils';
import { ICnabRegistroFieldMap } from './interfaces/cnab-registro-field-map.interface';
import { CnabField } from './types/cnab-field.type';
import { CnabFileMapped } from './types/cnab-file-mapped.type';
import { CnabFile } from './types/cnab-file.type';
import { CnabLoteMapped } from './types/cnab-lote-mapped.type';
import { CnabLote } from './types/cnab-lote.type';
import { CnabRegistroMapped } from './types/cnab-registro-mapped.type';
import { CnabRegistro } from './types/cnab-registro.type';

process.env.TZ = 'UTC';
Expand Down Expand Up @@ -183,4 +194,186 @@ describe('cnab-utils.ts', () => {
expect(resultGreather).toThrowError();
});
});

describe('getPlainRegistros()', () => {
const fields: Record<string, CnabField>[] = [
{ a: { picture: 'X(1)', pos: [1, 1], value: ' ' } },
{ b: { picture: 'X(2)', pos: [1, 2], value: ' ' } },
{ c: { picture: 'X(3)', pos: [1, 3], value: ' ' } },
{ d: { picture: 'X(4)', pos: [1, 4], value: ' ' } },
{ e: { picture: 'X(5)', pos: [1, 5], value: ' ' } },
{ f: { picture: 'X(6)', pos: [1, 6], value: ' ' } },
{ g: { picture: 'X(7)', pos: [1, 7], value: ' ' } },
{ h: { picture: 'X(8)', pos: [1, 8], value: ' ' } },
{ i: { picture: 'X(9)', pos: [1, 9], value: ' ' } },
{ j: { picture: 'X(10)', pos: [1, 10], value: ' ' } },
{ k: { picture: 'X(11)', pos: [1, 11], value: ' ' } },
{ l: { picture: 'X(12)', pos: [1, 12], value: ' ' } },
{ m: { picture: 'X(13)', pos: [1, 13], value: ' ' } },
{ n: { picture: 'X(14)', pos: [1, 14], value: ' ' } },
{ o: { picture: 'X(15)', pos: [1, 15], value: ' ' } },
{ p: { picture: 'X(16)', pos: [1, 16], value: ' ' } },
{ q: { picture: 'X(17)', pos: [1, 17], value: ' ' } },
{ r: { picture: 'X(18)', pos: [1, 18], value: ' ' } },
{ s: { picture: 'X(19)', pos: [1, 19], value: ' ' } },
{ t: { picture: 'X(20)', pos: [1, 20], value: ' ' } },
{ u: { picture: 'X(21)', pos: [1, 21], value: ' ' } },
{ v: { picture: 'X(22)', pos: [1, 22], value: ' ' } },
{ w: { picture: 'X(23)', pos: [1, 23], value: ' ' } },
{ x: { picture: 'X(24)', pos: [1, 24], value: ' ' } },
];
const mapping: ICnabRegistroFieldMap = {
registroCodigoField: '',
registroLoteField: '',
};

it('should convert CnabLote record', () => {
// Arrange
const registros: CnabRegistro[] = [
{ ...fields[0], ...fields[1] },
{ ...fields[2], ...fields[3] },
{ ...fields[4], ...fields[5] },
{ ...fields[6], ...fields[7] },
];
const lote: CnabLote = {
headerLote: registros[0],
registros: [registros[1], registros[2]],
trailerLote: registros[3],
};

// Act
const result = getPlainRegistros(lote);

// Assert
expect(result).toEqual(registros);
});

it('should convert CnabLoteMapped record', () => {
// Arrange
const registros: CnabRegistroMapped[] = [
{
registro: { ...fields[0], ...fields[1] },
fieldMap: mapping,
},
{
registro: { ...fields[2], ...fields[3] },
fieldMap: mapping,
},
{
registro: { ...fields[4], ...fields[5] },
fieldMap: mapping,
},
{
registro: { ...fields[6], ...fields[7] },
fieldMap: mapping,
},
];
const lote: CnabLoteMapped = {
headerLote: registros[0],
registros: [registros[1], registros[2]],
trailerLote: registros[3],
};

// Act
const result = getPlainRegistros(lote);

// Assert
expect(result).toEqual([
{ ...fields[0], ...fields[1] },
{ ...fields[2], ...fields[3] },
{ ...fields[4], ...fields[5] },
{ ...fields[6], ...fields[7] },
]);
});

it('should convert CnabFile record', () => {
// Arrange
const registros: CnabRegistro[] = [
{ ...fields[0], ...fields[1] },
{ ...fields[2], ...fields[3] },
{ ...fields[4], ...fields[5] },
{ ...fields[6], ...fields[7] },
{ ...fields[8], ...fields[9] },
{ ...fields[10], ...fields[11] },
{ ...fields[12], ...fields[13] },
{ ...fields[14], ...fields[15] },
{ ...fields[16], ...fields[27] },
{ ...fields[18], ...fields[19] },
];
const lotes: CnabLote[] = [
{
headerLote: registros[1],
registros: [registros[2], registros[3]],
trailerLote: registros[4],
},
{
headerLote: registros[5],
registros: [registros[6], registros[7]],
trailerLote: registros[8],
},
];
const file: CnabFile = {
headerArquivo: registros[0],
lotes,
trailerArquivo: registros[9],
};

// Act
const result = getPlainRegistros(file);

// Assert
expect(result).toEqual(registros);
});

it('should convert CnabFileMapped record', () => {
// Arrange
const registros: CnabRegistroMapped[] = [
{ registro: { ...fields[0], ...fields[1] }, fieldMap: mapping },
{ registro: { ...fields[2], ...fields[3] }, fieldMap: mapping },
{ registro: { ...fields[4], ...fields[5] }, fieldMap: mapping },
{ registro: { ...fields[6], ...fields[7] }, fieldMap: mapping },
{ registro: { ...fields[8], ...fields[9] }, fieldMap: mapping },
{ registro: { ...fields[10], ...fields[11] }, fieldMap: mapping },
{ registro: { ...fields[12], ...fields[13] }, fieldMap: mapping },
{ registro: { ...fields[14], ...fields[15] }, fieldMap: mapping },
{ registro: { ...fields[16], ...fields[17] }, fieldMap: mapping },
{ registro: { ...fields[18], ...fields[19] }, fieldMap: mapping },
];

const lotes: CnabLoteMapped[] = [
{
headerLote: registros[1],
registros: [registros[2], registros[3]],
trailerLote: registros[4],
},
{
headerLote: registros[5],
registros: [registros[6], registros[7]],
trailerLote: registros[8],
},
];
const file: CnabFileMapped = {
headerArquivo: registros[0],
lotes,
trailerArquivo: registros[9],
};

// Act
const result = getPlainRegistros(file);

// Assert
expect(result).toEqual([
{ ...fields[0], ...fields[1] },
{ ...fields[2], ...fields[3] },
{ ...fields[4], ...fields[5] },
{ ...fields[6], ...fields[7] },
{ ...fields[8], ...fields[9] },
{ ...fields[10], ...fields[11] },
{ ...fields[12], ...fields[13] },
{ ...fields[14], ...fields[15] },
{ ...fields[16], ...fields[17] },
{ ...fields[18], ...fields[19] },
]);
});
});
});
77 changes: 61 additions & 16 deletions src/cnab/cnab-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { Exception } from 'handlebars';
import { CNAB_SUPPORTED_FORMATS } from './cnab-consts';
import { getCnabPictureValue } from './cnab-field-utils';
import { CnabField } from './types/cnab-field.type';
import {
CnabFileMapped,
isCnabFileMapped,
} from './types/cnab-file-mapped.type';
import { CnabFile, isCnabFile } from './types/cnab-file.type';
import {
CnabLoteMapped,
isCnabLoteMapped,
} from './types/cnab-lote-mapped.type';
import { CnabLote, isCnabLote } from './types/cnab-lote.type';
import { CnabRegistro } from './types/cnab-registro.type';

Expand Down Expand Up @@ -50,22 +60,57 @@ export function validateRegistroPosition(
}

export function getPlainRegistros(
cnab: Record<string, CnabRegistro | CnabRegistro[] | CnabLote[]>,
cnab: CnabFile | CnabFileMapped | CnabLote | CnabLoteMapped,
): CnabRegistro[] {
// return
const plainCnab: CnabRegistro[] = [];
for (const value of Object.values(cnab)) {
if (Array.isArray(value)) {
if (isCnabLote(value)) {
for (const lote of value as CnabLote[]) {
plainCnab.push(...getPlainRegistros(lote));
}
} else {
plainCnab.push(...(value as CnabRegistro[]));
}
} else {
plainCnab.push(value);
}
const plainRegistros: CnabRegistro[] = [];

if (isCnabLote(cnab)) {
plainRegistros.push(...getPlainRegistrosFromLote(cnab as CnabLote));
} else if (isCnabLoteMapped(cnab)) {
plainRegistros.push(
...getPlainRegistrosFromLoteMapped(cnab as CnabLoteMapped),
);
} else if (isCnabFile(cnab)) {
plainRegistros.push(...getPlainRegistrosFromCnabFile(cnab as CnabFile));
} else if (isCnabFileMapped(cnab)) {
plainRegistros.push(
...getPlainRegistrosFromCnabFileMapped(cnab as CnabFileMapped),
);
} else {
throw new Exception('Unsupported object type.');
}
return plainCnab;
return plainRegistros;
}

function getPlainRegistrosFromCnabFile(file: CnabFile): CnabRegistro[] {
return [
file.headerArquivo,
...file.lotes.reduce((l, i) => [...l, ...getPlainRegistrosFromLote(i)], []),
file.trailerArquivo,
];
}

function getPlainRegistrosFromCnabFileMapped(
file: CnabFileMapped,
): CnabRegistro[] {
return [
file.headerArquivo.registro,
...file.lotes.reduce(
(l, i) => [...l, ...getPlainRegistrosFromLoteMapped(i)],
[],
),
file.trailerArquivo.registro,
];
}

function getPlainRegistrosFromLote(lote: CnabLote): CnabRegistro[] {
return [lote.headerLote, ...lote.registros, lote.trailerLote];
}

function getPlainRegistrosFromLoteMapped(lote: CnabLoteMapped): CnabRegistro[] {
return [
lote.headerLote.registro,
...lote.registros.reduce((l, i) => [...l, i.registro], []),
lote.trailerLote.registro,
];
}
12 changes: 12 additions & 0 deletions src/cnab/types/cnab-field.type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isArrayContainEqual } from 'src/utils/array-utils';

export type CnabField = {
pos: [number, number];
picture: string;
Expand All @@ -9,3 +11,13 @@ export type CnabField = {
*/
dateFormat?: string;
};

export function isCnabField(value: any) {
return (
typeof value === 'object' &&
isArrayContainEqual(Object.keys(value), ['pos', 'picture', 'value']) &&
typeof value?.picture === 'string' &&
typeof value?.pos[0] === 'number' &&
typeof value?.pos[1] === 'number'
);
}
25 changes: 25 additions & 0 deletions src/cnab/types/cnab-file-mapped.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { isArrayContainEqual } from 'src/utils/array-utils';
import {
CnabRegistroMapped,
isCnabRegistroMapped,
} from './cnab-registro-mapped.type';
import { CnabLoteMapped } from './cnab-lote-mapped.type';

export type CnabFileMapped = {
headerArquivo: CnabRegistroMapped;
lotes: CnabLoteMapped[];
trailerArquivo: CnabRegistroMapped;
};

export function isCnabFileMapped(value: any) {
return (
typeof value === 'object' &&
!Array.isArray(value) &&
isArrayContainEqual(Object.keys(value), [
'headerArquivo',
'lotes',
'trailerArquivo',
]) &&
isCnabRegistroMapped(value.headerArquivo)
);
}
16 changes: 15 additions & 1 deletion src/cnab/types/cnab-file.type.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
import { isArrayContainEqual } from 'src/utils/array-utils';
import { CnabLote } from './cnab-lote.type';
import { CnabRegistro } from './cnab-registro.type';
import { CnabRegistro, isCnabRegistro } from './cnab-registro.type';

export type CnabFile = {
headerArquivo: CnabRegistro;
lotes: CnabLote[];
trailerArquivo: CnabRegistro;
};

export function isCnabFile(value: any) {
return (
typeof value === 'object' &&
!Array.isArray(value) &&
isArrayContainEqual(Object.keys(value), [
'headerArquivo',
'lotes',
'trailerArquivo',
]) &&
isCnabRegistro(value.headerArquivo)
);
}
24 changes: 24 additions & 0 deletions src/cnab/types/cnab-lote-mapped.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { isArrayContainEqual } from 'src/utils/array-utils';
import {
CnabRegistroMapped,
isCnabRegistroMapped,
} from './cnab-registro-mapped.type';

export type CnabLoteMapped = {
headerLote: CnabRegistroMapped;
registros: CnabRegistroMapped[];
trailerLote: CnabRegistroMapped;
};

export function isCnabLoteMapped(value: any) {
return (
typeof value === 'object' &&
!Array.isArray(value) &&
isArrayContainEqual(Object.keys(value), [
'headerLote',
'registros',
'trailerLote',
]) &&
isCnabRegistroMapped(value.headerLote)
);
}
Loading

0 comments on commit 08fe640

Please sign in to comment.