Skip to content

Commit

Permalink
Cleanup and test cases for the failure modes with improved errors
Browse files Browse the repository at this point in the history
  • Loading branch information
JaredHatfield committed Mar 3, 2024
1 parent f7edb07 commit b3a5004
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 20 deletions.
5 changes: 0 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@
<artifactId>jsonassert</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
Expand Down
45 changes: 34 additions & 11 deletions src/main/java/com/unitvectory/jsonparamunit/JsonNodeParamUnit.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/
package com.unitvectory.jsonparamunit;

import static org.junit.jupiter.api.Assertions.fail;
import java.nio.file.Files;
import java.nio.file.Path;
import org.json.JSONException;
Expand Down Expand Up @@ -71,20 +70,44 @@ public JsonNodeParamUnit(JsonParamUnitConfig config) {
*/
public final void run(String filePath) {

if (filePath == null) {
throw new JsonParamError("The provided filePath is null.");
}

if (filePath.isEmpty()) {
throw new JsonParamError("The provided filePath is empty.");
}

Path path = Path.of(filePath);

// Check if the file exists

if (!Files.exists(path)) {
throw new JsonParamError("The provided filePath does not exist.");
}

// Check if the file is a directory

if (!Files.isRegularFile(path)) {
throw new JsonParamError("The provided filePath is not a regular file.");
}

// Parse the test JSON

JsonNode rootNode = null;
try {
// Load the file path to string
String file = Files.readString(Path.of(filePath));
String file = Files.readString(path);

// Parse the JSON
rootNode = this.config.getMapper().readTree(file);
} catch (Exception e) {
fail("Failed to parse JSON", e);
throw new JsonParamError("Failed to parse the JSON from the test file.", e);
}

// THe input object
// The input object
if (!rootNode.has("input")) {
fail("Input is missing");
throw new JsonParamError("The 'input' JSON Object is missing from the test file.");
}

JsonNode inputNode = rootNode.get("input");
Expand All @@ -94,7 +117,7 @@ public final void run(String filePath) {

// The output object
if (!rootNode.has("output")) {
fail("Output is missing");
throw new JsonParamError("The 'output' JSON Object is missing from the test file.");
}

JsonNode expectedOutputNode = rootNode.get("output");
Expand All @@ -104,8 +127,8 @@ public final void run(String filePath) {
try {
expectedOutput = this.config.getMapper().writeValueAsString(expectedOutputNode);
} catch (JsonProcessingException e) {
fail("failed to encode expected output", e);
return;
throw new JsonParamError("The 'output' JSON Object could not be encoded as a string.",
e);
}

// Process the input to produce the actual output
Expand All @@ -114,16 +137,16 @@ public final void run(String filePath) {
try {
actualOutput = this.config.getMapper().writeValueAsString(actualOutputNode);
} catch (JsonProcessingException e) {
fail("failed to encode the actual output", e);
return;
throw new JsonParamError("The actual output could not be encoded as a string.", e);
}

// Assert the actual output matches the expected output
// This is the actual purpose of the test case.
try {
JSONAssert.assertEquals(expectedOutput, actualOutput, this.config.isStrictOutput());
} catch (JSONException e) {
fail("failed to assert the actual output matches the expected output", e);
throw new JsonParamError(
"Failed to assert the actual output matches the expected output.", e);
}
}

Expand Down
46 changes: 46 additions & 0 deletions src/main/java/com/unitvectory/jsonparamunit/JsonParamError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package com.unitvectory.jsonparamunit;

/**
* The JsonParamError exception used to indicate an assertion failed.
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
public class JsonParamError extends AssertionError {


/**
* Creates a new instance of the JsonParamError class.
*
* @param message the message
*/
public JsonParamError(String message) {
super(message);
}

/**
* Creates a new instance of the JsonParamError class.
*
* @param message the message
* @param cause the cause
*/
public JsonParamError(String message, Throwable cause) {
super(message, cause);
}

/**
* Creates a new instance of the JsonParamError class.
*
* @param cause the cause
*/
public JsonParamError(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
*/
package com.unitvectory.jsonparamunit;

import static org.junit.jupiter.api.Assertions.fail;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;

Expand Down Expand Up @@ -42,16 +41,15 @@ public final JsonNode process(JsonNode input, String context) {
try {
inputString = this.getConfig().getMapper().writeValueAsString(input);
} catch (JsonProcessingException e) {
fail("failed to encode input as JsonNode", e);
throw new JsonParamError("Failed to encode input as String.", e);
}

String outputString = process(inputString, context);

try {
return this.getConfig().getMapper().readTree(outputString);
} catch (JsonProcessingException e) {
fail("failed to encode ouput as JsonNode", e);
return null;
throw new JsonParamError("Failed to decode output as JsonNode.", e);
}
}

Expand Down
107 changes: 107 additions & 0 deletions src/test/java/com/unitvectory/jsonparamunit/FailuresTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright 2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v2.0 which accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package com.unitvectory.jsonparamunit;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import com.fasterxml.jackson.databind.JsonNode;
import com.unitvectory.fileparamunit.ListFileSource;

/**
* Test cases for testing the failures by intentionally misconfiguring the test case environment and
* asserting the correct exception is thrown to describe the failure.
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
public class FailuresTest extends JsonNodeParamUnit {

@Test
public void filePathNullTest() {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
run(null);
});

assertEquals("The provided filePath is null.", exception.getMessage());
}

@Test
public void filePathEmptyTest() {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
run("");
});

assertEquals("The provided filePath is empty.", exception.getMessage());
}

@ParameterizedTest
@ListFileSource(resources = "/failures/badjson", fileExtension = ".json")
public void fileNotExistTest(String file) {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
// Changing the file path it won't exist
run(file + "x");
});

assertEquals("The provided filePath does not exist.", exception.getMessage());
}

@ParameterizedTest
@ListFileSource(resources = "/failures/badjson", fileExtension = ".json")
public void fileIsDirectoryTest(String file) {
// For this test instead of the file we are getting the directory it is in which will fail
String directory = new File(file).getParent();
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
// Changing the file path it won't exist
run(directory);
});

assertEquals("The provided filePath is not a regular file.", exception.getMessage());
}

@ParameterizedTest
@ListFileSource(resources = "/failures/badjson", fileExtension = ".json")
public void badJsonTest(String file) {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
// Changing the file path it won't exist
run(file);
});

assertEquals("Failed to parse the JSON from the test file.", exception.getMessage());
}

@ParameterizedTest
@ListFileSource(resources = "/failures/noinput", fileExtension = ".json")
public void noInputTest(String file) {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
run(file);
});

assertEquals("The 'input' JSON Object is missing from the test file.",
exception.getMessage());
}

@ParameterizedTest
@ListFileSource(resources = "/failures/nooutput", fileExtension = ".json")
public void noOutputTest(String file) {
JsonParamError exception = assertThrows(JsonParamError.class, () -> {
run(file);
});

assertEquals("The 'output' JSON Object is missing from the test file.",
exception.getMessage());
}

@Override
public JsonNode process(JsonNode input, String context) {
return this.getConfig().getMapper().createObjectNode();
}

}
1 change: 1 addition & 0 deletions src/test/resources/failures/badjson/file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{
6 changes: 6 additions & 0 deletions src/test/resources/failures/noinput/file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"context": "context",
"output": {
"foo": "bar"
}
}
6 changes: 6 additions & 0 deletions src/test/resources/failures/nooutput/file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"input": {
"foo": "bar"
},
"context": "myContext"
}

0 comments on commit b3a5004

Please sign in to comment.