From 949a27f4e692a6a63bb7055f560549ccd594afb1 Mon Sep 17 00:00:00 2001 From: dotasek Date: Fri, 2 Jun 2023 18:00:26 -0400 Subject: [PATCH] Tests + start refactor --- .../org/hl7/fhir/validation/ValidatorCli.java | 152 ++++++----- .../fhir/validation/cli/tasks/CliTask.java | 20 ++ .../validation/cli/tasks/CompileTask.java | 34 +++ .../validation/cli/tasks/FhirpathTask.java | 33 +++ .../validation/cli/tasks/InstallTask.java | 32 +++ .../cli/tasks/LangTransformTask.java | 33 +++ .../validation/cli/tasks/NarrativeTask.java | 33 +++ .../fhir/validation/cli/tasks/ScanTask.java | 36 +++ .../validation/cli/tasks/SnapshotTask.java | 33 +++ .../validation/cli/tasks/SpecialTask.java | 41 +++ .../validation/cli/tasks/SpreadsheetTask.java | 33 +++ .../validation/cli/tasks/StandaloneTask.java | 14 + .../validation/cli/tasks/TransformTask.java | 33 +++ .../validation/cli/tasks/ValidateTask.java | 44 ++++ .../cli/tasks/ValidationServiceTask.java | 15 ++ .../validation/cli/tasks/VersionTask.java | 33 +++ .../fhir/validation/cli/utils/Display.java | 7 +- .../fhir/validation/ValidatorCliTests.java | 244 ++++++++++++++++++ .../validation/cli/utils/DisplayTests.java | 2 +- 19 files changed, 788 insertions(+), 84 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CliTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CompileTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/FhirpathTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/InstallTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/LangTransformTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/NarrativeTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ScanTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SnapshotTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpecialTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpreadsheetTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/StandaloneTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TransformTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidateTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidationServiceTask.java create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/VersionTask.java create mode 100644 org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/ValidatorCliTests.java diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java index 76d019efc..34c319b0a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java @@ -9,8 +9,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import org.hl7.fhir.convertors.loaders.loaderR5.R4BToR5Loader; - /* Copyright (c) 2011+, HL7, Inc. All rights reserved. @@ -82,6 +80,7 @@ import org.hl7.fhir.utilities.settings.FhirSettings; import org.hl7.fhir.validation.cli.model.CliContext; import org.hl7.fhir.validation.cli.services.ComparisonService; import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.tasks.*; import org.hl7.fhir.validation.cli.utils.Display; import org.hl7.fhir.validation.cli.utils.EngineMode; import org.hl7.fhir.validation.cli.utils.Params; @@ -120,7 +119,34 @@ public class ValidatorCli { private static ValidationService validationService = new ValidationService(); - public static void main(String[] args) throws Exception { + protected ValidationService myValidationService; + + final List cliTasks; + + final CliTask defaultCliTask = new ValidateTask(); + protected ValidatorCli(ValidationService validationService) { + myValidationService = validationService; + cliTasks = getCliTasks(); + } + + protected List getCliTasks() { + return List.of( + + new CompileTask(), + new FhirpathTask(), + new InstallTask(), + new LangTransformTask(), + new NarrativeTask(), + new ScanTask(), + new SnapshotTask(), + new SpecialTask(), + new SpreadsheetTask(), + new TransformTask(), + new VersionTask(), + defaultCliTask); + } + + protected void readParamsAndExecuteTask(CliContext cliContext, String[] args) throws Exception { TimeTracker tt = new TimeTracker(); TimeTracker.Session tts = tt.start("Loading"); @@ -130,8 +156,6 @@ public class ValidatorCli { Display.displayVersion(); Display.displaySystemInfo(); - CliContext cliContext = Params.loadCliContext(args); - if (cliContext.getFhirSettingsFile() != null) { FhirSettings.setExplicitFilePath(cliContext.getFhirSettingsFile()); } @@ -139,35 +163,26 @@ public class ValidatorCli { FileFormat.checkCharsetAndWarnIfNotUTF8(System.out); if (shouldDisplayHelpToUser(args)) { - Display.displayHelpDetails(); + Display.displayHelpDetails("help.txt"); } else if (Params.hasParam(args, Params.COMPARE)) { if (destinationDirectoryValid(Params.getParam(args, Params.DESTINATION))) { doLeftRightComparison(args, cliContext, tt); } } else if (Params.hasParam(args, Params.TEST) || Params.hasParam(args, Params.TX_TESTS)) { parseTestParamsAndExecute(args); - } else if (Params.hasParam(args, Params.SPECIAL)) { - executeSpecial(args); - } else { + } + else { Display.printCliArgumentsAndInfo(args); - doValidation(tt, tts, cliContext); + doValidation(tt, tts, cliContext, args); } } - private static void executeSpecial(String[] args) throws JsonException, IOException { - String specialMode = Params.getParam(args, Params.SPECIAL); - if ("r4r5tests".equals(specialMode)) { - final String target = Params.getParam(args, Params.TARGET); - final String source = Params.getParam(args, Params.SOURCE); - final String filter = Params.getParam(args, Params.FILTER); - if (new File(target).exists()) { - new R4R5MapTester().testMaps(target, source, filter); - } - } else { - System.out.println("Unknown SpecialMode "+specialMode); - } + public static void main(String[] args) throws Exception { + final ValidatorCli validatorCli = new ValidatorCli(validationService); + final CliContext cliContext = Params.loadCliContext(args); + validatorCli.readParamsAndExecuteTask(cliContext, args); } - + private static void setJavaSystemProxyParamsFromParams(String[] args) { setJavaSystemProxyHostFromParams(args, Params.PROXY, HTTP_PROXY_HOST, HTTP_PROXY_PORT); @@ -285,6 +300,7 @@ public class ValidatorCli { } private static boolean shouldDisplayHelpToUser(String[] args) { + String helpTarget = Params.getParam(args, Params.HELP); return (args.length == 0 || Params.hasParam(args, Params.HELP) || Params.hasParam(args, "?") @@ -304,14 +320,37 @@ public class ValidatorCli { ComparisonService.doLeftRightComparison(args, Params.getParam(args, Params.DESTINATION), validator); } - private static void doValidation(TimeTracker tt, TimeTracker.Session tts, CliContext cliContext) throws Exception { + private void doValidation(TimeTracker tt, TimeTracker.Session tts, CliContext cliContext, String[] params) throws Exception { if (cliContext.getSv() == null) { - cliContext.setSv(validationService.determineVersion(cliContext)); + cliContext.setSv(myValidationService.determineVersion(cliContext)); } + + CliTask cliTask = null; + for(CliTask candidateTask : cliTasks) { + if (candidateTask.shouldExecuteTask(cliContext, params)) { + cliTask = candidateTask; + } + } + if (cliTask == null) + cliTask = defaultCliTask; + + if (cliTask instanceof ValidationServiceTask) { + ValidationEngine validationEngine = getValidationEngine(tt, cliContext); + tts.end(); + ((ValidationServiceTask) cliTask).executeTask(myValidationService, validationEngine, cliContext, params, tt, tts); + } else if (cliTask instanceof StandaloneTask) { + ((StandaloneTask) cliTask).executeTask(cliContext,params,tt,tts); + } + + System.out.println("Done. " + tt.report()+". Max Memory = "+Utilities.describeSize(Runtime.getRuntime().maxMemory())); + } + + private ValidationEngine getValidationEngine(TimeTracker tt, CliContext cliContext) throws Exception { + ValidationEngine validationEngine; System.out.println(" Locale: "+Locale.getDefault().getDisplayCountry()+"/"+Locale.getDefault().getCountry()); if (cliContext.getJurisdiction() == null) { - System.out.println(" Jurisdiction: None specified (locale = "+Locale.getDefault().getCountry()+")"); - System.out.println(" Note that exceptions and validation failures may happen in the absense of a locale"); + System.out.println(" Jurisdiction: None specified (locale = "+Locale.getDefault().getCountry()+")"); + System.out.println(" Note that exceptions and validation failures may happen in the absense of a locale"); } else { System.out.println(" Jurisdiction: "+JurisdictionUtilities.displayJurisdiction(cliContext.getJurisdiction())); } @@ -320,57 +359,12 @@ public class ValidatorCli { // Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long). // Version gets spit out a couple of lines later after we've loaded the context String definitions = "dev".equals(cliContext.getSv()) ? "hl7.fhir.r5.core#current" : VersionUtilities.packageForVersion(cliContext.getSv()) + "#" + VersionUtilities.getCurrentVersion(cliContext.getSv()); - ValidationEngine validator = validationService.initializeValidator(cliContext, definitions, tt); - tts.end(); - switch (cliContext.getMode()) { - case TRANSFORM: - validationService.transform(cliContext, validator); - break; - case COMPILE: - validationService.compile(cliContext, validator); - break; - case NARRATIVE: - validationService.generateNarrative(cliContext, validator); - break; - case SNAPSHOT: - validationService.generateSnapshot(cliContext, validator); - break; - case INSTALL: - validationService.install(cliContext, validator); - break; - case SPREADSHEET: - validationService.generateSpreadsheet(cliContext, validator); - break; - case CONVERT: - validationService.convertSources(cliContext, validator); - break; - case FHIRPATH: - validationService.evaluateFhirpath(cliContext, validator); - break; - case VERSION: - validationService.transformVersion(cliContext, validator); - break; - case LANG_TRANSFORM: - validationService.transformLang(cliContext, validator); - break; - case VALIDATION: - case SCAN: - default: - for (String s : cliContext.getProfiles()) { - if (!validator.getContext().hasResource(StructureDefinition.class, s) && !validator.getContext().hasResource(ImplementationGuide.class, s)) { - System.out.println(" Fetch Profile from " + s); - validator.loadProfile(cliContext.getLocations().getOrDefault(s, s)); - } - } - System.out.println("Validating"); - if (cliContext.getMode() == EngineMode.SCAN) { - Scanner validationScanner = new Scanner(validator.getContext(), validator.getValidator(null), validator.getIgLoader(), validator.getFhirPathEngine()); - validationScanner.validateScan(cliContext.getOutput(), cliContext.getSources()); - } else { - validationService.validateSources(cliContext, validator); - } - break; - } - System.out.println("Done. " + tt.report()+". Max Memory = "+Utilities.describeSize(Runtime.getRuntime().maxMemory())); + validationEngine = myValidationService.initializeValidator(cliContext, definitions, tt); + return validationEngine; + } + + protected void validateScan(CliContext cliContext, ValidationEngine validator) throws Exception { + Scanner validationScanner = new Scanner(validator.getContext(), validator.getValidator(null), validator.getIgLoader(), validator.getFhirPathEngine()); + validationScanner.validateScan(cliContext.getOutput(), cliContext.getSources()); } } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CliTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CliTask.java new file mode 100644 index 000000000..2c8d22861 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CliTask.java @@ -0,0 +1,20 @@ +package org.hl7.fhir.validation.cli.tasks; + +import lombok.Getter; +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.cli.model.CliContext; + +import java.io.IOException; + +public abstract class CliTask { + + public abstract String getName(); + public final String getTaskParam() { + return "-" + getName(); + } + public abstract boolean shouldExecuteTask(CliContext cliContext, String[] args); + public abstract void printHelp(java.io.PrintStream out); + + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CompileTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CompileTask.java new file mode 100644 index 000000000..82b8f7468 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/CompileTask.java @@ -0,0 +1,34 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.Scanner; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class CompileTask extends ValidationServiceTask { + + @Override + public String getName() { + return "compile"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.COMPILE; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.compile(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/FhirpathTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/FhirpathTask.java new file mode 100644 index 000000000..e60579027 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/FhirpathTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class FhirpathTask extends ValidationServiceTask { + + @Override + public String getName() { + return "fhirpath"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.FHIRPATH; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.evaluateFhirpath(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/InstallTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/InstallTask.java new file mode 100644 index 000000000..9a770ef2d --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/InstallTask.java @@ -0,0 +1,32 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class InstallTask extends ValidationServiceTask { + + @Override + public String getName() { + return "install"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.INSTALL; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.install(cliContext, validationEngine); + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/LangTransformTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/LangTransformTask.java new file mode 100644 index 000000000..391059dbc --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/LangTransformTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class LangTransformTask extends ValidationServiceTask { + + @Override + public String getName() { + return "lang-transform"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.LANG_TRANSFORM; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.transformLang(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/NarrativeTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/NarrativeTask.java new file mode 100644 index 000000000..fe76a9729 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/NarrativeTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class NarrativeTask extends ValidationServiceTask { + + @Override + public String getName() { + return "narrative"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.NARRATIVE; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.generateNarrative(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ScanTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ScanTask.java new file mode 100644 index 000000000..f7b960699 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ScanTask.java @@ -0,0 +1,36 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.Scanner; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class ScanTask extends ValidationServiceTask { + + + @Override + public String getName() { + return "scan"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.SCAN; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + Scanner validationScanner = new Scanner(validationEngine.getContext(), validationEngine.getValidator(null), validationEngine.getIgLoader(), validationEngine.getFhirPathEngine()); + validationScanner.validateScan(cliContext.getOutput(), cliContext.getSources()); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SnapshotTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SnapshotTask.java new file mode 100644 index 000000000..810f75af3 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SnapshotTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class SnapshotTask extends ValidationServiceTask { + + @Override + public String getName() { + return "snapshot"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.SNAPSHOT; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.generateSnapshot(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpecialTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpecialTask.java new file mode 100644 index 000000000..4091ba859 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpecialTask.java @@ -0,0 +1,41 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.utils.Params; +import org.hl7.fhir.validation.special.R4R5MapTester; + +import java.io.File; +import java.io.PrintStream; + +public class SpecialTask extends StandaloneTask{ + @Override + public String getName() { + return "special"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return Params.hasParam(args, Params.SPECIAL); + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + String specialMode = Params.getParam(args, Params.SPECIAL); + if ("r4r5tests".equals(specialMode)) { + final String target = Params.getParam(args, Params.TARGET); + final String source = Params.getParam(args, Params.SOURCE); + final String filter = Params.getParam(args, Params.FILTER); + if (new File(target).exists()) { + new R4R5MapTester().testMaps(target, source, filter); + } + } else { + System.out.println("Unknown SpecialMode "+specialMode); + } + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpreadsheetTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpreadsheetTask.java new file mode 100644 index 000000000..533a5559b --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/SpreadsheetTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class SpreadsheetTask extends ValidationServiceTask { + + @Override + public String getName() { + return "spreadsheet"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.SPREADSHEET; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.generateSpreadsheet(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/StandaloneTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/StandaloneTask.java new file mode 100644 index 000000000..ad40dc80c --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/StandaloneTask.java @@ -0,0 +1,14 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; + +public abstract class StandaloneTask extends CliTask{ + + public abstract void executeTask(CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception; + + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TransformTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TransformTask.java new file mode 100644 index 000000000..78ec5a091 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/TransformTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class TransformTask extends ValidationServiceTask { + + @Override + public String getName() { + return "transform"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.TRANSFORM; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.transform(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidateTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidateTask.java new file mode 100644 index 000000000..3c2d165b8 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidateTask.java @@ -0,0 +1,44 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.r5.model.ImplementationGuide; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; + +import java.io.PrintStream; + +public class ValidateTask extends ValidationServiceTask { + + @Override + public String getName() { + return "validate"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + // There is no explicit way to trigger a validation task. + // It is the default task. + return false; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + for (String s : cliContext.getProfiles()) { + if (!validationEngine.getContext().hasResource(StructureDefinition.class, s) && !validationEngine.getContext().hasResource(ImplementationGuide.class, s)) { + System.out.println(" Fetch Profile from " + s); + validationEngine.loadProfile(cliContext.getLocations().getOrDefault(s, s)); + } + } + System.out.println("Validating"); + + validationService.validateSources(cliContext, validationEngine); + + } +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidationServiceTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidationServiceTask.java new file mode 100644 index 000000000..8cfd3a08f --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/ValidationServiceTask.java @@ -0,0 +1,15 @@ +package org.hl7.fhir.validation.cli.tasks; + +import lombok.Getter; +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; + +public abstract class ValidationServiceTask extends CliTask{ + + public abstract void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, org.hl7.fhir.utilities.TimeTracker tt, TimeTracker.Session tts) throws Exception; + + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/VersionTask.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/VersionTask.java new file mode 100644 index 000000000..aae1bfcc8 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/tasks/VersionTask.java @@ -0,0 +1,33 @@ +package org.hl7.fhir.validation.cli.tasks; + +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.ValidationEngine; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.utils.EngineMode; + +import java.io.PrintStream; + +public class VersionTask extends ValidationServiceTask { + + @Override + public String getName() { + return "to-version"; + } + + @Override + public boolean shouldExecuteTask(CliContext cliContext, String[] args) { + return cliContext.getMode() == EngineMode.VERSION; + } + + @Override + public void printHelp(PrintStream out) { + + } + + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) throws Exception { + validationService.transformVersion(cliContext, validationEngine); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java index 14a988487..42857323c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Display.java @@ -5,9 +5,7 @@ import java.io.InputStream; import org.apache.commons.io.IOUtils; import org.hl7.fhir.r5.model.Constants; -import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; -import org.hl7.fhir.utilities.npm.ToolsVersion; /** * Class for displaying output to the cli user. @@ -52,10 +50,11 @@ public class Display { /** * Loads the help details from resources/help.txt, and displays them on the command line to the user. + * @param file */ - public static void displayHelpDetails() { + public static void displayHelpDetails(String file) { ClassLoader classLoader = Display.class.getClassLoader(); - InputStream help = classLoader.getResourceAsStream("help.txt"); + InputStream help = classLoader.getResourceAsStream(file); try { String data = IOUtils.toString(help, "UTF-8"); diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/ValidatorCliTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/ValidatorCliTests.java new file mode 100644 index 000000000..dc7fffd20 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/ValidatorCliTests.java @@ -0,0 +1,244 @@ +package org.hl7.fhir.validation; + +import org.apache.commons.compress.archivers.sevenz.CLI; +import org.hl7.fhir.utilities.TimeTracker; +import org.hl7.fhir.validation.cli.model.CliContext; +import org.hl7.fhir.validation.cli.services.ValidationService; +import org.hl7.fhir.validation.cli.tasks.*; +import org.hl7.fhir.validation.cli.utils.Params; + + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class ValidatorCliTests { + + @Mock + ValidationService validationService; + + @Mock + ValidationEngine validationEngine; + + @Spy + CompileTask compileTask; + + @Spy + FhirpathTask fhirpathTask; + @Spy + InstallTask installTask; + + @Spy + LangTransformTask langTransformTask; + + @Spy + NarrativeTask narrativeTask; + + @Spy + SnapshotTask snapshotTask; + @Spy + SpreadsheetTask spreadsheetTask; + @Spy + TransformTask transformTask; + + @Spy + VersionTask versionTask; + @Spy + ValidateTask validateTask; + + @Spy + ScanTask scanTask = new ScanTask() { + @Override + public void executeTask(ValidationService validationService, ValidationEngine validationEngine, CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) {} + }; + @Spy + SpecialTask specialTask = new SpecialTask() { + @Override + public void executeTask(CliContext cliContext, String[] args, TimeTracker tt, TimeTracker.Session tts) {} + }; + + public ValidatorCli mockValidatorCli() { + ValidatorCli validatorCli = spy(new ValidatorCli(validationService){ + protected void validateScan(CliContext cliContext, ValidationEngine validator) { + // DO NOTHING; + } + + protected List getCliTasks() { + return List.of( + compileTask, + fhirpathTask, + installTask, + langTransformTask, + narrativeTask, + scanTask, + snapshotTask, + specialTask, + spreadsheetTask, + transformTask, + versionTask, + //validate is the default + validateTask + ); + } + }); + return validatorCli; + } + public ValidatorCli mockValidatorCliWithService(CliContext cliContext) throws Exception { + when(validationService.determineVersion(Mockito.same(cliContext))).thenReturn("5.0.1"); + when(validationService.initializeValidator(Mockito.same(cliContext), anyString(), any(org.hl7.fhir.utilities.TimeTracker.class))).thenReturn(validationEngine); + return mockValidatorCli(); + } + + @Test + public void testCorrectTasksInValidatorCli() { + ValidatorCli realCli = new ValidatorCli(mock(ValidationService.class)); + ValidatorCli mockCli = mockValidatorCli(); + + List realTasks = realCli.getCliTasks(); + List mockTasks = mockCli.getCliTasks(); + assertEquals(mockTasks.size(), realTasks.size()); + for (int i = 0; i < realTasks.size(); i++) { + assertEquals(mockTasks.get(i).getName(), realTasks.get(i).getName(), "Differing task at index " + i); + } + } + + private void assertContainsValidationTask(List tasks, String name) { + for (CliTask task : tasks) { + if (task.getName().equals(name)) { + return; + } + } + fail("Cannot find " + name + " in task list"); + } + + @Test + public void transformTest() throws Exception { + final String[] args = new String[]{"-transform", "dummyFile.map", "dummySource.json"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).transform(same(cliContext), same(validationEngine)); + } + + @Test + public void narrativeTest() throws Exception { + final String[] args = new String[]{"-narrative"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).generateNarrative(same(cliContext), same(validationEngine)); + } + + @Test + public void compileTest() throws Exception { + final String[] args = new String[]{"-compile", "dummyMap.map"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).compile(same(cliContext), same(validationEngine)); + } + + @Test + public void snapshotTest() throws Exception { + final String[] args = new String[]{"-snapshot"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).generateSnapshot(same(cliContext), same(validationEngine)); + } + + @Test + public void installTest() throws Exception { + final String[] args = new String[]{"-install"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).install(same(cliContext), same(validationEngine)); + } + + @Test + public void spreadsheetTest() throws Exception { + final String[] args = new String[]{"-spreadsheet"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).generateSpreadsheet(same(cliContext), same(validationEngine)); + } + + @Test + public void fhirpathTest() throws Exception { + final String[] args = new String[]{"-fhirpath", "dummyExpression"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).evaluateFhirpath(same(cliContext), same(validationEngine)); + } + + @Test + public void versionTest() throws Exception { + final String[] args = new String[]{"-to-version", "1.2.3"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).transformVersion(same(cliContext), same(validationEngine)); + } + + @Test + public void langTransformTest() throws Exception { + final String[] args = new String[]{"-lang-transform", "dummyLang"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).transformLang(same(cliContext), same(validationEngine)); + } + + @Test + public void defaultTest() throws Exception { + final String[] args = new String[]{"dummyFile.json"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(validationService).validateSources(same(cliContext), same(validationEngine)); + } + + @Test + public void scanTest() throws Exception { + final String[] args = new String[]{"-scan"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCliWithService(cliContext); + cli.readParamsAndExecuteTask(cliContext, args); + Mockito.verify(validationService).determineVersion(same(cliContext)); + Mockito.verify(scanTask).executeTask(same(validationService), same(validationEngine), same(cliContext), eq(args), any(TimeTracker.class), any(TimeTracker.Session.class)); + } + + @Test + public void specialTest() throws Exception { + final String[] args = new String[]{"-special"}; + CliContext cliContext = Params.loadCliContext(args); + ValidatorCli cli = mockValidatorCli(); + cli.readParamsAndExecuteTask(cliContext, args); + + Mockito.verify(specialTask).executeTask(same(cliContext), eq(args), any(TimeTracker.class), any(TimeTracker.Session.class)); + } +} diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/utils/DisplayTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/utils/DisplayTests.java index 38061f386..eccac5731 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/utils/DisplayTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/cli/utils/DisplayTests.java @@ -23,7 +23,7 @@ public class DisplayTests { System.setErr(new PrintStream(errContent)); try { - Display.displayHelpDetails(); + Display.displayHelpDetails("help.txt"); String output = outContent.toString();