diff --git a/SDKTestFramework/README.md b/SDKTestFramework/README.md index 002264e..7614c17 100644 --- a/SDKTestFramework/README.md +++ b/SDKTestFramework/README.md @@ -312,6 +312,7 @@ final TestParserSource source = SDKTestFramework.createTestParserSource( .build()); ``` +The dcsample.sample file should be located into the "resources" folder. For the sample above, the file is located under a "file" sub-directory in the "resources" folder. This essentially replicates the data source uploaded into Data Studio as below: ![parser test data source](readme-images/parser-test-data-source.png) diff --git a/SDKTestFramework/build.gradle b/SDKTestFramework/build.gradle index cda11ab..189b8b3 100644 --- a/SDKTestFramework/build.gradle +++ b/SDKTestFramework/build.gradle @@ -11,10 +11,10 @@ repositories { dependencies { compileOnly( - "com.experian.datastudio:sdkapi:2.1.0", - "com.experian.datastudio:sdklib:2.1.0" + "com.experian.datastudio:sdkapi:2.2.0", + "com.experian.datastudio:sdklib:2.2.0" ) - testImplementation "com.experian.datastudio:sdktestframework:2.1.0" + testImplementation "com.experian.datastudio:sdktestframework:2.2.0" testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' } diff --git a/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParser.java b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParser.java new file mode 100644 index 0000000..76cd214 --- /dev/null +++ b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParser.java @@ -0,0 +1,63 @@ +package com.experian.datastudio.sdk.parser.sample; + +import com.experian.datastudio.sdk.api.CustomTypeMetadata; +import com.experian.datastudio.sdk.api.CustomTypeMetadataBuilder; +import com.experian.datastudio.sdk.api.parser.CustomParserDefinition; +import com.experian.datastudio.sdk.api.parser.configuration.*; + +import java.nio.charset.StandardCharsets; + +public class SampleParser implements CustomParserDefinition { + static final String PARAMETER_KEY_ENCODING = "&encoding"; + static final String PARAMETER_KEY_MAX_ROWS = "&maxRow"; + + @Override + public ParserConfiguration createConfiguration(ParserConfigurationBuilder parserConfigurationBuilder) { + return parserConfigurationBuilder + .withParserId("&sample_parser") + .withSupportedFileExtensions(supportedFileExtensionsBuilder -> supportedFileExtensionsBuilder + .add(supportedFileExtensionBuilder -> supportedFileExtensionBuilder + .withSupportedFileExtension("sample") + .withFileExtensionName("sample name") + .withFileExtensionDescription("sample description") + .build()) + .build()) + .withParserParameterDefinition(parameterDefinitionsBuilder -> parameterDefinitionsBuilder + .add(parameterDefinitionBuilder -> parameterDefinitionBuilder + .withId(PARAMETER_KEY_ENCODING) + .withName("Encoding") + .withDescription("Select encoding") + .setAsRequired(true) + .setTypeAs(ParserParameterValueType.STRING) + .setDisplayTypeAs(ParserParameterDisplayType.CHARSET) + .withDefaultValueAsString(StandardCharsets.UTF_8.name()) + .affectsTableStructure(false) + .build()) + .add(parameterDefinitionBuilder -> parameterDefinitionBuilder + .withId(PARAMETER_KEY_MAX_ROWS) + .withName("Max row") + .withDescription("Maximum row displayed") + .setAsRequired(false) + .setTypeAs(ParserParameterValueType.INTEGER) + .setDisplayTypeAs(ParserParameterDisplayType.TEXTFIELD) + .withDefaultValueAsNumber(10) + .affectsTableStructure(false) + .build()) + .build()) + .withProcessor(new SampleParserProcessor()) + .build(); + } + + @Override + public CustomTypeMetadata createMetadata(CustomTypeMetadataBuilder metadataBuilder) { + return metadataBuilder + .withName("Sample parser") + .withDescription("The sample parser") + .withMajorVersion(1) + .withMinorVersion(0) + .withPatchVersion(0) + .withDeveloper("Test") + .withLicense("License 1.0") + .build(); + } +} diff --git a/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserProcessor.java b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserProcessor.java new file mode 100644 index 0000000..0775bfe --- /dev/null +++ b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserProcessor.java @@ -0,0 +1,64 @@ +package com.experian.datastudio.sdk.parser.sample; + +import com.experian.datastudio.sdk.api.parser.processor.*; + +import java.io.*; +import java.util.*; + +public class SampleParserProcessor implements ParserProcessor { + @Override + public List getTableDefinition(TableDefinitionContext context) throws IOException { + Objects.requireNonNull(context.getLocale(), "context.getLocale() must not null."); + Objects.requireNonNull(context.getFilename(), "context.getFilename() must not null."); + Optional optEncoding = context.getParameterConfiguration(SampleParser.PARAMETER_KEY_ENCODING); + if (!optEncoding.isPresent()) { + throw new IllegalStateException("Expected encoding parameter is presented."); + } + + InputStream stream = context.getStreamSupplier().get(); + ParserTableDefinitionFactory parserTableDefinitionFactory = context.getParserTableDefinitionFactory(); + ParserColumnDefinitionFactory parserColumnDefinitionFactory = context.getParserColumnDefinitionFactory(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + if (reader.ready()) { + String firstLine = reader.readLine(); + ParserTableDefinition tableDefinition = parserTableDefinitionFactory.createTableDefinition("1", "MySample", "My sample definition"); + Arrays.stream(firstLine.split(",")) + .forEach(columnName -> tableDefinition.addColumn(parserColumnDefinitionFactory.createColumnDefinition(columnName, columnName))); + + reader.close(); + stream.close(); + return Collections.singletonList(tableDefinition); + } + return null; + } + + @Override + public ClosableIterator> getRowIterator(RowIteratorContext context) { + Objects.requireNonNull(context.getLocale(), "context.getLocale() must not null."); + if (!"1".equals(context.getTableId())) { + throw new IllegalStateException("Expected tableId '" + context.getTableId() + "' equals to '1'."); + } + Objects.requireNonNull(context.getTableDefinition(), "context.getTableDefinition() must not null."); + long maxRow = (long) context.getParameterConfiguration(SampleParser.PARAMETER_KEY_MAX_ROWS).orElse(0L); + if (maxRow <= 0) { + throw new IllegalStateException("Expected maxRow '" + maxRow + "' larger than '0'."); + } + + InputStreamReader streamReader = new InputStreamReader(context.getStreamSupplier().get()); + Scanner scanner = new Scanner(streamReader); + ClosableIteratorBuilder closableIteratorBuilder = context.getClosableIteratorBuilder(); + + if (scanner.hasNextLine()) { + //skip first line + scanner.nextLine(); + return closableIteratorBuilder.withHasNext(scanner::hasNextLine) + .withNext(() -> Arrays.asList(scanner.nextLine().split(","))) + .withProgress(() -> 1.0) + .withClose(scanner::close) + .build(); + } + + return null; + } +} diff --git a/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserTest.java b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserTest.java new file mode 100644 index 0000000..56402b2 --- /dev/null +++ b/SDKTestFramework/src/test/java/com/experian/datastudio/sdk/parser/sample/SampleParserTest.java @@ -0,0 +1,45 @@ +package com.experian.datastudio.sdk.parser.sample; + +import com.experian.datastudio.sdk.testframework.SDKTestFramework; +import com.experian.datastudio.sdk.testframework.assertion.TableResultAssert; +import com.experian.datastudio.sdk.testframework.customparser.*; +import org.junit.jupiter.api.Test; + +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SampleParserTest { + + @Test + public void testCustomParser() { + final TestParser parser = SDKTestFramework.createTestParser( + parserBuilder -> parserBuilder + .loadCustomParser(customParserLoader -> + customParserLoader.fromParserDefinition(new SampleParser())) + .withLocale(Locale.CANADA) + .addParserParameter("&encoding", "UTF-8") + .build()); + + final TestParserSource source = SDKTestFramework.createTestParserSource( + parserSourceBuilder -> parserSourceBuilder + .loadFile("/csvdata/columns_123.sample") + .build()); + + final TestParserSetting setting = SDKTestFramework.createTestParserSetting( + parserSettingBuilder -> parserSettingBuilder + .assignDataTypeToColumn(ParserDataType.NUMERIC, "Customer Id") + .build()); + + final ParserTestSuite testSuite = ParserTestSuiteBuilderFactory + .newBuilder() + .withParser(parser) + .withSource(source) + .withSetting(setting) + .build(); + + final ParserTestResult result = testSuite.execute(); + assertThat(result.getFirstTableDefinition().getName()).isEqualTo("MySample"); + TableResultAssert.assertThat(result.getTableResult("1")).compareOutputWithCsv("/csvdata/columns_123.sample"); + } +} \ No newline at end of file diff --git a/SDKTestFramework/src/test/resources/csvdata/columns_123.sample b/SDKTestFramework/src/test/resources/csvdata/columns_123.sample new file mode 100644 index 0000000..b9694cf --- /dev/null +++ b/SDKTestFramework/src/test/resources/csvdata/columns_123.sample @@ -0,0 +1,3 @@ +Column 1,Column 2,Column 3 +a,1,true +b,2,false \ No newline at end of file