Skip to content

Commit

Permalink
[7.x] Convert common/lib files to Typescript and Jest (#37640) (#39109)
Browse files Browse the repository at this point in the history
* Convert common/lib files to Typescript and Jest  (#37640)

* Remove unused lib and associated tests

* Convert unquote string to TS and Jest

* Convert getFieldType to TS and Jest

* Convert httpurl to TS and Jest

* Remove latest_change and tests

* Convert pivot_object_array to TS and Jest

* Address PR feedback

* Fix type
  • Loading branch information
Corey Robertson authored Jul 1, 2019
1 parent c66eefb commit f7c0982
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/

const emptyTable = {
import { Datatable } from '../../../types';

const emptyTable: Datatable = {
type: 'datatable',
columns: [],
rows: [],
};

const testTable = {
const testTable: Datatable = {
type: 'datatable',
columns: [
{
Expand Down Expand Up @@ -101,7 +103,7 @@ const testTable = {
],
};

const stringTable = {
const stringTable: Datatable = {
type: 'datatable',
columns: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';
import { getFieldType } from '../get_field_type';
import {
emptyTable,
Expand All @@ -13,14 +12,14 @@ import {

describe('getFieldType', () => {
it('returns type of a field in a datatable', () => {
expect(getFieldType(testTable.columns, 'name')).to.be('string');
expect(getFieldType(testTable.columns, 'time')).to.be('date');
expect(getFieldType(testTable.columns, 'price')).to.be('number');
expect(getFieldType(testTable.columns, 'quantity')).to.be('number');
expect(getFieldType(testTable.columns, 'in_stock')).to.be('boolean');
expect(getFieldType(testTable.columns, 'name')).toBe('string');
expect(getFieldType(testTable.columns, 'time')).toBe('date');
expect(getFieldType(testTable.columns, 'price')).toBe('number');
expect(getFieldType(testTable.columns, 'quantity')).toBe('number');
expect(getFieldType(testTable.columns, 'in_stock')).toBe('boolean');
});
it(`returns 'null' if field does not exist in datatable`, () => {
expect(getFieldType(testTable.columns, 'foo')).to.be('null');
expect(getFieldType(emptyTable.columns, 'foo')).to.be('null');
expect(getFieldType(testTable.columns, 'foo')).toBe('null');
expect(getFieldType(emptyTable.columns, 'foo')).toBe('null');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,27 @@
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';
import { isValidHttpUrl } from '../httpurl';

describe('httpurl.isValidHttpUrl', () => {
it('matches HTTP URLs', () => {
expect(isValidHttpUrl('http://server.com/veggie/hamburger.jpg')).to.be(true);
expect(isValidHttpUrl('https://server.com:4443/veggie/hamburger.jpg')).to.be(true);
expect(isValidHttpUrl('http://user:[email protected]:4443/veggie/hamburger.jpg')).to.be(true);
expect(isValidHttpUrl('http://virtual-machine/veggiehamburger.jpg')).to.be(true);
expect(isValidHttpUrl('https://virtual-machine:44330/veggie.jpg?hamburger')).to.be(true);
expect(isValidHttpUrl('http://192.168.1.50/veggie/hamburger.jpg')).to.be(true);
expect(isValidHttpUrl('https://2600::/veggie/hamburger.jpg')).to.be(true); // ipv6
expect(isValidHttpUrl('http://2001:4860:4860::8844/veggie/hamburger.jpg')).to.be(true); // ipv6
expect(isValidHttpUrl('http://server.com/veggie/hamburger.jpg')).toBe(true);
expect(isValidHttpUrl('https://server.com:4443/veggie/hamburger.jpg')).toBe(true);
expect(isValidHttpUrl('http://user:[email protected]:4443/veggie/hamburger.jpg')).toBe(true);
expect(isValidHttpUrl('http://virtual-machine/veggiehamburger.jpg')).toBe(true);
expect(isValidHttpUrl('https://virtual-machine:44330/veggie.jpg?hamburger')).toBe(true);
expect(isValidHttpUrl('http://192.168.1.50/veggie/hamburger.jpg')).toBe(true);
expect(isValidHttpUrl('https://2600::/veggie/hamburger.jpg')).toBe(true); // ipv6
expect(isValidHttpUrl('http://2001:4860:4860::8844/veggie/hamburger.jpg')).toBe(true); // ipv6
});
it('rejects non-HTTP URLs', () => {
expect(isValidHttpUrl('')).to.be(false);
expect(isValidHttpUrl('http://server.com')).to.be(false);
expect(isValidHttpUrl('file:///Users/programmer/Pictures/hamburger.jpeg')).to.be(false);
expect(isValidHttpUrl('ftp://hostz.com:1111/path/to/image.png')).to.be(false);
expect(isValidHttpUrl('ftp://user:password@host:1111/path/to/image.png')).to.be(false);
expect(isValidHttpUrl('')).toBe(false);
expect(isValidHttpUrl('http://server.com')).toBe(false);
expect(isValidHttpUrl('file:///Users/programmer/Pictures/hamburger.jpeg')).toBe(false);
expect(isValidHttpUrl('ftp://hostz.com:1111/path/to/image.png')).toBe(false);
expect(isValidHttpUrl('ftp://user:password@host:1111/path/to/image.png')).toBe(false);
expect(
isValidHttpUrl('data:image/gif;base64,R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P+...')
).to.be(false);
).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';
import { pivotObjectArray } from '../pivot_object_array';

interface Car {
make: string;
model: string;
price: string;
}

describe('pivotObjectArray', () => {
let rows;
let rows: Car[] = [];

beforeEach(() => {
rows = [
Expand All @@ -19,37 +24,39 @@ describe('pivotObjectArray', () => {
});

it('converts array of objects', () => {
const data = pivotObjectArray(rows);
const data = pivotObjectArray<Car>(rows);

expect(typeof data).toBe('object');

expect(data).to.be.an('object');
expect(data).to.have.property('make');
expect(data).to.have.property('model');
expect(data).to.have.property('price');
expect(data).toHaveProperty('make');
expect(data).toHaveProperty('model');
expect(data).toHaveProperty('price');

expect(data.make).to.eql(['honda', 'toyota', 'tesla']);
expect(data.model).to.eql(['civic', 'corolla', 'model 3']);
expect(data.price).to.eql(['10000', '12000', '35000']);
expect(data.make).toEqual(['honda', 'toyota', 'tesla']);
expect(data.model).toEqual(['civic', 'corolla', 'model 3']);
expect(data.price).toEqual(['10000', '12000', '35000']);
});

it('uses passed in column list', () => {
const data = pivotObjectArray(rows, ['price']);
const data = pivotObjectArray<Car, 'price'>(rows, ['price']);

expect(data).to.be.an('object');
expect(data).to.eql({ price: ['10000', '12000', '35000'] });
expect(typeof data).toBe('object');
expect(data).toEqual({ price: ['10000', '12000', '35000'] });
});

it('adds missing columns with undefined values', () => {
const data = pivotObjectArray(rows, ['price', 'missing']);
const data = pivotObjectArray<Car, 'price' | 'missing'>(rows, ['price', 'missing']);

expect(data).to.be.an('object');
expect(data).to.eql({
expect(typeof data).toBe('object');
expect(data).toEqual({
price: ['10000', '12000', '35000'],
missing: [undefined, undefined, undefined],
});
});

it('throws when given an invalid column list', () => {
// @ts-ignore testing potential calls from legacy code that should throw
const check = () => pivotObjectArray(rows, [{ name: 'price' }, { name: 'missing' }]);
expect(check).to.throwException('Columns should be an array of strings');
expect(check).toThrowError('Columns should be an array of strings');
});
});

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { unquoteString } from '../unquote_string';

describe('unquoteString', () => {
it('removes double quotes', () => {
expect(unquoteString('"hello world"')).toEqual('hello world');
});

it('removes single quotes', () => {
expect(unquoteString("'hello world'")).toEqual('hello world');
});

it('returns unquoted strings', () => {
expect(unquoteString('hello world')).toEqual('hello world');
expect(unquoteString('hello')).toEqual('hello');
expect(unquoteString('hello"world')).toEqual('hello"world');
expect(unquoteString("hello'world")).toEqual("hello'world");
expect(unquoteString("'hello'world")).toEqual("'hello'world");
expect(unquoteString('"hello"world')).toEqual('"hello"world');
});
});
16 changes: 0 additions & 16 deletions x-pack/legacy/plugins/canvas/common/lib/get_field_type.js

This file was deleted.

24 changes: 24 additions & 0 deletions x-pack/legacy/plugins/canvas/common/lib/get_field_type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { DatatableColumn } from '../../canvas_plugin_src/functions/types';
import { unquoteString } from './unquote_string';

/**
* Get the type for the column with the given name
*
* @argument columns Array of all columns
* @field Name of the column that we are looking for the type of
* @returns The column type or the string 'null'
*/
export function getFieldType(columns: DatatableColumn[], field?: string): string {
if (!field) {
return 'null';
}
const realField = unquoteString(field);
const column = columns.find(dataTableColumn => dataTableColumn.name === realField);
return column ? column.type : 'null';
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
// A cheap regex to distinguish an HTTP URL string from a data URL string
const httpurlRegex = /^https?:\/\/\S+(?:[0-9]+)?\/\S{1,}/;

export function isValidHttpUrl(str) {
export function isValidHttpUrl(str: string): boolean {
return httpurlRegex.test(str);
}
4 changes: 0 additions & 4 deletions x-pack/legacy/plugins/canvas/common/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export * from './errors';
export * from './expression_form_handlers';
// @ts-ignore missing local definition
export * from './fetch';
// @ts-ignore missing local definition
export * from './find_in_object';
export * from './fonts';
// @ts-ignore missing local definition
export * from './get_colors_from_palette';
Expand All @@ -31,8 +29,6 @@ export * from './hex_to_rgb';
// @ts-ignore missing local definition
export * from './httpurl';
// @ts-ignore missing local definition
export * from './latest_change';
// @ts-ignore missing local definition
export * from './missing_asset';
// @ts-ignore missing local definition
export * from './palettes';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@

import { map, zipObject } from 'lodash';

const isString = val => typeof val === 'string';
const isString = (val: any): boolean => typeof val === 'string';

export function pivotObjectArray(rows, columns) {
export function pivotObjectArray<
RowType extends { [key: string]: any },
ReturnColumns extends string = keyof RowType
>(
rows: RowType[],
columns?: string[]
): { [Column in ReturnColumns]: Column extends keyof RowType ? Array<RowType[Column]> : never } {
const columnNames = columns || Object.keys(rows[0]);
if (!columnNames.every(isString)) {
throw new Error('Columns should be an array of strings');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

export const unquoteString = str => {
/**
* Removes single or double quotes if any exist around the given string
* @param str the string to unquote
* @returns the unquoted string
*/
export const unquoteString = (str: string): string => {
if (/^"/.test(str)) {
return str.replace(/^"(.+(?="$))"$/, '$1');
}
Expand Down

0 comments on commit f7c0982

Please sign in to comment.