From 9f0e0fca5943f4f7df4c5c63221cc206d8c9ca13 Mon Sep 17 00:00:00 2001 From: Julien Maitrehenry Date: Mon, 24 Oct 2022 13:50:03 -0400 Subject: [PATCH 1/4] Add RuntimeField, esb.runtimeField, esb.requestBodySearch().runtimeField() and esb.requestBodySearch().runtimeFields() --- package.json | 1 + src/core/index.js | 2 + src/core/request-body-search.js | 68 +++++++++++++++++++++ src/core/runtime-field.js | 71 ++++++++++++++++++++++ src/index.d.ts | 17 ++++++ src/index.js | 4 ++ test/core-test/request-body-search.test.js | 47 +++++++++++++- test/core-test/runtime-field.test.js | 52 ++++++++++++++++ 8 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 src/core/runtime-field.js create mode 100644 test/core-test/runtime-field.test.js diff --git a/package.json b/package.json index c990dc16..3df0fdd8 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "author": "Suhas Karanth ", "contributors": [ "austin ce ", + "Julien Maitrehenry ", "ochan12 ", "kennylindahl ", "foxstarius ", diff --git a/src/core/index.js b/src/core/index.js index dcf0305c..80013bec 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -31,3 +31,5 @@ exports.SearchTemplate = require('./search-template'); exports.consts = require('./consts'); exports.util = require('./util'); + +exports.RuntimeField = require('./runtime-field'); diff --git a/src/core/request-body-search.js b/src/core/request-body-search.js index c1a90d11..49312bfb 100644 --- a/src/core/request-body-search.js +++ b/src/core/request-body-search.js @@ -406,6 +406,74 @@ class RequestBodySearch { return this; } + /** + * Computes a document property dynamically based on the supplied `script`. + * + * @example + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeField( + * 'sessionId-name', + * esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['name'].value)` + * ) + * ) + * + * @example + * // runtime fields can also be used in query aggregation + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeField( + * 'sessionId-eventName', + * esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['eventName'].value)`, + * ) + * ) + * .agg(esb.cardinalityAggregation('uniqueCount', `sessionId-eventName`)),; + * + * @param {string} runtimeFieldName + * @param {RuntimeField} instance of `RuntimeField` + * @returns {RequestBodySearch} returns `this` so that calls can be chained + */ + runtimeMapping(runtimeMappingName, runtimeField) { + setDefault(this._body, 'runtime_mappings', {}); + this._body.runtime_mappings[runtimeMappingName] = runtimeField; + return this; + } + + /** + * Computes one or more document properties dynamically based on supplied `RuntimeField`s. + * + * @example + * const fieldA = esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['name'].value)`, + * 'sessionId-name' + * ); + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeFields({ + * 'sessionId-name': fieldA, + * }) + * + * @param {Object} runtimeFields Object with `runtimeFieldName` as key and `RuntimeField` instance as the value. + * @returns {RequestBodySearch} returns `this` so that calls can be chained + */ + runtimeMappings(runtimeMappings) { + checkType(runtimeMappings, Object); + + Object.keys(runtimeMappings).forEach(runtimeMappingName => + this.runtimeMapping( + runtimeMappingName, + runtimeMappings[runtimeMappingName] + ) + ); + + return this; + } + /** * Computes a document property dynamically based on the supplied `Script`. * diff --git a/src/core/runtime-field.js b/src/core/runtime-field.js new file mode 100644 index 00000000..a8680243 --- /dev/null +++ b/src/core/runtime-field.js @@ -0,0 +1,71 @@ +'use strict'; + +const isNil = require('lodash.isnil'); +const validType = [ + 'boolean', + 'composite', + 'date', + 'double', + 'geo_point', + 'ip', + 'keyword', + 'long', + 'lookup' +]; + +class RuntimeField { + constructor(type, script, name) { + this._body = {}; + this._name = name; + this._isTypeSet = false; + this._isScriptSet = false; + + if (!isNil(type)) { + this.type(type); + } + + if (!isNil(script)) { + this.script(script); + } + } + + name(name) { + this._name = name; + } + + script(script) { + this._body.script = { + source: script + }; + this._isScriptSet = true; + } + + type(type) { + const typeLower = type.toLowerCase(); + if (!validType.includes(typeLower)) { + throw new Error(`\`type\` must be one of ${validType.join(', ')}`); + } + this._body.type = typeLower; + this._isTypeSet = true; + } + + /** + * Override default `toJSON` to return DSL representation for the `script`. + * + * @override + * @returns {Object} returns an Object which maps to the elasticsearch query DSL + */ + toJSON() { + if (!this._isTypeSet) { + throw new Error('`type` should be set'); + } + + if (!this._isScriptSet) { + throw new Error('`script` should be set'); + } + + return this._body; + } +} + +module.exports = RuntimeField; diff --git a/src/index.d.ts b/src/index.d.ts index db3b6740..837dd5d1 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -167,6 +167,9 @@ declare namespace esb { */ storedFields(fields: object | string): this; + runtimeMapping(runtimeMappingName: string, script: string | RuntimeField): this; + runtimeMappings(runtimeMappings: object): this; + /** * Computes a document property dynamically based on the supplied `Script`. * @@ -8761,6 +8764,20 @@ declare namespace esb { */ export function highlight(fields?: string | string[]): Highlight; + export class RuntimeField { + constructor(type?: string, script?: string, name?: string); + name(name: string); + type(type: 'boolean' | 'composite' | 'date' | 'double' | 'geo_point' | 'ip' | 'keyword' | 'long' | 'lookup'); + script(script: string); + /** + * Override default `toJSON` to return DSL representation for the `script`. + * + * @override + */ + toJSON(): object; + } + export function runtimeField(type?: string, script?: string, name?: string): RuntimeField; + /** * Class supporting the Elasticsearch scripting API. * diff --git a/src/index.js b/src/index.js index 92e27bcf..5c03524d 100644 --- a/src/index.js +++ b/src/index.js @@ -12,6 +12,7 @@ const { Sort, Rescore, InnerHits, + RuntimeField, SearchTemplate, Query, util: { constructorWrapper } @@ -640,6 +641,9 @@ exports.innerHits = constructorWrapper(InnerHits); exports.SearchTemplate = SearchTemplate; exports.searchTemplate = constructorWrapper(SearchTemplate); +exports.RuntimeField = RuntimeField; +exports.runtimeField = constructorWrapper(RuntimeField); + exports.prettyPrint = function prettyPrint(obj) { console.log(JSON.stringify(obj, null, 2)); }; diff --git a/test/core-test/request-body-search.test.js b/test/core-test/request-body-search.test.js index a6567f04..a5bf02e0 100644 --- a/test/core-test/request-body-search.test.js +++ b/test/core-test/request-body-search.test.js @@ -1,3 +1,4 @@ +/* eslint-disable max-lines */ import test from 'ava'; import { RequestBodySearch, @@ -14,7 +15,8 @@ import { Script, Highlight, Rescore, - InnerHits + InnerHits, + RuntimeField } from '../../src'; import { illegalParamType, makeSetsOptionMacro } from '../_macros'; @@ -37,6 +39,17 @@ const suggest = new TermSuggester( const sortChannel = new Sort('channel', 'desc'); const sortCategories = new Sort('categories', 'desc'); +const runtimeFieldA = new RuntimeField( + 'keyword', + "emit(doc['name'].value)", + 'test1' +); +const runtimeFieldB = new RuntimeField( + 'boolean', + "emit(doc['qty'].value > 10)", + 'test2' +); + const scriptA = new Script('inline', "doc['my_field_name'].value * 2").lang( 'painless' ); @@ -131,6 +144,38 @@ test('sets stored_fields(arr) option', setsOption, 'storedFields', { param: ['user', 'postDate'], spread: false }); + +test(setsOption, 'runtimeMapping', { + param: ['test1', runtimeFieldA], + propValue: { + test1: { + type: 'keyword', + script: { + source: "emit(doc['name'].value)" + } + } + }, + keyName: 'runtime_mappings' +}); +test(setsOption, 'runtimeMappings', { + param: { test1: runtimeFieldA, test2: runtimeFieldB }, + propValue: { + test1: { + type: 'keyword', + script: { + source: "emit(doc['name'].value)" + } + }, + test2: { + type: 'boolean', + script: { + source: "emit(doc['qty'].value > 10)" + } + } + }, + keyName: 'runtime_mappings' +}); + test(setsOption, 'scriptField', { param: ['test1', scriptA], propValue: { test1: { script: scriptA } }, diff --git a/test/core-test/runtime-field.test.js b/test/core-test/runtime-field.test.js new file mode 100644 index 00000000..a2a963ce --- /dev/null +++ b/test/core-test/runtime-field.test.js @@ -0,0 +1,52 @@ +import test from 'ava'; +import RuntimeField from '../../src/core/runtime-field'; + +test('constructor set arguments', t => { + const valueA = new RuntimeField( + 'keyword', + "emit(doc['name'].value)" + ).toJSON(); + const valueB = new RuntimeField( + 'keyword', + "emit(doc['name'].value)" + ).toJSON(); + t.deepEqual(valueA, valueB); + + const expected = { + type: 'keyword', + script: { + source: "emit(doc['name'].value)" + } + }; + t.deepEqual(valueA, expected); + + let err = t.throws(() => new RuntimeField().toJSON(), Error); + t.is(err.message, '`type` should be set'); + + err = t.throws(() => new RuntimeField('keyword').toJSON(), Error); + t.is(err.message, '`script` should be set'); +}); + +test('type validate and set argument', t => { + const fieldA = new RuntimeField('keyword', "emit(doc['name'].value)"); + fieldA.type('boolean'); + const expected = { + type: 'boolean', + script: { + source: "emit(doc['name'].value)" + } + }; + t.deepEqual(fieldA.toJSON(), expected); + + const err = t.throws(() => fieldA.type('invalid'), Error); + t.is( + err.message, + '`type` must be one of boolean, composite, date, double, geo_point, ip, keyword, long, lookup' + ); +}); + +test('name set _name', t => { + const fieldA = new RuntimeField(); + fieldA.name('field-name'); + t.deepEqual(fieldA._name, 'field-name'); +}); From 3f3f6fc44a0ae232411f851c92a1273b9154ecb3 Mon Sep 17 00:00:00 2001 From: Aaron Donaldson <56371059+atreids@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:52:12 +0000 Subject: [PATCH 2/4] feat: updated runtime_mapping work - added jsdocs --- .vscode/settings.json | 4 +- src/core/request-body-search.js | 42 +++++--- src/core/runtime-field.js | 32 ++++-- src/index.d.ts | 115 ++++++++++++++++++++- test/core-test/request-body-search.test.js | 9 +- test/core-test/runtime-field.test.js | 6 -- 6 files changed, 170 insertions(+), 38 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 08d3434b..42a6a0bb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,13 @@ // Place your settings in this file to overwrite default and user settings. { "eslint.enable": true, - "eslint.autoFixOnSave": true, "files.eol": "\n", "vsicons.presets.angular": false, "editor.detectIndentation": true, "[json]": { "editor.tabSize": 2 + }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" } } diff --git a/src/core/request-body-search.js b/src/core/request-body-search.js index 49312bfb..e69a3c2d 100644 --- a/src/core/request-body-search.js +++ b/src/core/request-body-search.js @@ -13,6 +13,7 @@ const Query = require('./query'), InnerHits = require('./inner-hits'); const { checkType, setDefault, recursiveToJSON } = require('./util'); +const RuntimeField = require('./runtime-field'); /** * Helper function to call `recursiveToJSON` on elements of array and assign to object. @@ -407,12 +408,17 @@ class RequestBodySearch { } /** - * Computes a document property dynamically based on the supplied `script`. + * Computes a document property dynamically based on the supplied `runtimeField`. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) * * @example * const reqBody = esb.requestBodySearch() * .query(esb.matchAllQuery()) - * .runtimeField( + * .runtimeMapping( * 'sessionId-name', * esb.runtimeField( * 'keyword', @@ -424,7 +430,7 @@ class RequestBodySearch { * // runtime fields can also be used in query aggregation * const reqBody = esb.requestBodySearch() * .query(esb.matchAllQuery()) - * .runtimeField( + * .runtimeMapping( * 'sessionId-eventName', * esb.runtimeField( * 'keyword', @@ -433,41 +439,49 @@ class RequestBodySearch { * ) * .agg(esb.cardinalityAggregation('uniqueCount', `sessionId-eventName`)),; * - * @param {string} runtimeFieldName - * @param {RuntimeField} instance of `RuntimeField` + * @param {string} runtimeFieldName Name for the computed runtime mapping field. + * @param {RuntimeField} runtimeField Instance of RuntimeField + * * @returns {RequestBodySearch} returns `this` so that calls can be chained + * */ - runtimeMapping(runtimeMappingName, runtimeField) { + runtimeMapping(runtimeFieldName, runtimeField) { + checkType(runtimeField, RuntimeField); + setDefault(this._body, 'runtime_mappings', {}); - this._body.runtime_mappings[runtimeMappingName] = runtimeField; + this._body.runtime_mappings[runtimeFieldName] = runtimeField; return this; } /** * Computes one or more document properties dynamically based on supplied `RuntimeField`s. * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * * @example * const fieldA = esb.runtimeField( * 'keyword', - * `emit(doc['session_id'].value + '::' + doc['name'].value)`, - * 'sessionId-name' + * `emit(doc['session_id'].value + '::' + doc['name'].value)` * ); * const reqBody = esb.requestBodySearch() * .query(esb.matchAllQuery()) - * .runtimeFields({ + * .runtimeMappings({ * 'sessionId-name': fieldA, * }) * - * @param {Object} runtimeFields Object with `runtimeFieldName` as key and `RuntimeField` instance as the value. + * @param {Object} runtimeMappings Object with `runtimeFieldName` as key and instance of `RuntimeField` as the value. * @returns {RequestBodySearch} returns `this` so that calls can be chained */ runtimeMappings(runtimeMappings) { checkType(runtimeMappings, Object); - Object.keys(runtimeMappings).forEach(runtimeMappingName => + Object.keys(runtimeMappings).forEach(runtimeFieldName => this.runtimeMapping( - runtimeMappingName, - runtimeMappings[runtimeMappingName] + runtimeFieldName, + runtimeMappings[runtimeFieldName] ) ); diff --git a/src/core/runtime-field.js b/src/core/runtime-field.js index a8680243..5820d0ba 100644 --- a/src/core/runtime-field.js +++ b/src/core/runtime-field.js @@ -13,10 +13,24 @@ const validType = [ 'lookup' ]; +/** + * Class supporting the Elasticsearch runtime field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * + * @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`. + * @param {string=} script Source of the script. + * + * @example + * const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`); + */ class RuntimeField { - constructor(type, script, name) { + // eslint-disable-next-line require-jsdoc + constructor(type, script) { this._body = {}; - this._name = name; this._isTypeSet = false; this._isScriptSet = false; @@ -29,10 +43,11 @@ class RuntimeField { } } - name(name) { - this._name = name; - } - + /** + * Sets the source of the script. + * @param {string} script + * @returns {void} + */ script(script) { this._body.script = { source: script @@ -40,6 +55,11 @@ class RuntimeField { this._isScriptSet = true; } + /** + * Sets the type of the runtime field. + * @param {string} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`. + * @returns {void} + */ type(type) { const typeLower = type.toLowerCase(); if (!validType.includes(typeLower)) { diff --git a/src/index.d.ts b/src/index.d.ts index 837dd5d1..f4cda447 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -167,7 +167,71 @@ declare namespace esb { */ storedFields(fields: object | string): this; - runtimeMapping(runtimeMappingName: string, script: string | RuntimeField): this; + + + /** + * Computes a document property dynamically based on the supplied `runtimeField`. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * + * @example + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeMapping( + * 'sessionId-name', + * esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['name'].value)` + * ) + * ) + * + * @example + * // runtime fields can also be used in query aggregation + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeMapping( + * 'sessionId-eventName', + * esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['eventName'].value)`, + * ) + * ) + * .agg(esb.cardinalityAggregation('uniqueCount', `sessionId-eventName`)),; + * + * @param {string} runtimeFieldName Name for the computed runtime mapping field. + * @param {RuntimeField} runtimeField Instance of RuntimeField + * + * @returns {RequestBodySearch} returns `this` so that calls can be chained + * + */ + runtimeMapping(runtimeFieldName: string, runtimeField: RuntimeField): this; + + + /** + * Computes one or more document properties dynamically based on supplied `RuntimeField`s. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime-search-request.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * + * @example + * const fieldA = esb.runtimeField( + * 'keyword', + * `emit(doc['session_id'].value + '::' + doc['name'].value)` + * ); + * const reqBody = esb.requestBodySearch() + * .query(esb.matchAllQuery()) + * .runtimeMappings({ + * 'sessionId-name': fieldA, + * }) + * + * @param {Object} runtimeMappings Object with `runtimeFieldName` as key and instance of `RuntimeField` as the value. + * @returns {RequestBodySearch} returns `this` so that calls can be chained + */ runtimeMappings(runtimeMappings: object): this; /** @@ -8764,11 +8828,39 @@ declare namespace esb { */ export function highlight(fields?: string | string[]): Highlight; + /** + * Class supporting the Elasticsearch runtime field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * + * @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`. + * @param {string=} script Source of the script. + * + * @example + * const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`); + */ export class RuntimeField { - constructor(type?: string, script?: string, name?: string); - name(name: string); + constructor(type?: string, script?: string); + + /** + * Sets the type of the runtime field. + * + * @param {string} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`. + * @returns {void} + */ type(type: 'boolean' | 'composite' | 'date' | 'double' | 'geo_point' | 'ip' | 'keyword' | 'long' | 'lookup'); + + /** + * Sets the source of the script. + * + * @param {string} script + * @returns {void} + */ script(script: string); + /** * Override default `toJSON` to return DSL representation for the `script`. * @@ -8776,7 +8868,22 @@ declare namespace esb { */ toJSON(): object; } - export function runtimeField(type?: string, script?: string, name?: string): RuntimeField; + + /** + * Class supporting the Elasticsearch runtime field. + * + * [Elasticsearch reference](https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html) + * + * Added in Elasticsearch v7.11.0 + * [Release note](https://www.elastic.co/guide/en/elasticsearch/reference/7.11/release-notes-7.11.0.html) + * + * @param {string=} type One of `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`, `keyword`, `long`, `lookup`. + * @param {string=} script Source of the script. + * + * @example + * const field = esb.runtimeField('keyword', `emit(doc['sessionId'].value + '::' + doc['name'].value)`); + */ + export function runtimeField(type?: 'boolean' | 'composite' | 'date' | 'double' | 'geo_point' | 'ip' | 'keyword' | 'long' | 'lookup', script?: string): RuntimeField; /** * Class supporting the Elasticsearch scripting API. diff --git a/test/core-test/request-body-search.test.js b/test/core-test/request-body-search.test.js index a5bf02e0..47b11910 100644 --- a/test/core-test/request-body-search.test.js +++ b/test/core-test/request-body-search.test.js @@ -39,15 +39,10 @@ const suggest = new TermSuggester( const sortChannel = new Sort('channel', 'desc'); const sortCategories = new Sort('categories', 'desc'); -const runtimeFieldA = new RuntimeField( - 'keyword', - "emit(doc['name'].value)", - 'test1' -); +const runtimeFieldA = new RuntimeField('keyword', "emit(doc['name'].value)"); const runtimeFieldB = new RuntimeField( 'boolean', - "emit(doc['qty'].value > 10)", - 'test2' + "emit(doc['qty'].value > 10)" ); const scriptA = new Script('inline', "doc['my_field_name'].value * 2").lang( diff --git a/test/core-test/runtime-field.test.js b/test/core-test/runtime-field.test.js index a2a963ce..9afe988a 100644 --- a/test/core-test/runtime-field.test.js +++ b/test/core-test/runtime-field.test.js @@ -44,9 +44,3 @@ test('type validate and set argument', t => { '`type` must be one of boolean, composite, date, double, geo_point, ip, keyword, long, lookup' ); }); - -test('name set _name', t => { - const fieldA = new RuntimeField(); - fieldA.name('field-name'); - t.deepEqual(fieldA._name, 'field-name'); -}); From c55d120b44770c1c8ce565adca2ac26b1d4c8fc3 Mon Sep 17 00:00:00 2001 From: Aaron Donaldson <56371059+atreids@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:06:55 +0000 Subject: [PATCH 3/4] chore: remove unnecessary deepequal --- test/core-test/runtime-field.test.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/core-test/runtime-field.test.js b/test/core-test/runtime-field.test.js index 9afe988a..bf9f1509 100644 --- a/test/core-test/runtime-field.test.js +++ b/test/core-test/runtime-field.test.js @@ -6,11 +6,6 @@ test('constructor set arguments', t => { 'keyword', "emit(doc['name'].value)" ).toJSON(); - const valueB = new RuntimeField( - 'keyword', - "emit(doc['name'].value)" - ).toJSON(); - t.deepEqual(valueA, valueB); const expected = { type: 'keyword', From 47f2362d930e6946e68727289301cbb4f9a4d86e Mon Sep 17 00:00:00 2001 From: Aaron Donaldson <56371059+atreids@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:29:15 +0000 Subject: [PATCH 4/4] test: test script method --- test/core-test/runtime-field.test.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/core-test/runtime-field.test.js b/test/core-test/runtime-field.test.js index bf9f1509..4d487bb5 100644 --- a/test/core-test/runtime-field.test.js +++ b/test/core-test/runtime-field.test.js @@ -39,3 +39,15 @@ test('type validate and set argument', t => { '`type` must be one of boolean, composite, date, double, geo_point, ip, keyword, long, lookup' ); }); + +test('script method sets script source', t => { + const fieldA = new RuntimeField('keyword'); + fieldA.script("emit(doc['name'].value)"); + const expected = { + type: 'keyword', + script: { + source: "emit(doc['name'].value)" + } + }; + t.deepEqual(fieldA.toJSON(), expected); +});