mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-19 05:37:51 +00:00
256 lines
7.7 KiB
TypeScript
256 lines
7.7 KiB
TypeScript
|
/**
|
||
|
* @license
|
||
|
* Copyright 2020-2021 Balena Ltd.
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
/* tslint:disable: prefer-const no-empty */
|
||
|
|
||
|
import rewire = require('rewire');
|
||
|
import sinon = require('sinon');
|
||
|
import { expect } from 'chai';
|
||
|
|
||
|
const dataItem = {
|
||
|
name: 'item1',
|
||
|
id: 1,
|
||
|
thing_color: 'blue',
|
||
|
thing_shape: 'square',
|
||
|
};
|
||
|
|
||
|
const dataSet = [
|
||
|
{
|
||
|
name: 'item1',
|
||
|
id: 1,
|
||
|
thing_color: 'red',
|
||
|
thing_shape: 'square',
|
||
|
},
|
||
|
{
|
||
|
name: 'item2',
|
||
|
id: 2,
|
||
|
thing_color: 'blue',
|
||
|
thing_shape: 'round',
|
||
|
},
|
||
|
];
|
||
|
|
||
|
describe('outputData', function () {
|
||
|
let outputData: any;
|
||
|
let outputDataSetSpy: any;
|
||
|
let outputDataItemSpy: any;
|
||
|
|
||
|
this.beforeEach(() => {
|
||
|
const output = rewire('../../build/framework/output');
|
||
|
|
||
|
outputDataSetSpy = sinon.spy();
|
||
|
outputDataItemSpy = sinon.spy();
|
||
|
|
||
|
output.__set__('outputDataSet', outputDataSetSpy);
|
||
|
output.__set__('outputDataItem', outputDataItemSpy);
|
||
|
|
||
|
outputData = output.__get__('outputData');
|
||
|
});
|
||
|
|
||
|
it('should call outputDataSet function when data param is an array', async () => {
|
||
|
await outputData(dataSet);
|
||
|
expect(outputDataSetSpy.called).to.be.true;
|
||
|
expect(outputDataItemSpy.called).to.be.false;
|
||
|
});
|
||
|
|
||
|
it('should call outputDataItem function when data param is an object', async () => {
|
||
|
await outputData(dataItem);
|
||
|
expect(outputDataSetSpy.called).to.be.false;
|
||
|
expect(outputDataItemSpy.called).to.be.true;
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('outputDataSet', function () {
|
||
|
let outputDataSet: any;
|
||
|
let printLineSpy: any;
|
||
|
|
||
|
this.beforeEach(() => {
|
||
|
const output = rewire('../../build/framework/output');
|
||
|
printLineSpy = sinon.spy();
|
||
|
output.__set__('printLine', printLineSpy);
|
||
|
outputDataSet = output.__get__('outputDataSet');
|
||
|
});
|
||
|
|
||
|
it('should only output fields specified in `fields` param, in that order', async () => {
|
||
|
const fields = ['id', 'name', 'thing_color'];
|
||
|
const options = {};
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
// check correct number of rows (2 data, 2 header)
|
||
|
expect(printLineSpy.callCount).to.equal(4);
|
||
|
const headerLine = printLineSpy.firstCall.firstArg.toLowerCase();
|
||
|
// check we have fields we specified
|
||
|
fields.forEach((f) => {
|
||
|
expect(headerLine).to.include(f.replace(/_/g, ' '));
|
||
|
});
|
||
|
// check we don't have fields we didn't specify
|
||
|
expect(headerLine).to.not.include('thing_shape');
|
||
|
// check order
|
||
|
// split header using the `name` column as delimiter
|
||
|
const splitHeader = headerLine.split('name');
|
||
|
expect(splitHeader[0]).to.include('id');
|
||
|
expect(splitHeader[1]).to.include('thing');
|
||
|
});
|
||
|
|
||
|
/*
|
||
|
it('should output fields in the order specified in `fields` param', async () => {
|
||
|
const fields = ['thing_color', 'id', 'name'];
|
||
|
const options = {};
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
const headerLine = printLineSpy.firstCall.firstArg.toLowerCase();
|
||
|
// split header using the `it` column as delimiter
|
||
|
const splitHeader = headerLine.split('id');
|
||
|
expect(splitHeader[0]).to.include('thing');
|
||
|
expect(splitHeader[1]).to.include('name');
|
||
|
});
|
||
|
*/
|
||
|
|
||
|
it('should only output fields specified in `options.fields` if present', async () => {
|
||
|
const fields = ['name', 'id', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
// test all formats
|
||
|
fields: 'Name,thing_color,Thing shape',
|
||
|
};
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
const headerLine = printLineSpy.firstCall.firstArg.toLowerCase();
|
||
|
// check we have fields we specified
|
||
|
expect(headerLine).to.include('name');
|
||
|
expect(headerLine).to.include('thing color');
|
||
|
expect(headerLine).to.include('thing shape');
|
||
|
// check we don't have fields we didn't specify
|
||
|
expect(headerLine).to.not.include('id');
|
||
|
});
|
||
|
|
||
|
it('should output records in order specified by `options.sort` if present', async () => {
|
||
|
const fields = ['name', 'id', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
sort: 'thing shape',
|
||
|
'no-header': true,
|
||
|
};
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
// blue should come before red
|
||
|
expect(printLineSpy.getCall(0).firstArg).to.include('blue');
|
||
|
expect(printLineSpy.getCall(1).firstArg).to.include('red');
|
||
|
});
|
||
|
|
||
|
it('should only output records that match filter specified by `options.filter` if present', async () => {
|
||
|
const fields = ['name', 'id', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
filter: 'thing color=red',
|
||
|
'no-header': true,
|
||
|
};
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
// check correct number of rows (1 matched data, no-header)
|
||
|
expect(printLineSpy.callCount).to.equal(1);
|
||
|
expect(printLineSpy.getCall(0).firstArg).to.include('red');
|
||
|
});
|
||
|
|
||
|
it('should output data in json format, if `options.json` true', async () => {
|
||
|
const fields = ['name', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
json: true,
|
||
|
};
|
||
|
|
||
|
// TODO: I've run into an oclif cli-ux bug, where numbers are output as strings in json
|
||
|
// (this can be seen by including 'id' in the fields list above).
|
||
|
// Issue opened: https://github.com/oclif/cli-ux/issues/309
|
||
|
// For now removing id for this test.
|
||
|
const clonedDataSet = JSON.parse(JSON.stringify(dataSet));
|
||
|
clonedDataSet.forEach((d: any) => {
|
||
|
delete d.id;
|
||
|
});
|
||
|
|
||
|
const expectedJson = JSON.stringify(clonedDataSet, undefined, 2);
|
||
|
|
||
|
await outputDataSet(dataSet, fields, options);
|
||
|
|
||
|
expect(printLineSpy.callCount).to.equal(1);
|
||
|
expect(printLineSpy.getCall(0).firstArg).to.equal(expectedJson);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('outputDataItem', function () {
|
||
|
let outputDataItem: any;
|
||
|
let printLineSpy: any;
|
||
|
|
||
|
this.beforeEach(() => {
|
||
|
const output = rewire('../../build/framework/output');
|
||
|
printLineSpy = sinon.spy();
|
||
|
output.__set__('printLine', printLineSpy);
|
||
|
outputDataItem = output.__get__('outputDataItem');
|
||
|
});
|
||
|
|
||
|
it('should only output fields specified in `fields` param, in that order', async () => {
|
||
|
const fields = ['id', 'name', 'thing_color'];
|
||
|
const options = {};
|
||
|
|
||
|
await outputDataItem(dataItem, fields, options);
|
||
|
|
||
|
// check correct number of rows (3 fields)
|
||
|
expect(printLineSpy.callCount).to.equal(3);
|
||
|
// check we have fields we specified
|
||
|
fields.forEach((f, index) => {
|
||
|
const kvPair = printLineSpy.getCall(index).firstArg.split(':');
|
||
|
expect(kvPair[0].toLowerCase()).to.include(f.replace(/_/g, ' '));
|
||
|
expect(kvPair[1]).to.include((dataItem as any)[f]);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should only output fields specified in `options.fields` if present', async () => {
|
||
|
const fields = ['name', 'id', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
// test all formats
|
||
|
fields: 'Name,thing_color,Thing shape',
|
||
|
};
|
||
|
|
||
|
const expectedFields = ['name', 'thing_color', 'thing_shape'];
|
||
|
|
||
|
await outputDataItem(dataItem, fields, options);
|
||
|
|
||
|
// check correct number of rows (3 fields)
|
||
|
expect(printLineSpy.callCount).to.equal(3);
|
||
|
// check we have fields we specified
|
||
|
expectedFields.forEach((f, index) => {
|
||
|
const kvPair = printLineSpy.getCall(index).firstArg.split(':');
|
||
|
expect(kvPair[0].toLowerCase()).to.include(f.replace(/_/g, ' '));
|
||
|
expect(kvPair[1]).to.include((dataItem as any)[f]);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('should output data in json format, if `options.json` true', async () => {
|
||
|
const fields = ['name', 'id', 'thing_color', 'thing_shape'];
|
||
|
const options = {
|
||
|
json: true,
|
||
|
};
|
||
|
|
||
|
const expectedJson = JSON.stringify(dataItem, undefined, 2);
|
||
|
|
||
|
await outputDataItem(dataItem, fields, options);
|
||
|
|
||
|
expect(printLineSpy.callCount).to.equal(1);
|
||
|
expect(printLineSpy.getCall(0).firstArg).to.equal(expectedJson);
|
||
|
});
|
||
|
});
|