/* * Copyright 2016 Christoph Böhme * * Licensed under the Apache License, Version 2.0 the "License"; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.culturegraph.mf.metamorph.functions; import static org.mockito.Mockito.inOrder; import org.culturegraph.mf.framework.StreamReceiver; import org.culturegraph.mf.metamorph.InlineMorph; import org.culturegraph.mf.metamorph.Metamorph; import org.junit.Rule; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; /** * Tests for various Metamorph functions. * * @author Markus Geipel (metamorph-test xml) * @author Christoph Böhme (conversion to Java) */ public final class TestVariousFunctions { // TODO: This class need to be split into separate classes for each function! @Rule public final MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private StreamReceiver receiver; private Metamorph metamorph; @Test public void testRegexpFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data' name='island'>") .with(" <regexp match='(\\w*) island' format='${1}' />") .with(" </data>") .with(" <data source='data' name='year'>") .with(" <regexp match='\\d\\d\\d\\d' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "Aloha!"); metamorph.literal("data", "Oahu island, Hawaii island, Maui island"); metamorph.literal("data", "year 1960!"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("island", "Oahu"); ordered.verify(receiver).literal("island", "Hawaii"); ordered.verify(receiver).literal("island", "Maui"); ordered.verify(receiver).literal("year", "1960"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testIsbnFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='isbn' name='withError'>") .with(" <isbn to='isbn13' errorString='error' />") .with(" </data>") .with(" <data source='isbn' name='withoutError'>") .with(" <isbn to='isbn13' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("isbn", "123 invalid"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("withError", "error"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testSplitFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data' name='island'>") .with(" <split delimiter=',' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "Oahu,Hawaii,Maui"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("island", "Oahu"); ordered.verify(receiver).literal("island", "Hawaii"); ordered.verify(receiver).literal("island", "Maui"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testSubstringFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='a'>") .with(" <substring start='3' end='5' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("a", "012345"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("a", "34"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testConstantFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data'>") .with(" <constant value='Hawaii' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "Aloha"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("data", "Hawaii"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testSetReplaceFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data'>") .with(" <setreplace>") .with(" <entry name='dt.' value='deutsch' />") .with(" <entry name='frz.' value='französich' />") .with(" <entry name='eng.' value='englisch' />") .with(" </setreplace>") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "dt., frz. und eng."); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("data", "deutsch, französich und englisch"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testCaseFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data'>") .with(" <case to='upper' />") .with(" </data>") .with(" <data source='data'>") .with(" <case to='lower' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "Aloha"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("data", "ALOHA"); ordered.verify(receiver).literal("data", "aloha"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testEqualsFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data' name='data1'>") .with(" <equals string='Aloha' />") .with(" </data>") .with(" <data source='data' name='data2'>") .with(" <not-equals string='Aloha' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "Aloha"); metamorph.literal("data", "Hawaii"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("data1", "Aloha"); ordered.verify(receiver).literal("data2", "Hawaii"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testBufferFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <combine name='greeting' value='${greet} ${island}' reset='false'>") .with(" <data source='d1' name='greet' />") .with(" <data source='d2' name='island'>") .with(" <buffer />") .with(" </data>") .with(" </combine>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("0"); metamorph.literal("d1", "Aloha"); metamorph.endRecord(); metamorph.startRecord("1"); metamorph.literal("d2", "Hawaii"); metamorph.literal("d2", "Oahu"); metamorph.literal("d1", "Aloha"); metamorph.endRecord(); metamorph.startRecord("2"); metamorph.endRecord(); metamorph.startRecord("3"); metamorph.literal("d1", "Aloha"); metamorph.endRecord(); metamorph.startRecord("4"); metamorph.literal("d2", "to all"); metamorph.literal("d1", "Aloha"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("0"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("greeting", "Aloha Hawaii"); ordered.verify(receiver).literal("greeting", "Aloha Oahu"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("2"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("3"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("4"); ordered.verify(receiver).literal("greeting", "Aloha to all"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testOccurrenceFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data' name='l2'>") .with(" <occurrence only='lessThan 2' />") .with(" </data>") .with(" <data source='data' name='2'>") .with(" <occurrence only='2' />") .with(" </data>") .with(" <data source='data' name='g2'>") .with(" <occurrence only='moreThan 2' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endRecord(); metamorph.startRecord("2"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("2"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testOccurrenceFunctionWithSameEntity() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='e.data' name='l2'>") .with(" <occurrence only='lessThan 2' sameEntity='true' />") .with(" </data>") .with(" <data source='e.data' name='2'>") .with(" <occurrence only='2' sameEntity='true' />") .with(" </data>") .with(" <data source='e.data' name='g2'>") .with(" <occurrence only='moreThan 2' sameEntity='true' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.startEntity("e"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endEntity(); metamorph.startEntity("e"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endEntity(); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testOccurrenceFunctionWithSameEntityInNestedEntitiesShouldChangeWithInnerEntities() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='o.i.data' name='l2'>") .with(" <occurrence only='lessThan 2' sameEntity='true' />") .with(" </data>") .with(" <data source='o.i.data' name='2'>") .with(" <occurrence only='2' sameEntity='true' />") .with(" </data>") .with(" <data source='o.i.data' name='g2'>") .with(" <occurrence only='moreThan 2' sameEntity='true' />") .with(" </data>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.startEntity("o"); metamorph.startEntity("i"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endEntity(); metamorph.startEntity("i"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endEntity(); metamorph.endEntity(); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).literal("l2", "1"); ordered.verify(receiver).literal("2", "2"); ordered.verify(receiver).literal("g2", "3"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testCountFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <data source='data' name='count'>") .with(" <count />") .with(" </data>") .with(" <choose flushWith='record'>") .with(" <data source='datax' name='count'>") .with(" <count />") .with(" </data>") .with(" </choose>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("0"); metamorph.literal("datax", "1"); metamorph.literal("datax", "2"); metamorph.endRecord(); metamorph.startRecord("1"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endRecord(); metamorph.startRecord("2"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.endRecord(); metamorph.startRecord("3"); metamorph.literal("datax", "1"); metamorph.literal("datax", "2"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("0"); ordered.verify(receiver).literal("count", "2"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("count", "1"); ordered.verify(receiver).literal("count", "2"); ordered.verify(receiver).literal("count", "3"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("2"); ordered.verify(receiver).literal("count", "1"); ordered.verify(receiver).literal("count", "2"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("3"); ordered.verify(receiver).literal("count", "2"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } @Test public void testNestedCountFunction() { metamorph = InlineMorph.in(this) .with("<rules>") .with(" <combine name='count' value='${count}' flushWith='record'>") .with(" <data source='data' name='count'>") .with(" <count />") .with(" </data>") .with(" <data source='fantasy' />") .with(" </combine>") .with("</rules>") .createConnectedTo(receiver); metamorph.startRecord("1"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.literal("data", "3"); metamorph.endRecord(); metamorph.startRecord("2"); metamorph.literal("data", "1"); metamorph.literal("data", "2"); metamorph.endRecord(); final InOrder ordered = inOrder(receiver); ordered.verify(receiver).startRecord("1"); ordered.verify(receiver).literal("count", "3"); ordered.verify(receiver).endRecord(); ordered.verify(receiver).startRecord("2"); ordered.verify(receiver).literal("count", "2"); ordered.verify(receiver).endRecord(); ordered.verifyNoMoreInteractions(); } }