From 945b6caa130ec9a4d9f28f95dfb30f15eb659ee7 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 26 Feb 2018 11:56:54 -0800 Subject: [PATCH] Clean up EuiSearchBar docs and reorganize code. - Rename AST to Ast and astToES to astToEs to maintain consistent naming convention. - Fix enzyme imports. - Move Query to services. - Publish Ast and Query services. - Change random.oneOf to accept an array. --- CHANGELOG.md | 9 +- src-docs/src/views/search_bar/search_bar.js | 339 ++++++++++-------- .../views/search_bar/search_bar_example.js | 2 +- .../table_of_records/column_data_types.js | 2 +- .../views/table_of_records/full_featured.js | 8 +- .../implicit_record_action.js | 8 +- src-docs/src/views/tables/data_store.js | 8 +- .../collapsed_item_actions.test.js | 2 +- .../basic_table/custom_item_action.test.js | 2 +- .../basic_table/default_item_action.test.js | 4 +- .../basic_table/expanded_item_actions.test.js | 2 +- src/components/basic_table/in_memory_table.js | 5 +- .../basic_table/pagination_bar.test.js | 2 +- src/components/index.js | 2 +- .../__snapshots__/search_bar.test.js.snap | 2 +- .../__snapshots__/search_filters.test.js.snap | 4 +- .../filters/field_value_selection_filter.js | 2 +- .../field_value_selection_filter.test.js | 4 +- .../filters/field_value_toggle_filter.js | 2 +- .../filters/field_value_toggle_filter.test.js | 4 +- .../field_value_toggle_group_filter.js | 2 +- .../field_value_toggle_group_filter.test.js | 4 +- .../search_bar/filters/is_filter.js | 2 +- .../search_bar/filters/is_filter.test.js | 4 +- src/components/search_bar/index.js | 1 - .../search_bar/query/ast_to_es.test.js | 69 ---- src/components/search_bar/search_bar.js | 9 +- src/components/search_bar/search_bar.test.js | 2 +- src/components/search_bar/search_box.js | 7 +- src/components/search_bar/search_box.test.js | 2 +- src/components/search_bar/search_filters.js | 7 +- .../search_bar/search_filters.test.js | 4 +- .../collapsed_record_actions.test.js | 2 +- .../custom_record_action.test.js | 2 +- .../default_record_action.test.js | 4 +- .../expanded_record_actions.test.js | 2 +- .../table_of_records/pagination_bar.test.js | 2 +- src/services/index.js | 12 +- .../__snapshots__/ast_to_es.test.js.snap | 14 +- .../search_bar => services}/query/ast.js | 31 +- .../query/ast_to_es.js | 12 +- src/services/query/ast_to_es.test.js | 67 ++++ .../query/default_syntax.js | 30 +- .../query/default_syntax.test.js | 146 ++++---- .../query/execute_ast.js | 12 +- .../query/execute_ast.test.js | 102 +++--- .../search_bar => services}/query/index.js | 2 +- .../search_bar => services}/query/must.js | 2 +- .../search_bar => services}/query/must_not.js | 2 +- .../search_bar => services}/query/query.js | 22 +- src/services/random.js | 4 +- 51 files changed, 527 insertions(+), 469 deletions(-) delete mode 100644 src/components/search_bar/query/ast_to_es.test.js rename src/{components/search_bar => services}/query/__snapshots__/ast_to_es.test.js.snap (89%) rename src/{components/search_bar => services}/query/ast.js (93%) rename src/{components/search_bar => services}/query/ast_to_es.js (93%) create mode 100644 src/services/query/ast_to_es.test.js rename src/{components/search_bar => services}/query/default_syntax.js (75%) rename src/{components/search_bar => services}/query/default_syntax.test.js (73%) rename src/{components/search_bar => services}/query/execute_ast.js (92%) rename src/{components/search_bar => services}/query/execute_ast.test.js (72%) rename src/{components/search_bar => services}/query/index.js (53%) rename src/{components/search_bar => services}/query/must.js (95%) rename src/{components/search_bar => services}/query/must_not.js (95%) rename src/{components/search_bar => services}/query/query.js (92%) diff --git a/CHANGELOG.md b/CHANGELOG.md index abe7c6006be..f88795f490f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `0.0.24`. +- Added `Ast` and `Query` services ([#454](https://github.com/elastic/eui/pull/454)) + +**Breaking changes** + +- The `Random` service's `oneOf` method now only accepts an array ([#454](https://github.com/elastic/eui/pull/454)) # [`0.0.24`](https://github.com/elastic/eui/tree/v0.0.24) @@ -12,8 +16,7 @@ No public interface changes since `0.0.24`. # [`0.0.23`](https://github.com/elastic/eui/tree/v0.0.23) -- Added `EuiInMemoryTable`, which encapsulates sorting, searching, selection, and pagination state -and logic ([#390](https://github.com/elastic/eui/pull/390)) +- Added `EuiInMemoryTable`, which encapsulates sorting, searching, selection, and pagination state and logic ([#390](https://github.com/elastic/eui/pull/390)) - Added stack trace information to `EuiErrorBoundary` ([#428](https://github.com/elastic/eui/pull/428)) **Bug fixes** diff --git a/src-docs/src/views/search_bar/search_bar.js b/src-docs/src/views/search_bar/search_bar.js index 5598c3e583c..4f7a7f83ebf 100644 --- a/src-docs/src/views/search_bar/search_bar.js +++ b/src-docs/src/views/search_bar/search_bar.js @@ -1,72 +1,89 @@ -import React, { Fragment } from 'react'; -import { Random } from '../../../../src/services/random'; +import React, { Component, Fragment } from 'react'; + import { + EuiHealth, + EuiCallOut, + EuiSpacer, + EuiFlexGroup, + EuiFlexItem, + EuiCodeBlock, + EuiIcon, + EuiTitle, + EuiSwitch, + EuiBasicTable, EuiSearchBar, - Query -} from '../../../../src/components/search_bar'; -import { EuiHealth } from '../../../../src/components/health'; -import { EuiCallOut } from '../../../../src/components/call_out'; -import { EuiSpacer } from '../../../../src/components/spacer/spacer'; -import { EuiFlexGroup } from '../../../../src/components/flex/flex_group'; -import { EuiFlexItem } from '../../../../src/components/flex/flex_item'; -import { EuiCodeBlock } from '../../../../src/components/code'; +} from '../../../../src/components'; + +import { + Query, + Random, +} from '../../../../src/services'; + import { times } from 'lodash'; -import { EuiIcon } from '../../../../src/components/icon/icon'; -import { EuiTitle } from '../../../../src/components/title'; -import { EuiSwitch } from '../../../../src/components/form/switch/switch'; -import { EuiBasicTable } from '../../../../src/components/basic_table'; const random = new Random(); -const tags = [ - { value: 'marketing', view: (marketing) }, - { value: 'finance', view: (finance) }, - { value: 'eng', view: (eng) }, - { value: 'sales', view: (sales) }, - { value: 'ga', view: (ga) } -]; +const tags = [{ + name: 'marketing', status: 'off', +}, { + name: 'finance', status: 'on', +}, { + name: 'eng', status: 'on', +}, { + name: 'sales', status: 'processing', +}, { + name: 'ga', status: 'on', +}]; const types = [ - { value: 'dashboard', view: (
Dashboard
) }, - { value: 'visualization', view: (
Visualization
) }, - { value: 'watch', view: (
Watch
) } + 'dashboard', + 'visualization', + 'watch', ]; const users = [ - { value: 'dewey', name: 'Dewey Caldwell', view: (
Dewey Caldwell
) }, - { value: 'wanda', name: 'Wanda Potter', view: (
Wanda Potter
) }, - { value: 'carrie', name: 'Carrie Hamilton', view: (
Carrie Hamilton
) }, - { value: 'jmack', name: 'Joann Mack', view: (
Joann Mack
) }, - { value: 'gabic', name: 'Gabriel Curtis', view: (
Gabriel Curtis
) }, + 'dewey', + 'wanda', + 'carrie', + 'jmack', + 'gabic', ]; const items = times(10, (id) => { return { id, - status: random.oneOf('open', 'closed'), - type: random.oneOf(...types.map(type => type.value)), - tag: random.setOf(tags.map(tag => tag.value), { min: 0, max: 3 }), + status: random.oneOf(['open', 'closed']), + type: random.oneOf(types), + tag: random.setOf(tags.map(tag => tag.name), { min: 0, max: 3 }), active: random.boolean(), - owner: random.oneOf(...users.map(user => user.value)) + owner: random.oneOf(users) }; }); const loadTags = () => { + const statusToColorMap = { + 'on': 'success', + 'off': 'danger', + 'processing': 'warning', + }; + return new Promise((resolve) => { setTimeout(() => { - resolve(tags); - }, random.number({ min: 0, max: 2000 })); + resolve(tags.map(tag => ({ + value: tag.name, + view: {tag.name} + }))); + }, 2000); }); }; const initialQuery = Query.MATCH_ALL; -export class SearchBar extends React.Component { - +export class SearchBar extends Component { constructor(props) { super(props); this.state = { - esQuery: Query.toESQuery(initialQuery), + query: initialQuery, result: items, error: null, incremental: false @@ -80,8 +97,7 @@ export class SearchBar extends React.Component { onChange = (query) => { this.setState({ error: null, - result: Query.execute(query, items, { defaultFields: ['owner', 'tag', 'type'] }), - esQuery: Query.toESQuery(query) + query, }); }; @@ -89,116 +105,157 @@ export class SearchBar extends React.Component { this.setState(prevState => ({ incremental: !prevState.incremental })); }; + renderSearch() { + const { + incremental, + } = this.state; + + const filters = [{ + type: 'field_value_toggle_group', + field: 'status', + items: [{ + value: 'open', + name: 'Open' + }, { + value: 'closed', + name: 'Closed' + }] + }, { + type: 'is', + field: 'active', + name: 'Active', + negatedName: 'Inactive' + }, { + type: 'field_value_toggle', + name: 'Mine', + field: 'owner', + value: 'dewey' + }, { + type: 'field_value_selection', + field: 'tag', + name: 'Tag', + multiSelect: 'or', + cache: 10000, // will cache the loaded tags for 10 sec + options: () => loadTags() + }]; + + return ( + + ); + } + + renderError() { + const { + error, + } = this.state; + + if (!error) { + return; + } + + return ( + + + + + ); + } + + renderTable() { + const columns = [{ + name: 'Type', + field: 'type' + }, { + name: 'Open', + field: 'status', + render: (status) => status === 'open' ? 'Yes' : 'No' + }, { + name: 'Active', + field: 'active', + dataType: 'boolean' + }, { + name: 'Tags', + field: 'tag' + }, { + name: 'Owner', + field: 'owner', + }]; + + const queriedItems = Query.execute(this.state.query, items, { + defaultFields: ['owner', 'tag', 'type'] + }); + + return ( + + ); + } + render() { + const { + incremental, + error, + query, + } = this.state; + + const esQuery = Query.toESQuery(query); + return ( -
- - - loadTags() - } - ]} - onChange={this.onChange} - onParse={this.onParse} - /> - - - - - - - -
- + {this.renderError()} + + + + {this.renderSearch()} + + + + + + + + + -

Elasticsearch Query

- + +

Elasticsearch query

+
+ + + - {this.state.esQuery ? JSON.stringify(this.state.esQuery, null, 2) : ''} + {esQuery ? JSON.stringify(esQuery, null, 2) : ''}
+ -

JS Execution

- - status === 'open' ? 'Yes' : 'No' - }, - { - name: 'Active', - field: 'active', - dataType: 'boolean' - }, - { - name: 'Tags', - field: 'tag' - }, - { - name: 'Owner', - field: 'owner', - render: (username) => { - const user = users.find(user => user.value === username); - return user.name; - } - } - ]} - /> + +

JS execution

+
+ + + + {this.renderTable()}
diff --git a/src-docs/src/views/search_bar/search_bar_example.js b/src-docs/src/views/search_bar/search_bar_example.js index 93d2d2a0ef9..f0cb013c3f2 100644 --- a/src-docs/src/views/search_bar/search_bar_example.js +++ b/src-docs/src/views/search_bar/search_bar_example.js @@ -57,7 +57,7 @@ export const SearchBarExample = {

- While the user can us the syntax described above to enter queries in the search box, it is possible + While the user can use the syntax described above to enter queries in the search box, it is possible provide the user help with the syntax using filters. The filters are UI controls that can manipulate the query. The available filters are:

diff --git a/src-docs/src/views/table_of_records/column_data_types.js b/src-docs/src/views/table_of_records/column_data_types.js index f42e79bde14..7a4ae897779 100644 --- a/src-docs/src/views/table_of_records/column_data_types.js +++ b/src-docs/src/views/table_of_records/column_data_types.js @@ -14,7 +14,7 @@ const random = new Random(); const records = times(5, (index) => { return { id: index, - string: random.oneOf('Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan'), + string: random.oneOf(['Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan']), number: random.integer({ min: 0, max: 2000000 }), boolean: random.boolean(), date: random.date({ min: new Date(1971, 0, 0), max: new Date(1990, 0, 0) }) diff --git a/src-docs/src/views/table_of_records/full_featured.js b/src-docs/src/views/table_of_records/full_featured.js index 0083cd329fc..f9830daa9e2 100644 --- a/src-docs/src/views/table_of_records/full_featured.js +++ b/src-docs/src/views/table_of_records/full_featured.js @@ -26,11 +26,11 @@ const random = new Random(); const people = times(20, (index) => { return { id: index, - firstName: random.oneOf('Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan'), - lastName: random.oneOf('van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel'), - nickname: random.oneOf('martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'whack'), + firstName: random.oneOf(['Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan']), + lastName: random.oneOf(['van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel']), + nickname: random.oneOf(['martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'whack']), dateOfBirth: random.date({ min: new Date(1971, 0, 0), max: new Date(1990, 0, 0) }), - country: random.oneOf('us', 'nl', 'cz', 'za', 'au'), + country: random.oneOf(['us', 'nl', 'cz', 'za', 'au']), online: random.boolean() }; }); diff --git a/src-docs/src/views/table_of_records/implicit_record_action.js b/src-docs/src/views/table_of_records/implicit_record_action.js index 6ef27a99035..77d7056a29a 100644 --- a/src-docs/src/views/table_of_records/implicit_record_action.js +++ b/src-docs/src/views/table_of_records/implicit_record_action.js @@ -19,11 +19,11 @@ const random = new Random(); const people = times(20, (index) => { return { id: index, - firstName: random.oneOf('Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan'), - lastName: random.oneOf('van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel'), - nickname: random.oneOf('martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'whack'), + firstName: random.oneOf(['Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan']), + lastName: random.oneOf(['van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel']), + nickname: random.oneOf(['martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'whack']), dateOfBirth: random.date({ min: new Date(1971, 0, 0), max: new Date(1990, 0, 0) }), - country: random.oneOf('us', 'nl', 'cz', 'za', 'au'), + country: random.oneOf(['us', 'nl', 'cz', 'za', 'au']), online: random.boolean() }; }); diff --git a/src-docs/src/views/tables/data_store.js b/src-docs/src/views/tables/data_store.js index 8dfdcfc6903..c324b549cb5 100644 --- a/src-docs/src/views/tables/data_store.js +++ b/src-docs/src/views/tables/data_store.js @@ -35,11 +35,11 @@ const createUsers = (countries) => { return times(20, (index) => { return { id: index, - firstName: random.oneOf('Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan'), - lastName: random.oneOf('van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel'), - github: random.oneOf('martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'jordansissel'), + firstName: random.oneOf(['Martijn', 'Elissa', 'Clinton', 'Igor', 'Karl', 'Drew', 'Honza', 'Rashid', 'Jordan']), + lastName: random.oneOf(['van Groningen', 'Weve', 'Gormley', 'Motov', 'Minarik', 'Raines', 'Král', 'Khan', 'Sissel']), + github: random.oneOf(['martijnvg', 'elissaw', 'clintongormley', 'imotov', 'karmi', 'drewr', 'HonzaKral', 'rashidkpc', 'jordansissel']), dateOfBirth: random.date({ min: new Date(1971, 0, 0), max: new Date(1990, 0, 0) }), - nationality: random.oneOf(...countries.map(country => country.code)), + nationality: random.oneOf(countries.map(country => country.code)), online: random.boolean() }; }); diff --git a/src/components/basic_table/collapsed_item_actions.test.js b/src/components/basic_table/collapsed_item_actions.test.js index d90e82d64e1..f83fadfbe1f 100644 --- a/src/components/basic_table/collapsed_item_actions.test.js +++ b/src/components/basic_table/collapsed_item_actions.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { CollapsedItemActions } from './collapsed_item_actions'; describe('CollapsedItemActions', () => { diff --git a/src/components/basic_table/custom_item_action.test.js b/src/components/basic_table/custom_item_action.test.js index 3bfa026bec6..63a4708a0d7 100644 --- a/src/components/basic_table/custom_item_action.test.js +++ b/src/components/basic_table/custom_item_action.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { CustomItemAction } from './custom_item_action'; describe('CustomItemAction', () => { diff --git a/src/components/basic_table/default_item_action.test.js b/src/components/basic_table/default_item_action.test.js index 47950bb5638..59caeb22ab3 100644 --- a/src/components/basic_table/default_item_action.test.js +++ b/src/components/basic_table/default_item_action.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { DefaultItemAction } from './default_item_action'; import { Random } from '../../services/random'; @@ -13,7 +13,7 @@ describe('DefaultItemAction', () => { action: { name: 'action1', description: 'action 1', - type: random.oneOf(undefined, 'button', 'foobar'), + type: random.oneOf([undefined, 'button', 'foobar']), onClick: () => {} }, enabled: true, diff --git a/src/components/basic_table/expanded_item_actions.test.js b/src/components/basic_table/expanded_item_actions.test.js index ebc154bd79f..19d54b76aad 100644 --- a/src/components/basic_table/expanded_item_actions.test.js +++ b/src/components/basic_table/expanded_item_actions.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { ExpandedItemActions } from './expanded_item_actions'; describe('ExpandedItemActions', () => { diff --git a/src/components/basic_table/in_memory_table.js b/src/components/basic_table/in_memory_table.js index 3ba3455e53a..c8f840dad1c 100644 --- a/src/components/basic_table/in_memory_table.js +++ b/src/components/basic_table/in_memory_table.js @@ -8,13 +8,14 @@ import { import { defaults as paginationBarDefaults } from './pagination_bar'; +import { Query } from '../../services/query'; import { isBoolean, isString } from '../../services/predicate'; import { Comparators } from '../../services/sort'; import { - Query, QueryType, SearchFiltersFiltersType, - SearchBoxConfigPropTypes, EuiSearchBar + SearchBoxConfigPropTypes, + EuiSearchBar, } from '../search_bar'; import { EuiSpacer } from '../spacer/spacer'; diff --git a/src/components/basic_table/pagination_bar.test.js b/src/components/basic_table/pagination_bar.test.js index 688ed411eaa..58d2da80f4f 100644 --- a/src/components/basic_table/pagination_bar.test.js +++ b/src/components/basic_table/pagination_bar.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { requiredProps } from '../../test'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { PaginationBar } from './pagination_bar'; describe('PaginationBar', () => { diff --git a/src/components/index.js b/src/components/index.js index b99f97ab8a3..e072c7e0bce 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -209,7 +209,7 @@ export { } from './progress'; export { - EuiSearchBar + EuiSearchBar, } from './search_bar'; export { diff --git a/src/components/search_bar/__snapshots__/search_bar.test.js.snap b/src/components/search_bar/__snapshots__/search_bar.test.js.snap index 99c45e8b419..19825888375 100644 --- a/src/components/search_bar/__snapshots__/search_bar.test.js.snap +++ b/src/components/search_bar/__snapshots__/search_bar.test.js.snap @@ -92,7 +92,7 @@ exports[`SearchBar render - provided query, filters 1`] = ` onChange={[Function]} query={ Query { - "ast": _AST { + "ast": _Ast { "_clauses": Array [ Object { "match": "must", diff --git a/src/components/search_bar/__snapshots__/search_filters.test.js.snap b/src/components/search_bar/__snapshots__/search_filters.test.js.snap index 269c295f2e7..8c072425f5d 100644 --- a/src/components/search_bar/__snapshots__/search_filters.test.js.snap +++ b/src/components/search_bar/__snapshots__/search_filters.test.js.snap @@ -24,7 +24,7 @@ exports[`EuiSearchFilters render - with filters 1`] = ` onChange={[Function]} query={ Query { - "ast": _AST { + "ast": _Ast { "_clauses": Array [], "_indexedClauses": Object { "field": Object {}, @@ -62,7 +62,7 @@ exports[`EuiSearchFilters render - with filters 1`] = ` onChange={[Function]} query={ Query { - "ast": _AST { + "ast": _Ast { "_clauses": Array [], "_indexedClauses": Object { "field": Object {}, diff --git a/src/components/search_bar/filters/field_value_selection_filter.js b/src/components/search_bar/filters/field_value_selection_filter.js index cc149f22a68..ded96fe7bae 100644 --- a/src/components/search_bar/filters/field_value_selection_filter.js +++ b/src/components/search_bar/filters/field_value_selection_filter.js @@ -10,7 +10,7 @@ import { EuiFilterSelectItem, EuiFilterButton } from '../../filter_group'; import { EuiLoadingChart } from '../../loading/loading_chart'; import { EuiSpacer } from '../../spacer/spacer'; import { EuiIcon } from '../../icon/icon'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; const FieldValueOptionType = PropTypes.shape({ value: PropTypes.any.isRequired, diff --git a/src/components/search_bar/filters/field_value_selection_filter.test.js b/src/components/search_bar/filters/field_value_selection_filter.test.js index ef88afc2ea2..fd659e635ef 100644 --- a/src/components/search_bar/filters/field_value_selection_filter.test.js +++ b/src/components/search_bar/filters/field_value_selection_filter.test.js @@ -1,8 +1,8 @@ import React from 'react'; +import { shallow } from 'enzyme'; import { requiredProps } from '../../../test'; -import { shallow } from 'enzyme/build/index'; import { FieldValueSelectionFilter } from './field_value_selection_filter'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; describe('FieldValueSelectionFilter', () => { diff --git a/src/components/search_bar/filters/field_value_toggle_filter.js b/src/components/search_bar/filters/field_value_toggle_filter.js index 92e3405c451..7c9b1fd7cb7 100644 --- a/src/components/search_bar/filters/field_value_toggle_filter.js +++ b/src/components/search_bar/filters/field_value_toggle_filter.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { EuiFilterButton } from '../../filter_group'; import { isNil } from '../../../services/predicate'; import { EuiPropTypes } from '../../../utils/prop_types'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; export const FieldValueToggleFilterConfigType = PropTypes.shape({ type: EuiPropTypes.is('field_value_toggle').isRequired, diff --git a/src/components/search_bar/filters/field_value_toggle_filter.test.js b/src/components/search_bar/filters/field_value_toggle_filter.test.js index 10a84a3a995..ad90e02dde4 100644 --- a/src/components/search_bar/filters/field_value_toggle_filter.test.js +++ b/src/components/search_bar/filters/field_value_toggle_filter.test.js @@ -1,7 +1,7 @@ import React from 'react'; +import { shallow } from 'enzyme'; import { requiredProps } from '../../../test'; -import { shallow } from 'enzyme/build/index'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; import { FieldValueToggleFilter } from './field_value_toggle_filter'; describe('FieldValueToggleFilter', () => { diff --git a/src/components/search_bar/filters/field_value_toggle_group_filter.js b/src/components/search_bar/filters/field_value_toggle_group_filter.js index b4b31ce8d5f..350670ca28b 100644 --- a/src/components/search_bar/filters/field_value_toggle_group_filter.js +++ b/src/components/search_bar/filters/field_value_toggle_group_filter.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { EuiFilterButton } from '../../filter_group'; import { EuiPropTypes } from '../../../utils/prop_types'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; export const FieldValueToggleGroupFilterItemType = PropTypes.shape({ value: PropTypes.string.isRequired, diff --git a/src/components/search_bar/filters/field_value_toggle_group_filter.test.js b/src/components/search_bar/filters/field_value_toggle_group_filter.test.js index 586a772b186..f7fb294403a 100644 --- a/src/components/search_bar/filters/field_value_toggle_group_filter.test.js +++ b/src/components/search_bar/filters/field_value_toggle_group_filter.test.js @@ -1,7 +1,7 @@ import React from 'react'; +import { shallow } from 'enzyme'; import { requiredProps } from '../../../test'; -import { shallow } from 'enzyme/build/index'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; import { FieldValueToggleGroupFilter } from './field_value_toggle_group_filter'; describe('TermToggleGroupFilter', () => { diff --git a/src/components/search_bar/filters/is_filter.js b/src/components/search_bar/filters/is_filter.js index 4d040f36810..ce1e54ea97c 100644 --- a/src/components/search_bar/filters/is_filter.js +++ b/src/components/search_bar/filters/is_filter.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { EuiFilterButton } from '../../filter_group'; import { isNil } from '../../../services/predicate'; import { EuiPropTypes } from '../../../utils/prop_types'; -import { Query } from '../query'; +import { Query } from '../../../services/query'; export const IsFilterConfigType = PropTypes.shape({ type: EuiPropTypes.is('is').isRequired, diff --git a/src/components/search_bar/filters/is_filter.test.js b/src/components/search_bar/filters/is_filter.test.js index 94db9f5df92..891bc0e2265 100644 --- a/src/components/search_bar/filters/is_filter.test.js +++ b/src/components/search_bar/filters/is_filter.test.js @@ -1,8 +1,8 @@ import React from 'react'; +import { shallow } from 'enzyme'; import { requiredProps } from '../../../test'; -import { shallow } from 'enzyme/build/index'; +import { Query } from '../../../services/query'; import { IsFilter } from './is_filter'; -import { Query } from '../query'; describe('IsFilter', () => { diff --git a/src/components/search_bar/index.js b/src/components/search_bar/index.js index 89174986313..a203e6fc36f 100644 --- a/src/components/search_bar/index.js +++ b/src/components/search_bar/index.js @@ -1,5 +1,4 @@ export { EuiSearchBar } from './search_bar'; -export { Query } from './query'; export { QueryType } from './search_bar'; export { SearchBoxConfigPropTypes } from './search_box'; export { SearchFiltersFiltersType } from './search_filters'; diff --git a/src/components/search_bar/query/ast_to_es.test.js b/src/components/search_bar/query/ast_to_es.test.js deleted file mode 100644 index fde2aea9c8e..00000000000 --- a/src/components/search_bar/query/ast_to_es.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import { astToES } from './ast_to_es'; -import { AST } from './ast'; - -describe('astToES', () => { - - test(`ast - ''`, () => { - const query = astToES(AST.create([])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - 'john -sales'`, () => { - const query = astToES(AST.create([ - AST.Term.must('john'), - AST.Term.mustNot('sales'), - ])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - '-group:es group:kibana -group:beats group:logstash'`, () => { - const query = astToES(AST.create([ - AST.Field.mustNot('group', 'es'), - AST.Field.must('group', 'kibana'), - AST.Field.mustNot('group', 'beats'), - AST.Field.must('group', 'logstash') - ])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - 'is:online group:kibana john'`, () => { - const query = astToES(AST.create([ - AST.Is.must('online'), - AST.Field.must('group', 'kibana'), - AST.Term.must('john') - ])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - 'john -doe is:online group:eng group:es -group:kibana -is:active'`, () => { - const query = astToES(AST.create([ - AST.Term.must('john'), - AST.Term.mustNot('doe'), - AST.Is.must('online'), - AST.Field.must('group', 'eng'), - AST.Field.must('group', 'es'), - AST.Field.mustNot('group', 'kibana'), - AST.Is.mustNot('active') - ])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - 'john group:(eng or es) -group:kibana'`, () => { - const query = astToES(AST.create([ - AST.Term.must('john'), - AST.Field.must('group', ['eng', 'es']), - AST.Field.mustNot('group', 'kibana') - ])); - expect(query).toMatchSnapshot(); - }); - - test(`ast - 'john group:(eng or "marketing org") -group:"kibana team"`, () => { - const query = astToES(AST.create([ - AST.Term.must('john'), - AST.Field.must('group', ['eng', 'marketing org']), - AST.Field.mustNot('group', 'kibana team') - ])); - expect(query).toMatchSnapshot(); - }); - -}); diff --git a/src/components/search_bar/search_bar.js b/src/components/search_bar/search_bar.js index 4bcd9266656..24f29684d61 100644 --- a/src/components/search_bar/search_bar.js +++ b/src/components/search_bar/search_bar.js @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { isString } from '../../services/predicate'; import { EuiFlexGroup } from '../flex/flex_group'; import { @@ -9,8 +10,7 @@ import { EuiSearchFilters, SearchFiltersFiltersType } from './search_filters'; -import PropTypes from 'prop-types'; -import { Query } from './query'; +import { Query } from '../../services/query'; import { EuiFlexItem } from '../flex/flex_item'; export const QueryType = PropTypes.oneOfType([ PropTypes.instanceOf(Query), PropTypes.string ]); @@ -57,8 +57,7 @@ const resolveQuery = (query) => { return isString(query) ? Query.parse(query) : query; }; -export class EuiSearchBar extends React.Component { - +export class EuiSearchBar extends Component { static propTypes = SearchBoxConfigPropTypes; constructor(props) { diff --git a/src/components/search_bar/search_bar.test.js b/src/components/search_bar/search_bar.test.js index 2827f0a42da..0726f52c896 100644 --- a/src/components/search_bar/search_bar.test.js +++ b/src/components/search_bar/search_bar.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { requiredProps } from '../../test'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { EuiSearchBar } from './search_bar'; describe('SearchBar', () => { diff --git a/src/components/search_bar/search_box.js b/src/components/search_bar/search_box.js index 4793255435e..0e39fe2399d 100644 --- a/src/components/search_bar/search_box.js +++ b/src/components/search_bar/search_box.js @@ -1,14 +1,13 @@ -import React from 'react'; -import { EuiFieldSearch } from '../form/field_search/field_search'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import { EuiFieldSearch } from '../form/field_search/field_search'; export const SearchBoxConfigPropTypes = { placeholder: PropTypes.string, incremental: PropTypes.bool }; -export class EuiSearchBox extends React.Component { - +export class EuiSearchBox extends Component { static propTypes = { query: PropTypes.string.isRequired, onSearch: PropTypes.func.isRequired, // (queryText) => void diff --git a/src/components/search_bar/search_box.test.js b/src/components/search_bar/search_box.test.js index fca73f1fb99..a4999198153 100644 --- a/src/components/search_bar/search_box.test.js +++ b/src/components/search_bar/search_box.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { requiredProps } from '../../test'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { EuiSearchBox } from './search_box'; describe('EuiSearchBox', () => { diff --git a/src/components/search_bar/search_filters.js b/src/components/search_bar/search_filters.js index c104cac40aa..91984c51ddf 100644 --- a/src/components/search_bar/search_filters.js +++ b/src/components/search_bar/search_filters.js @@ -1,13 +1,12 @@ -import React from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { createFilter, FilterConfigType } from './filters'; -import { Query } from './query'; +import { Query } from '../../services/query'; import { EuiFilterGroup } from '../../components/filter_group'; export const SearchFiltersFiltersType = PropTypes.arrayOf(FilterConfigType); -export class EuiSearchFilters extends React.Component { - +export class EuiSearchFilters extends Component { static propTypes = { query: PropTypes.instanceOf(Query).isRequired, onChange: PropTypes.func.isRequired, diff --git a/src/components/search_bar/search_filters.test.js b/src/components/search_bar/search_filters.test.js index b3aa186346a..5ce46061082 100644 --- a/src/components/search_bar/search_filters.test.js +++ b/src/components/search_bar/search_filters.test.js @@ -1,8 +1,8 @@ import React from 'react'; import { requiredProps } from '../../test'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { EuiSearchFilters } from './search_filters'; -import { Query } from './query'; +import { Query } from '../../services/query'; describe('EuiSearchFilters', () => { diff --git a/src/components/table_of_records/collapsed_record_actions.test.js b/src/components/table_of_records/collapsed_record_actions.test.js index db36e1da597..5d424cb536b 100644 --- a/src/components/table_of_records/collapsed_record_actions.test.js +++ b/src/components/table_of_records/collapsed_record_actions.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { CollapsedRecordActions } from './collapsed_record_actions'; describe('CollapsedRecordActions', () => { diff --git a/src/components/table_of_records/custom_record_action.test.js b/src/components/table_of_records/custom_record_action.test.js index 4e2da17f5f6..bf64729cc6c 100644 --- a/src/components/table_of_records/custom_record_action.test.js +++ b/src/components/table_of_records/custom_record_action.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { CustomRecordAction } from './custom_record_action'; describe('CustomRecordAction', () => { diff --git a/src/components/table_of_records/default_record_action.test.js b/src/components/table_of_records/default_record_action.test.js index 58a100b7f3f..ec625d643dd 100644 --- a/src/components/table_of_records/default_record_action.test.js +++ b/src/components/table_of_records/default_record_action.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { DefaultRecordAction } from './default_record_action'; import { Random } from '../../services/random'; @@ -13,7 +13,7 @@ describe('DefaultRecordAction', () => { action: { name: 'action1', description: 'action 1', - type: random.oneOf(undefined, 'button', 'foobar'), + type: random.oneOf([undefined, 'button', 'foobar']), onClick: () => {} }, enabled: true, diff --git a/src/components/table_of_records/expanded_record_actions.test.js b/src/components/table_of_records/expanded_record_actions.test.js index c4a337b43d7..d3e6af9a653 100644 --- a/src/components/table_of_records/expanded_record_actions.test.js +++ b/src/components/table_of_records/expanded_record_actions.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { ExpandedRecordActions } from './expanded_record_actions'; describe('ExpandedRecordActions', () => { diff --git a/src/components/table_of_records/pagination_bar.test.js b/src/components/table_of_records/pagination_bar.test.js index bdf6021f5a9..004d00587cf 100644 --- a/src/components/table_of_records/pagination_bar.test.js +++ b/src/components/table_of_records/pagination_bar.test.js @@ -1,6 +1,6 @@ import React from 'react'; import { requiredProps } from '../../test'; -import { shallow } from 'enzyme/build/index'; +import { shallow } from 'enzyme'; import { PaginationBar } from './pagination_bar'; describe('PaginationBar', () => { diff --git a/src/services/index.js b/src/services/index.js index 9a6b0e6f734..f95bee4f9ea 100644 --- a/src/services/index.js +++ b/src/services/index.js @@ -36,6 +36,15 @@ export { checkHrefAndOnClick, } from './prop_types'; +export { + Ast, + Query, +} from './query'; + +export { + Random +} from './random'; + export { getSecureRelForTarget, } from './security'; @@ -52,6 +61,3 @@ export { noOverflowPlacement, } from './overflow'; -export { - Random -} from './random'; diff --git a/src/components/search_bar/query/__snapshots__/ast_to_es.test.js.snap b/src/services/query/__snapshots__/ast_to_es.test.js.snap similarity index 89% rename from src/components/search_bar/query/__snapshots__/ast_to_es.test.js.snap rename to src/services/query/__snapshots__/ast_to_es.test.js.snap index 5dbc177361f..71f38298994 100644 --- a/src/components/search_bar/query/__snapshots__/ast_to_es.test.js.snap +++ b/src/services/query/__snapshots__/ast_to_es.test.js.snap @@ -1,12 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`astToES ast - '' 1`] = ` +exports[`astToEs ast - '' 1`] = ` Object { "match_all": Object {}, } `; -exports[`astToES ast - '-group:es group:kibana -group:beats group:logstash' 1`] = ` +exports[`astToEs ast - '-group:es group:kibana -group:beats group:logstash' 1`] = ` Object { "bool": Object { "must": Array [ @@ -33,7 +33,7 @@ Object { } `; -exports[`astToES ast - 'is:online group:kibana john' 1`] = ` +exports[`astToEs ast - 'is:online group:kibana john' 1`] = ` Object { "bool": Object { "must": Array [ @@ -60,7 +60,7 @@ Object { } `; -exports[`astToES ast - 'john -doe is:online group:eng group:es -group:kibana -is:active' 1`] = ` +exports[`astToEs ast - 'john -doe is:online group:eng group:es -group:kibana -is:active' 1`] = ` Object { "bool": Object { "must": Array [ @@ -107,7 +107,7 @@ Object { } `; -exports[`astToES ast - 'john -sales' 1`] = ` +exports[`astToEs ast - 'john -sales' 1`] = ` Object { "bool": Object { "must": Array [ @@ -128,7 +128,7 @@ Object { } `; -exports[`astToES ast - 'john group:(eng or "marketing org") -group:"kibana team" 1`] = ` +exports[`astToEs ast - 'john group:(eng or "marketing org") -group:"kibana team" 1`] = ` Object { "bool": Object { "must": Array [ @@ -168,7 +168,7 @@ Object { } `; -exports[`astToES ast - 'john group:(eng or es) -group:kibana' 1`] = ` +exports[`astToEs ast - 'john group:(eng or es) -group:kibana' 1`] = ` Object { "bool": Object { "must": Array [ diff --git a/src/components/search_bar/query/ast.js b/src/services/query/ast.js similarity index 93% rename from src/components/search_bar/query/ast.js rename to src/services/query/ast.js index 89fbe1d5248..15bc356a04f 100644 --- a/src/components/search_bar/query/ast.js +++ b/src/services/query/ast.js @@ -1,4 +1,4 @@ -import { isArray, isNil } from '../../../services/predicate'; +import { isArray, isNil } from '../predicate'; export const Match = Object.freeze({ MUST: 'must', @@ -68,10 +68,9 @@ const Is = Object.freeze({ * * This AST is immutable - every "mutating" operation returns a newly mutated AST. */ -export class _AST { - +export class _Ast { static create(clauses) { - return new _AST(clauses); + return new _Ast(clauses); } constructor(clauses = []) { @@ -142,7 +141,7 @@ export class _AST { const existingClause = this.getOrFieldClause(field); if (!existingClause) { const newClause = must ? Field.must(field, [ value ]) : Field.mustNot(field, [ value ]); - return new _AST([ ...this._clauses, newClause ]); + return new _Ast([ ...this._clauses, newClause ]); } const clauses = this._clauses.map(clause => { if (clause === existingClause) { @@ -150,13 +149,13 @@ export class _AST { } return clause; }); - return new _AST(clauses); + return new _Ast(clauses); } removeOrFieldValue(field, value) { const existingClause = this.getOrFieldClause(field, value); if (!existingClause) { - return new _AST([ ...this._clauses ]); + return new _Ast([ ...this._clauses ]); } const clauses = this._clauses.reduce((clauses, clause) => { if (clause !== existingClause) { @@ -170,14 +169,14 @@ export class _AST { clauses.push({ ...clause, value: filteredValue }); return clauses; }, []); - return new _AST(clauses); + return new _Ast(clauses); } removeOrFieldClauses(field) { const clauses = this._clauses.filter(clause => { return !Field.isInstance(clause) || clause.field !== field || !isArray(clause.value); }); - return new _AST(clauses); + return new _Ast(clauses); } hasSimpleFieldClause(field, value = undefined) { @@ -200,17 +199,17 @@ export class _AST { removeSimpleFieldValue(field, value) { const existingClause = this.getSimpleFieldClause(field, value); if (!existingClause) { - return new _AST([ ...this._clauses ]); + return new _Ast([ ...this._clauses ]); } const clauses = this._clauses.filter(clause => clause !== existingClause); - return new _AST(clauses); + return new _Ast(clauses); } removeSimpleFieldClauses(field) { const clauses = this._clauses.filter(clause => { return !Field.isInstance(clause) || clause.field !== field || isArray(clause.value); }); - return new _AST(clauses); + return new _Ast(clauses); } getIsClauses() { @@ -222,7 +221,7 @@ export class _AST { } removeIsClause(flag) { - return new _AST(this._clauses.filter(clause => !Is.isInstance(clause) || clause.flag !== flag)); + return new _Ast(this._clauses.filter(clause => !Is.isInstance(clause) || clause.flag !== flag)); } /** @@ -280,14 +279,14 @@ export class _AST { if (!added) { newClauses.push(newClause); } - return new _AST(newClauses); + return new _Ast(newClauses); } } -export const AST = Object.freeze({ +export const Ast = Object.freeze({ Match, Term, Field, Is, - create: (clauses) => new _AST(clauses) + create: (clauses) => new _Ast(clauses) }); diff --git a/src/components/search_bar/query/ast_to_es.js b/src/services/query/ast_to_es.js similarity index 93% rename from src/components/search_bar/query/ast_to_es.js rename to src/services/query/ast_to_es.js index 354e13e761d..9fcb263db0d 100644 --- a/src/components/search_bar/query/ast_to_es.js +++ b/src/services/query/ast_to_es.js @@ -1,5 +1,5 @@ -import { AST } from './ast'; -import { isArray } from '../../../services/predicate'; +import { Ast } from './ast'; +import { isArray } from '../predicate'; export const _termValuesToQuery = (values, options) => { const body = { @@ -74,7 +74,7 @@ export const _isFlagToQuery = (flag, on) => { const collectTerms = (ast) => { return ast.getTermClauses().reduce((values, clause) => { - if (AST.Match.isMustClause(clause)) { + if (Ast.Match.isMustClause(clause)) { values.must.push(clause.value); } else { values.mustNot.push(clause.value); @@ -93,7 +93,7 @@ const collectFields = (ast) => { }; return ast.getFieldClauses().reduce((fields, clause) => { - if (AST.Match.isMustClause(clause)) { + if (Ast.Match.isMustClause(clause)) { if (isArray(clause.value)) { fieldArray(fields.must.or, clause.field).push(...clause.value); } else { @@ -113,7 +113,7 @@ const collectFields = (ast) => { }); }; -export const astToES = (ast, options = {}) => { +export const astToEs = (ast, options = {}) => { if (ast.clauses.length === 0) { return { match_all: {} }; @@ -141,7 +141,7 @@ export const astToES = (ast, options = {}) => { return fieldValuesToQuery(field, fields.must.or[field], 'or'); })); must.push(...ast.getIsClauses().map(clause => { - return isFlagToQuery(clause.flag, AST.Match.isMustClause(clause)); + return isFlagToQuery(clause.flag, Ast.Match.isMustClause(clause)); })); const mustNot = []; diff --git a/src/services/query/ast_to_es.test.js b/src/services/query/ast_to_es.test.js new file mode 100644 index 00000000000..61c4f3a8995 --- /dev/null +++ b/src/services/query/ast_to_es.test.js @@ -0,0 +1,67 @@ +import { astToEs } from './ast_to_es'; +import { Ast } from './ast'; + +describe('astToEs', () => { + test(`ast - ''`, () => { + const query = astToEs(Ast.create([])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - 'john -sales'`, () => { + const query = astToEs(Ast.create([ + Ast.Term.must('john'), + Ast.Term.mustNot('sales'), + ])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - '-group:es group:kibana -group:beats group:logstash'`, () => { + const query = astToEs(Ast.create([ + Ast.Field.mustNot('group', 'es'), + Ast.Field.must('group', 'kibana'), + Ast.Field.mustNot('group', 'beats'), + Ast.Field.must('group', 'logstash') + ])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - 'is:online group:kibana john'`, () => { + const query = astToEs(Ast.create([ + Ast.Is.must('online'), + Ast.Field.must('group', 'kibana'), + Ast.Term.must('john') + ])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - 'john -doe is:online group:eng group:es -group:kibana -is:active'`, () => { + const query = astToEs(Ast.create([ + Ast.Term.must('john'), + Ast.Term.mustNot('doe'), + Ast.Is.must('online'), + Ast.Field.must('group', 'eng'), + Ast.Field.must('group', 'es'), + Ast.Field.mustNot('group', 'kibana'), + Ast.Is.mustNot('active') + ])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - 'john group:(eng or es) -group:kibana'`, () => { + const query = astToEs(Ast.create([ + Ast.Term.must('john'), + Ast.Field.must('group', ['eng', 'es']), + Ast.Field.mustNot('group', 'kibana') + ])); + expect(query).toMatchSnapshot(); + }); + + test(`ast - 'john group:(eng or "marketing org") -group:"kibana team"`, () => { + const query = astToEs(Ast.create([ + Ast.Term.must('john'), + Ast.Field.must('group', ['eng', 'marketing org']), + Ast.Field.mustNot('group', 'kibana team') + ])); + expect(query).toMatchSnapshot(); + }); +}); diff --git a/src/components/search_bar/query/default_syntax.js b/src/services/query/default_syntax.js similarity index 75% rename from src/components/search_bar/query/default_syntax.js rename to src/services/query/default_syntax.js index b66d84fc374..482906fb47e 100644 --- a/src/components/search_bar/query/default_syntax.js +++ b/src/services/query/default_syntax.js @@ -1,5 +1,5 @@ -import { AST } from './ast'; -import { isArray } from '../../../services/predicate'; +import { Ast } from './ast'; +import { isArray } from '../predicate'; import peg from 'pegjs-inline-precompile'; // eslint-disable-line import/no-unresolved const unescapeValue = (value) => { @@ -12,7 +12,7 @@ const escapeValue = (value) => { const parser = peg` { - const { AST, unescapeValue } = options; + const { Ast, unescapeValue } = options; } Query @@ -32,19 +32,19 @@ Clause / TermClause TermClause - = space? "-" value:termValue { return AST.Term.mustNot(value); } - / space? value:termValue { return AST.Term.must(value); } + = space? "-" value:termValue { return Ast.Term.mustNot(value); } + / space? value:termValue { return Ast.Term.must(value); } IsClause - = space? "-" value:IsValue { return AST.Is.mustNot(value); } - / space? value:IsValue { return AST.Is.must(value); } + = space? "-" value:IsValue { return Ast.Is.mustNot(value); } + / space? value:IsValue { return Ast.Is.must(value); } IsValue = "is:" value:value { return value; } FieldClause - = space? "-" fv:FieldAndValue { return AST.Field.mustNot(fv.field, fv.value); } - / space? fv:FieldAndValue { return AST.Field.must(fv.field, fv.value); } + = space? "-" fv:FieldAndValue { return Ast.Field.mustNot(fv.field, fv.value); } + / space? fv:FieldAndValue { return Ast.Field.must(fv.field, fv.value); } FieldAndValue = field:fieldName ":" value:fieldValue { return {field, value}; } @@ -105,22 +105,22 @@ const printValue = (value) => { export const defaultSyntax = Object.freeze({ parse: (query) => { - const clauses = parser.parse(query, { AST, unescapeValue }); - return AST.create(clauses); + const clauses = parser.parse(query, { Ast, unescapeValue }); + return Ast.create(clauses); }, print: (ast) => { return ast.clauses.reduce((text, clause) => { - const prefix = AST.Match.isMustClause(clause) ? '' : '-'; + const prefix = Ast.Match.isMustClause(clause) ? '' : '-'; switch (clause.type) { - case AST.Field.TYPE: + case Ast.Field.TYPE: if (isArray(clause.value)) { return `${text} ${prefix}${escapeValue(clause.field)}:(${clause.value.map(val => printValue(val)).join(' or ')})`; } return `${text} ${prefix}${escapeValue(clause.field)}:${printValue(clause.value)}`; - case AST.Is.TYPE: + case Ast.Is.TYPE: return `${text} ${prefix}is:${escapeValue(clause.flag)}`; - case AST.Term.TYPE: + case Ast.Term.TYPE: return `${text} ${prefix}${printValue(clause.value)}`; default: return text; diff --git a/src/components/search_bar/query/default_syntax.test.js b/src/services/query/default_syntax.test.js similarity index 73% rename from src/components/search_bar/query/default_syntax.test.js rename to src/services/query/default_syntax.test.js index c0c0a1f3537..e018a52cc55 100644 --- a/src/components/search_bar/query/default_syntax.test.js +++ b/src/services/query/default_syntax.test.js @@ -1,5 +1,5 @@ import { defaultSyntax } from './default_syntax'; -import { AST } from './ast'; +import { Ast } from './ast'; describe('defaultSyntax', () => { @@ -25,20 +25,20 @@ describe('defaultSyntax', () => { let clause = ast.getTermClause('-'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('-'); clause = ast.getTermClause(':'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.value).toBe(':'); clause = ast.getTermClause('\\'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('\\'); const printedQuery = defaultSyntax.print(ast); @@ -55,8 +55,8 @@ describe('defaultSyntax', () => { const clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); @@ -74,8 +74,8 @@ describe('defaultSyntax', () => { const clause = ast.getSimpleFieldClause('n:ame', 'jo:hn'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('n:ame'); expect(clause.value).toBe('jo:hn'); @@ -93,15 +93,15 @@ describe('defaultSyntax', () => { let clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); clause = ast.getSimpleFieldClause('age', '6'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('6'); @@ -119,22 +119,22 @@ describe('defaultSyntax', () => { let clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); clause = ast.getSimpleFieldClause('age', '6'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('6'); clause = ast.getSimpleFieldClause('age', '5'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('5'); @@ -152,22 +152,22 @@ describe('defaultSyntax', () => { let clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); clause = ast.getSimpleFieldClause('age', '6'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('6'); clause = ast.getSimpleFieldClause('age', '5'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.field).toBe('age'); expect(clause.value).toBe('5'); @@ -185,14 +185,14 @@ describe('defaultSyntax', () => { let clause = ast.getTermClause('foo'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('foo'); clause = ast.getTermClause('bar'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('bar'); const printedQuery = defaultSyntax.print(ast); @@ -209,14 +209,14 @@ describe('defaultSyntax', () => { let clause = ast.getTermClause('foo'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('foo'); clause = ast.getTermClause('bar'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.value).toBe('bar'); const printedQuery = defaultSyntax.print(ast); @@ -233,34 +233,34 @@ describe('defaultSyntax', () => { let clause = ast.getTermClause('foo'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('foo'); clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); clause = ast.getTermClause('bar'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.value).toBe('bar'); clause = ast.getSimpleFieldClause('age', '5'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('5'); clause = ast.getSimpleFieldClause('name', 'joe'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('joe'); @@ -278,47 +278,47 @@ describe('defaultSyntax', () => { let clause = ast.getTermClause('foo'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('foo'); clause = ast.getSimpleFieldClause('name', 'john'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.field).toBe('name'); expect(clause.value).toBe('john'); clause = ast.getTermClause('bar'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.value).toBe('bar'); clause = ast.getSimpleFieldClause('age', '5'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('age'); expect(clause.value).toBe('5'); clause = ast.getSimpleFieldClause('name', 'joe'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('name'); expect(clause.value).toBe('joe'); clause = ast.getIsClause('open'); expect(clause).toBeDefined(); - expect(AST.Is.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Is.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.flag).toBe('open'); clause = ast.getIsClause('liberal'); expect(clause).toBeDefined(); - expect(AST.Is.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Is.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.flag).toBe('liberal'); const printedQuery = defaultSyntax.print(ast); @@ -335,8 +335,8 @@ describe('defaultSyntax', () => { const clause = ast.getTermClause('foo bar'); expect(clause).toBeDefined(); - expect(AST.Term.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Term.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.value).toBe('foo bar'); const printedQuery = defaultSyntax.print(ast); @@ -353,8 +353,8 @@ describe('defaultSyntax', () => { const clause = ast.getSimpleFieldClause('field', 'foo bar'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('field'); expect(clause.value).toBe('foo bar'); @@ -372,8 +372,8 @@ describe('defaultSyntax', () => { const clause = ast.getOrFieldClause('field'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('field'); expect(clause.value).toHaveLength(2); expect(clause.value).toContain('foo'); @@ -393,8 +393,8 @@ describe('defaultSyntax', () => { let clause = ast.getOrFieldClause('field1'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('field1'); expect(clause.value).toHaveLength(2); expect(clause.value).toContain('foo'); @@ -402,8 +402,8 @@ describe('defaultSyntax', () => { clause = ast.getSimpleFieldClause('field2'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(false); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(false); expect(clause.field).toBe('field2'); expect(clause.value).toBe('baz'); @@ -421,8 +421,8 @@ describe('defaultSyntax', () => { const clause = ast.getSimpleFieldClause('f'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('f'); expect(clause.value).toBe('this is a relaxed phrase'); @@ -440,8 +440,8 @@ describe('defaultSyntax', () => { const clause = ast.getOrFieldClause('f'); expect(clause).toBeDefined(); - expect(AST.Field.isInstance(clause)).toBe(true); - expect(AST.Match.isMustClause(clause)).toBe(true); + expect(Ast.Field.isInstance(clause)).toBe(true); + expect(Ast.Match.isMustClause(clause)).toBe(true); expect(clause.field).toBe('f'); expect(clause.value).toHaveLength(1); expect(clause.value).toContain('foo'); diff --git a/src/components/search_bar/query/execute_ast.js b/src/services/query/execute_ast.js similarity index 92% rename from src/components/search_bar/query/execute_ast.js rename to src/services/query/execute_ast.js index f825f40c73c..60cbbeae1c0 100644 --- a/src/components/search_bar/query/execute_ast.js +++ b/src/services/query/execute_ast.js @@ -1,20 +1,20 @@ import { get } from 'lodash'; -import { isString, isArray } from '../../../services/predicate'; +import { isString, isArray } from '../predicate'; import { must } from './must'; import { mustNot } from './must_not'; -import { AST } from './ast'; +import { Ast } from './ast'; const EXPLAIN_FIELD = '__explain'; const matchers = { - [AST.Match.MUST]: must, - [AST.Match.MUST_NOT]: mustNot + [Ast.Match.MUST]: must, + [Ast.Match.MUST_NOT]: mustNot }; const defaultIsClauseMatcher = (record, clause, explain) => { const { type, flag, match } = clause; const value = get(record, clause.flag); - const must = AST.Match.isMustClause(clause); + const must = Ast.Match.isMustClause(clause); const hit = !!value === must; if (explain && hit) { explain.push({ hit, type, flag, match }); @@ -57,7 +57,7 @@ const termClauseMatcher = (record, fields, clauses = [], explain) => { if (!matcher) { // unknown matcher return true; } - if (AST.Match.isMustClause(clause)) { + if (Ast.Match.isMustClause(clause)) { return fields.some(field => { const recordValue = get(record, field); const hit = matcher(recordValue, value); diff --git a/src/components/search_bar/query/execute_ast.test.js b/src/services/query/execute_ast.test.js similarity index 72% rename from src/components/search_bar/query/execute_ast.test.js rename to src/services/query/execute_ast.test.js index 3ea911775cb..0541481bef6 100644 --- a/src/components/search_bar/query/execute_ast.test.js +++ b/src/services/query/execute_ast.test.js @@ -1,6 +1,6 @@ -import { AST } from './ast'; +import { Ast } from './ast'; import { executeAst } from './execute_ast'; -import { Random } from '../../../services/random'; +import { Random } from '../random'; const random = new Random(); @@ -11,8 +11,8 @@ describe('execute ast', () => { { name: 'john doe' }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'john') + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'john') ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('john doe'); @@ -23,8 +23,8 @@ describe('execute ast', () => { { name: 'john' }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.mustNot('name', 'john') + const result = executeAst(Ast.create([ + Ast.Field.mustNot('name', 'john') ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('joe'); @@ -35,20 +35,20 @@ describe('execute ast', () => { { name: 'john' }, { name: 'joe' } ]; - let result = executeAst(AST.create([ - AST.Field.must('name', ['john', 'doe']) + let result = executeAst(Ast.create([ + Ast.Field.must('name', ['john', 'doe']) ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('john'); - result = executeAst(AST.create([ - AST.Field.must('name', ['joe', 'doe']) + result = executeAst(Ast.create([ + Ast.Field.must('name', ['joe', 'doe']) ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('joe'); - result = executeAst(AST.create([ - AST.Field.must('name', ['foo', 'bar']) + result = executeAst(Ast.create([ + Ast.Field.must('name', ['foo', 'bar']) ]), items); expect(result).toHaveLength(0); }); @@ -58,8 +58,8 @@ describe('execute ast', () => { { name: 'john' }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'foo') + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'foo') ]), items); expect(result).toHaveLength(0); }); @@ -69,9 +69,9 @@ describe('execute ast', () => { { name: 'john' }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'john'), - AST.Field.must('name', 'joe') + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'john'), + Ast.Field.must('name', 'joe') ]), items); expect(result).toHaveLength(0); }); @@ -81,9 +81,9 @@ describe('execute ast', () => { { name: 'john', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'foo'), - AST.Field.must('age', '7') + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'foo'), + Ast.Field.must('age', '7') ]), items); expect(result).toHaveLength(0); }); @@ -93,9 +93,9 @@ describe('execute ast', () => { { name: 'john', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'john'), - AST.Field.must('age', '5') + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'john'), + Ast.Field.must('age', '5') ]), items); expect(result).toHaveLength(1); }); @@ -105,9 +105,9 @@ describe('execute ast', () => { { name: 'john', description: 'doe', age: 5 }, { name: 'joe' } ]; - const value = random.oneOf('john', 'doe'); - const result = executeAst(AST.create([ - AST.Term.must(value) + const value = random.oneOf(['john', 'doe']); + const result = executeAst(Ast.create([ + Ast.Term.must(value) ]), items); expect(result).toHaveLength(1); }); @@ -119,8 +119,8 @@ describe('execute ast', () => { { name: 'john', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Term.must('5') + const result = executeAst(Ast.create([ + Ast.Term.must('5') ]), items); expect(result).toHaveLength(0); }); @@ -130,8 +130,8 @@ describe('execute ast', () => { { name: 'john', description: 'doe', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Term.must('john') + const result = executeAst(Ast.create([ + Ast.Term.must('john') ]), items, { defaultFields: [ 'name' ] }); expect(result).toHaveLength(1); }); @@ -141,8 +141,8 @@ describe('execute ast', () => { { name: 'john', description: 'doe', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Term.must('doe') + const result = executeAst(Ast.create([ + Ast.Term.must('doe') ]), items, { defaultFields: [ 'name' ] }); expect(result).toHaveLength(0); }); @@ -152,8 +152,8 @@ describe('execute ast', () => { { name: 'john', description: 'doe', age: 5 }, { name: 'joe' } ]; - const result = executeAst(AST.create([ - AST.Term.mustNot('john') + const result = executeAst(Ast.create([ + Ast.Term.mustNot('john') ]), items, { defaultFields: [ 'name' ] }); expect(result).toHaveLength(1); expect(result[0].name).toBe('joe'); @@ -164,8 +164,8 @@ describe('execute ast', () => { { name: 'john', open: true }, { name: 'joe', open: false } ]; - const result = executeAst(AST.create([ - AST.Is.must('open') + const result = executeAst(Ast.create([ + Ast.Is.must('open') ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('john'); @@ -176,8 +176,8 @@ describe('execute ast', () => { { name: 'john', open: true }, { name: 'joe', open: false } ]; - const result = executeAst(AST.create([ - AST.Is.mustNot('open') + const result = executeAst(Ast.create([ + Ast.Is.mustNot('open') ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('joe'); @@ -188,8 +188,8 @@ describe('execute ast', () => { { name: 'john', open: true }, { name: 'joe', open: false } ]; - const result = executeAst(AST.create([ - AST.Is.must('closed') + const result = executeAst(Ast.create([ + Ast.Is.must('closed') ]), items); expect(result).toHaveLength(0); }); @@ -199,8 +199,8 @@ describe('execute ast', () => { { name: 'john', open: true }, { name: 'joe', open: false } ]; - const result = executeAst(AST.create([ - AST.Is.mustNot('closed') + const result = executeAst(Ast.create([ + Ast.Is.mustNot('closed') ]), items); expect(result).toHaveLength(2); }); @@ -212,11 +212,11 @@ describe('execute ast', () => { { text: 'foo bar', age: 7 }, { text: 'bar', age: 7 }, ]; - const result = executeAst(AST.create([ - AST.Is.mustNot('open'), - AST.Field.must('age', '7'), - AST.Term.must('bar'), - AST.Term.mustNot('foo') + const result = executeAst(Ast.create([ + Ast.Is.mustNot('open'), + Ast.Field.must('age', '7'), + Ast.Term.must('bar'), + Ast.Term.mustNot('foo') ]), items); expect(result).toHaveLength(1); expect(result[0].text).toBe('bar'); @@ -230,8 +230,8 @@ describe('execute ast', () => { { text: 'foo bar', age: 7 }, { text: 'bar', age: 7 }, ]; - const result = executeAst(AST.create([ - AST.Field.must('name', 'John Doe'), + const result = executeAst(Ast.create([ + Ast.Field.must('name', 'John Doe'), ]), items); expect(result).toHaveLength(1); expect(result[0].name).toBe('john doe'); @@ -244,8 +244,8 @@ describe('execute ast', () => { { name: 'foo bar', age: 7 }, { name: 'bar', age: 7 }, ]; - const result = executeAst(AST.create([ - AST.Field.must('name', [ 'john', 'bar' ]), + const result = executeAst(Ast.create([ + Ast.Field.must('name', [ 'john', 'bar' ]), ]), items); expect(result).toHaveLength(3); const names = result.map(item => item.name); diff --git a/src/components/search_bar/query/index.js b/src/services/query/index.js similarity index 53% rename from src/components/search_bar/query/index.js rename to src/services/query/index.js index 60e75e781d8..f6ddbd44ea2 100644 --- a/src/components/search_bar/query/index.js +++ b/src/services/query/index.js @@ -1,2 +1,2 @@ export { Query } from './query'; -export { AST } from './ast'; +export { Ast } from './ast'; diff --git a/src/components/search_bar/query/must.js b/src/services/query/must.js similarity index 95% rename from src/components/search_bar/query/must.js rename to src/services/query/must.js index 7c02950cc90..6d0db460a63 100644 --- a/src/components/search_bar/query/must.js +++ b/src/services/query/must.js @@ -1,7 +1,7 @@ import { isArray, isBoolean, isNumber, isString -} from '../../../services/predicate'; +} from '../predicate'; import moment from 'moment/moment'; const defaultOptions = { diff --git a/src/components/search_bar/query/must_not.js b/src/services/query/must_not.js similarity index 95% rename from src/components/search_bar/query/must_not.js rename to src/services/query/must_not.js index eadd7e410b5..1f37ee18a9c 100644 --- a/src/components/search_bar/query/must_not.js +++ b/src/services/query/must_not.js @@ -1,7 +1,7 @@ import { isArray, isBoolean, isNumber, isString -} from '../../../services/predicate'; +} from '../predicate'; import moment from 'moment/moment'; const defaultOptions = { diff --git a/src/components/search_bar/query/query.js b/src/services/query/query.js similarity index 92% rename from src/components/search_bar/query/query.js rename to src/services/query/query.js index 6c358dede70..4da9733b464 100644 --- a/src/components/search_bar/query/query.js +++ b/src/services/query/query.js @@ -1,8 +1,8 @@ import { defaultSyntax } from './default_syntax'; import { executeAst } from './execute_ast'; -import { isNil, isString } from '../../../services/predicate'; -import { astToES } from './ast_to_es'; -import { AST } from './ast'; +import { isNil, isString } from '../predicate'; +import { astToEs } from './ast_to_es'; +import { Ast } from './ast'; /** * This is the consumer interface for the query - it's effectively a wrapper construct around @@ -10,27 +10,26 @@ import { AST } from './ast'; * It is immutable - all mutating operations return a new (mutated) query instance. */ export class Query { - static parse(text, syntax = defaultSyntax) { return new Query(syntax.parse(text), syntax, text); } static isMust(clause) { - return AST.Match.isMustClause(clause); + return Ast.Match.isMustClause(clause); } static MATCH_ALL = Query.parse(''); static isTerm(clause) { - return AST.Term.isInstance(clause); + return Ast.Term.isInstance(clause); } static isIs(clause) { - return AST.Is.isInstance(clause); + return Ast.Is.isInstance(clause); } static isField(clause) { - return AST.Field.isInstance(clause); + return Ast.Field.isInstance(clause); } constructor(ast, syntax = defaultSyntax, text = undefined) { @@ -94,12 +93,12 @@ export class Query { } addMustIsClause(flag) { - const ast = this.ast.addClause(AST.Is.must(flag)); + const ast = this.ast.addClause(Ast.Is.must(flag)); return new Query(ast, this.syntax); } addMustNotIsClause(flag) { - const ast = this.ast.addClause(AST.Is.mustNot(flag)); + const ast = this.ast.addClause(Ast.Is.mustNot(flag)); return new Query(ast, this.syntax); } @@ -163,7 +162,6 @@ export class Query { */ static toESQuery(query, options = {}) { const q = isString(query) ? Query.parse(query) : query; - return astToES(q.ast, options); + return astToEs(q.ast, options); } - } diff --git a/src/services/random.js b/src/services/random.js index 03294e35e35..8e85384a09b 100644 --- a/src/services/random.js +++ b/src/services/random.js @@ -27,7 +27,7 @@ export class Random { return min + delta; } - oneOf(...values) { + oneOf(values) { return values[Math.floor(this._rand() * values.length)]; } @@ -35,7 +35,7 @@ export class Random { const count = this.integer({ min: 0, max: values.length, ...options }); const copy = [...values]; return times(count, () => { - const value = this.oneOf(...copy); + const value = this.oneOf(copy); copy.splice(copy.indexOf(value), 1); return value; });