Skip to content

Commit

Permalink
test: more coverage and cases for typeguard and SC
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Sep 18, 2023
1 parent f3fa732 commit c9288ff
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/utils/previewOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { filePathsFromMetadataComponent } from '@salesforce/source-deploy-retrieve/lib/src/utils/filePathGenerator';

import { SourceTracking } from '@salesforce/source-tracking';
import { isSourceComponent } from './types';
import { isSourceComponentWithXml } from './types';

Messages.importMessagesDirectory(__dirname);
const messages = Messages.loadMessages('@salesforce/plugin-deploy-retrieve', 'previewMessages');
Expand Down Expand Up @@ -64,7 +64,7 @@ const resolvePaths = (filenames: string[]): Array<Pick<PreviewFile, 'type' | 'fu
return undefined;
}
})
.filter(isSourceComponent)
.filter(isSourceComponentWithXml)
.map((sc) => ({ fullName: sc.fullName, type: sc.type.name, path: ensureAbsolutePath(sc.xml) }));
// dedupe by xml path
return Array.from(new Map(sourceComponents.map((sc) => [sc.path, sc])).values());
Expand Down
17 changes: 11 additions & 6 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,19 @@ export type Formatter<T> = {
};

/** validates source component with fullname, type, and xml props */
export const isSourceComponent = (sc: unknown): sc is SourceComponent & { xml: string } =>
export const isSourceComponent = (sc: unknown): sc is SourceComponent =>
isObject(sc) &&
'fullName' in sc &&
'type' in sc &&
'xml' in sc &&
typeof sc.fullName === 'string' &&
typeof sc.type === 'string' &&
typeof sc.xml === 'string';
typeof sc.type === 'object' &&
sc.type !== null &&
'name' in sc.type &&
typeof sc.type.name === 'string' &&
'fullName' in sc &&
// (typeof sc.fullName === 'string' || typeof sc.fullName === 'function');
typeof sc.fullName === 'string';

export const isSourceComponentWithXml = (sc: unknown): sc is SourceComponent & { xml: string } =>
isSourceComponent(sc) && 'xml' in sc && typeof sc.xml === 'string';

export const isSdrFailure = (fileResponse: FileResponse): fileResponse is FileResponseFailure =>
fileResponse.state === ComponentStatus.Failed;
Expand Down
52 changes: 41 additions & 11 deletions test/utils/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,28 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { expect } from 'chai';
import { expect, config } from 'chai';
import { SourceComponent, RegistryAccess } from '@salesforce/source-deploy-retrieve';
import { isSourceComponent } from '../../src/utils/types';
import { isSourceComponent, isSourceComponentWithXml } from '../../src/utils/types';

config.truncateThreshold = 0;

const reg = new RegistryAccess();
const type = reg.getTypeByName('ApexClass');

describe('isSourceComponent (type guard)', () => {
describe('good', () => {
it('full, correct definition', () => {
expect({ fullName: 'foo', type: 'fooType', xml: 'fooXml', content: 'fooContent' }).to.satisfy(isSourceComponent);
expect({ fullName: 'foo', type, xml: 'fooXml', content: 'fooContent' }).to.satisfy(isSourceComponent);
});
it('SC constructed with xml', () => {
const reg = new RegistryAccess();
const type = reg.getTypeByName('ApexClass');
expect(new SourceComponent({ name: 'foo', type, xml: 'classes/foo.cls' })).to.not.satisfy(isSourceComponent);
expect(new SourceComponent({ name: 'foo', type, xml: 'classes/foo.cls' })).to.satisfy(isSourceComponent);
});
it('SC constructed with no xml', () => {
const sc = new SourceComponent({ name: 'foo', type });
// console.log(sc);
// console.log(typeof sc.fullName);
expect(sc).to.satisfy(isSourceComponent);
});
});
describe('bad', () => {
Expand All @@ -27,16 +36,37 @@ describe('isSourceComponent (type guard)', () => {
it('empty object', () => {
expect({}).to.not.satisfy(isSourceComponent);
});

it('object.type is set to undefined', () => {
expect({ fullName: 'foo', type: undefined, xml: 'fooXml' }).to.not.satisfy(isSourceComponent);
});
});
});

describe('isSourceComponentWithXml (type guard)', () => {
describe('good', () => {
it('full, correct definition', () => {
expect({ fullName: 'foo', type, xml: 'fooXml', content: 'fooContent' }).to.satisfy(isSourceComponentWithXml);
});
it('SC constructed with xml', () => {
expect(new SourceComponent({ name: 'foo', type, xml: 'classes/foo.cls' })).to.satisfy(isSourceComponentWithXml);
});
});
describe('bad', () => {
it('object is undefined', () => {
expect(undefined).to.not.satisfy(isSourceComponentWithXml);
});
it('empty object', () => {
expect({}).to.not.satisfy(isSourceComponentWithXml);
});
it('object.xml is undefined', () => {
expect({ fullName: 'foo', type: 'fooType', content: 'fooContent' }).to.not.satisfy(isSourceComponent);
expect({ fullName: 'foo', type: 'fooType', content: 'fooContent' }).to.not.satisfy(isSourceComponentWithXml);
});
it('object.type is set to undefined', () => {
expect({ fullName: 'foo', type: undefined, xml: 'fooXml' }).to.not.satisfy(isSourceComponent);
expect({ fullName: 'foo', type: undefined, xml: 'fooXml' }).to.not.satisfy(isSourceComponentWithXml);
});
it('SC constructed with no xml', () => {
const reg = new RegistryAccess();
const type = reg.getTypeByName('ApexClass');
expect(new SourceComponent({ name: 'foo', type })).to.not.satisfy(isSourceComponent);
expect(new SourceComponent({ name: 'foo', type })).to.not.satisfy(isSourceComponentWithXml);
});
});
});

0 comments on commit c9288ff

Please sign in to comment.