private JavaScriptDimFilter newJavaScriptDimFilter( final String dimension, final String function, final ExtractionFn extractionFn ) { return new JavaScriptDimFilter( dimension, function, extractionFn, JavaScriptConfig.getEnabledInstance() ); } }
@Test public void testCompute() { JavaScriptPostAggregator javaScriptPostAggregator; Map<String, Object> metricValues = new HashMap<>(); metricValues.put("delta", -10.0); metricValues.put("total", 100.0); String absPercentFunction = "function(delta, total) { return 100 * Math.abs(delta) / total; }"; javaScriptPostAggregator = new JavaScriptPostAggregator( "absPercent", Lists.newArrayList("delta", "total"), absPercentFunction, JavaScriptConfig.getEnabledInstance() ); Assert.assertEquals(10.0, javaScriptPostAggregator.compute(metricValues)); }
@Test public void testEquals() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter2 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter3 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter, javaScriptDimFilter2); Assert.assertEquals(javaScriptDimFilter2, javaScriptDimFilter3); RegexDimExtractionFn regexFn = new RegexDimExtractionFn(".*", false, null); JavaScriptDimFilter javaScriptDimFilter4 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter5 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter, javaScriptDimFilter3); Assert.assertEquals(javaScriptDimFilter4, javaScriptDimFilter5); }
@Test public void testGetCacheKey() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter2 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); Assert.assertFalse(Arrays.equals(javaScriptDimFilter.getCacheKey(), javaScriptDimFilter2.getCacheKey())); RegexDimExtractionFn regexFn = new RegexDimExtractionFn(".*", false, null); JavaScriptDimFilter javaScriptDimFilter3 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); Assert.assertFalse(Arrays.equals(javaScriptDimFilter.getCacheKey(), javaScriptDimFilter3.getCacheKey())); }
@Test public void testJavascriptSubstring() { String function = "function(str) { return str.substring(0,3); }"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); for (String str : testStrings) { String res = extractionFn.apply(str); Assert.assertEquals(str.substring(0, 3), res); } }
@Test public void testCastingAndNull() { String function = "function(x) {\n x = Number(x);\n if (isNaN(x)) return null;\n return Math.floor(x / 5) * 5;\n}"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); Iterator<String> it = Iterators.forArray("0", "5", "5", "10", null); for (String str : Lists.newArrayList("1", "5", "6", "10", "CA")) { String res = extractionFn.apply(str); String expected = it.next(); Assert.assertEquals(expected, res); } }
@Test public void testToFilter() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter( "dim", "function(x) { return true; }", null, JavaScriptConfig.getEnabledInstance() ); final Filter filter = javaScriptDimFilter.toFilter(); Assert.assertThat(filter, CoreMatchers.instanceOf(JavaScriptFilter.class)); }
@Test public void testInjective() { Assert.assertEquals(ExtractionFn.ExtractionType.MANY_TO_ONE, new JavaScriptExtractionFn("function(str) { return str; }", false, JavaScriptConfig.getEnabledInstance()).getExtractionType()); Assert.assertEquals(ExtractionFn.ExtractionType.ONE_TO_ONE, new JavaScriptExtractionFn("function(str) { return str; }", true, JavaScriptConfig.getEnabledInstance()).getExtractionType()); } }
@Test public void testTimeExample() { String utcHour = "function(t) {\nreturn 'Second ' + Math.floor((t % 60000) / 1000);\n}"; final long millis = DateTimes.of("2015-01-02T13:00:59.999Z").getMillis(); Assert.assertEquals("Second 59", new JavaScriptExtractionFn(utcHour, false, JavaScriptConfig.getEnabledInstance()).apply(millis)); }
@Test public void testJavascriptRegex() { String function = "function(str) { return str.replace(/[aeiou]/g, ''); }"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); Iterator it = Iterators.forArray("Qt", "Clgry", "Tky", "Stckhlm", "Vncvr", "Prtr", "Wllngtn", "Ontr"); for (String str : testStrings) { String res = extractionFn.apply(str); Assert.assertEquals(it.next(), res); } }
@Test public void testLongs() { String typeOf = "function(x) {\nreturn typeof x\n}"; Assert.assertEquals("number", new JavaScriptExtractionFn(typeOf, false, JavaScriptConfig.getEnabledInstance()).apply(1234L)); }
@Test public void testFloats() { String typeOf = "function(x) {\nreturn typeof x\n}"; Assert.assertEquals("number", new JavaScriptExtractionFn(typeOf, false, JavaScriptConfig.getEnabledInstance()).apply(1234.0)); }
@Test public void testHashcode() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter2 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter3 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter.hashCode(), javaScriptDimFilter2.hashCode()); Assert.assertEquals(javaScriptDimFilter2.hashCode(), javaScriptDimFilter3.hashCode()); RegexDimExtractionFn regexFn = new RegexDimExtractionFn(".*", false, null); JavaScriptDimFilter javaScriptDimFilter4 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter5 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter.hashCode(), javaScriptDimFilter3.hashCode()); Assert.assertEquals(javaScriptDimFilter4.hashCode(), javaScriptDimFilter5.hashCode()); }
@Test public void testSerde() throws Exception { ObjectMapper mapper = new DefaultObjectMapper(); mapper.setInjectableValues( new InjectableValues.Std().addValue( JavaScriptConfig.class, JavaScriptConfig.getEnabledInstance() ) ); Assert.assertEquals( STRATEGY, mapper.readValue( mapper.writeValueAsString(STRATEGY), WorkerSelectStrategy.class ) ); }
@Test public void testSerde() throws Exception { ObjectMapper mapper = new DefaultObjectMapper(); mapper.setInjectableValues( new InjectableValues.Std().addValue( JavaScriptConfig.class, JavaScriptConfig.getEnabledInstance() ) ); Assert.assertEquals( STRATEGY, mapper.readValue( mapper.writeValueAsString(STRATEGY), JavaScriptTieredBrokerSelectorStrategy.class ) ); }
@Test public void testSerde() throws Exception { final ObjectMapper objectMapper = new DefaultObjectMapper(); objectMapper.setInjectableValues( new InjectableValues.Std().addValue( JavaScriptConfig.class, JavaScriptConfig.getEnabledInstance() ) ); final String json = "{ \"type\" : \"javascript\", \"function\" : \"function(str) { return str.substring(0,3); }\" }"; JavaScriptExtractionFn extractionFn = (JavaScriptExtractionFn) objectMapper.readValue(json, ExtractionFn.class); Assert.assertEquals("function(str) { return str.substring(0,3); }", extractionFn.getFunction()); // round trip Assert.assertEquals( extractionFn, objectMapper.readValue( objectMapper.writeValueAsBytes(extractionFn), ExtractionFn.class ) ); }
@Test public void testMakeParser() { final JavaScriptConfig config = JavaScriptConfig.getEnabledInstance(); JavaScriptParseSpec spec = new JavaScriptParseSpec( new TimestampSpec("abc", "iso", null), new DimensionsSpec(DimensionsSpec.getDefaultSchemas(Collections.singletonList("abc")), null, null), "function(str) { var parts = str.split(\"-\"); return { one: parts[0], two: parts[1] } }", config ); final Parser<String, Object> parser = spec.makeParser(); final Map<String, Object> obj = parser.parseToMap("x-y"); Assert.assertEquals(ImmutableMap.of("one", "x", "two", "y"), obj); }
@Test public void testRegexWithExtractionFn() { String nullJsFn = "function(str) { if (str === null) { return 'NOT_NULL_ANYMORE'; } else { return str;} }"; ExtractionFn changeNullFn = new JavaScriptExtractionFn(nullJsFn, false, JavaScriptConfig.getEnabledInstance()); if (NullHandling.replaceWithDefault()) { assertFilterMatches(new RegexDimFilter("dim1", ".*ANYMORE", changeNullFn), ImmutableList.of("0")); assertFilterMatches(new RegexDimFilter("dim2", ".*ANYMORE", changeNullFn), ImmutableList.of("1", "2", "5")); } else { assertFilterMatches(new RegexDimFilter("dim1", ".*ANYMORE", changeNullFn), ImmutableList.of()); assertFilterMatches(new RegexDimFilter("dim2", ".*ANYMORE", changeNullFn), ImmutableList.of("1", "5")); } assertFilterMatches(new RegexDimFilter("dim1", "ab.*", changeNullFn), ImmutableList.of("4", "5")); assertFilterMatches(new RegexDimFilter("dim2", "a.*", changeNullFn), ImmutableList.of("0", "3")); assertFilterMatches(new RegexDimFilter("dim3", ".*ANYMORE", changeNullFn), ImmutableList.of("0", "1", "2", "3", "4", "5")); assertFilterMatches(new RegexDimFilter("dim3", "a.*", changeNullFn), ImmutableList.of()); assertFilterMatches(new RegexDimFilter("dim4", ".*ANYMORE", changeNullFn), ImmutableList.of("0", "1", "2", "3", "4", "5")); assertFilterMatches(new RegexDimFilter("dim4", "a.*", changeNullFn), ImmutableList.of()); } }
@Test public void testSearchOnLongColumnWithExFn() { String jsFn = "function(str) { return 'super-' + str; }"; ExtractionFn jsExtractionFn = new JavaScriptExtractionFn(jsFn, false, JavaScriptConfig.getEnabledInstance()); SearchQuery searchQuery = Druids.newSearchQueryBuilder() .dimensions( new ExtractionDimensionSpec( ColumnHolder.TIME_COLUMN_NAME, ColumnHolder.TIME_COLUMN_NAME, jsExtractionFn ) ) .dataSource(QueryRunnerTestHelper.dataSource) .granularity(QueryRunnerTestHelper.allGran) .intervals(QueryRunnerTestHelper.fullOnIntervalSpec) .query("1297123200000") .build(); List<SearchHit> expectedHits = new ArrayList<>(); expectedHits.add(new SearchHit(ColumnHolder.TIME_COLUMN_NAME, "super-1297123200000", 13)); checkSearchQuery(searchQuery, expectedHits); }
@Test public void testJavascriptIsNull() { String function = "function(x) { if (x == null) { return 'yes'; } else { return 'no' } }"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); Assert.assertEquals("yes", extractionFn.apply((String) null)); Assert.assertEquals("yes", extractionFn.apply((Object) null)); if (NullHandling.replaceWithDefault()) { Assert.assertEquals("yes", extractionFn.apply("")); } else { Assert.assertEquals("no", extractionFn.apply("")); } Assert.assertEquals("no", extractionFn.apply("abc")); Assert.assertEquals("no", extractionFn.apply(new Object())); Assert.assertEquals("no", extractionFn.apply(1)); }