Skip to content

Commit

Permalink
Add support of relative paths for script definition (#103)
Browse files Browse the repository at this point in the history
* Add support of relative paths for script definition

* Add relative paths to documentation
  • Loading branch information
lukfor authored Aug 30, 2023
1 parent 1f97f4c commit 66b825c
Show file tree
Hide file tree
Showing 15 changed files with 214 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ output
test_mock.nf
/.nf-test/
site
tests
/tests
3 changes: 3 additions & 0 deletions docs/docs/testcases/nextflow_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ nextflow_function {
}
```

>:bulb: Script paths that start with `./` or `../` are considered relative paths. These paths are resolved based on the location of the test script. Relative paths are beneficial when you want to reference files or directories located within the same directory as your test script or in a parent directory. These paths provide a convenient way to access files without specifying the entire path.

### Multiple Functions

If a Nextflow script contains multiple functions and you want to test them all in the same testsuite, you can override the `function` property in each test. For example:
Expand Down
16 changes: 16 additions & 0 deletions docs/docs/testcases/nextflow_process.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ nextflow_process {
}
```


>:bulb: Script paths that start with `./` or `../` are considered relative paths. These paths are resolved based on the location of the test script. Relative paths are beneficial when you want to reference files or directories located within the same directory as your test script or in a parent directory. These paths provide a convenient way to access files without specifying the entire path.
## Assertions

The `process` object can be used in asserts to check its status or error messages.
Expand Down Expand Up @@ -52,6 +55,19 @@ assert process.out.my_channel.size() == 3
assert process.out.my_channel.get(0) == "hello"
```

Channels that lack explicit names can be addressed using square brackets and the corresponding index. This indexing method provides a straightforward way to interact with channels without the need for predefined names. To access the first output channel, you can use the index [0] as demonstrated below:

```Groovy
// channel exists
assert process.out[0] != null
// channel contains 3 elements
assert process.out[0].size() == 3
// first element is "hello"
assert process.out[0].get(0) == "hello"
````
## Example
### Nextflow script
Expand Down
21 changes: 21 additions & 0 deletions docs/docs/testcases/nextflow_workflow.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Workflow Testing

nf-test also allows to test a specific workflow. Please checkout the [CLI](../cli/generate.md) to generate a workflow test.

## Syntax

```Groovy
nextflow_workflow {
Expand All @@ -14,6 +17,9 @@ nextflow_workflow {
}
```

> :bulb: Script paths that start with `./` or `../` are considered relative paths. These paths are resolved based on the location of the test script. Relative paths are beneficial when you want to reference files or directories located within the same directory as your test script or in a parent directory. These paths provide a convenient way to access files without specifying the entire path.

## Assertions

The `workflow` object can be used in asserts to check its status, error messages or traces.
Expand Down Expand Up @@ -42,6 +48,21 @@ assert workflow.stdout.contains("Hello World") == 3
```

### Output Channels

The `workflow.out` object provides access to the content of all named output Channels (see Nextflow `emit`):

```groovy
// channel exists
assert workflow.out.my_channel != null
// channel contains 3 elements
assert workflow.out.my_channel.size() == 3
// first element is "hello"
assert workflow.out.my_channel.get(0) == "hello"
```


## Example

Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/askimed/nf/test/core/AbstractTestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public abstract class AbstractTestSuite implements ITestSuite {
private boolean autoSort = true;

private String options = "";

private String directory = "";

private List<String> tags = new Vector<String>();

Expand Down Expand Up @@ -96,13 +98,19 @@ public File getLocalConfig() {
@Override
public void setFilename(String filename) {
this.filename = filename;
this.directory = new File(filename).getParentFile().getAbsolutePath();
}

@Override
public String getFilename() {
return filename;
}

@Override
public String getDirectory() {
return directory;
}

@Override
public List<ITest> getTests() {
return tests;
Expand All @@ -127,4 +135,12 @@ public ITaggable getParent() {
return null;
}

protected String makeAbsolute(String path) {
return new File(directory, path).getAbsolutePath();
}

protected boolean isRelative(String path) {
return path.startsWith("../") || path.startsWith("./");
}

}
2 changes: 2 additions & 0 deletions src/main/java/com/askimed/nf/test/core/ITestSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public interface ITestSuite extends ITaggable {
public void setFilename(String filename);

public String getFilename();

public String getDirectory();

public void configure(Config config);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public void setFunction(String function) {
}

public String getScript() {
return script;
if (script != null && isRelative(script)) {
return makeAbsolute(script);
} else {
return script;
}
}

public void setScript(String script) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ public void script(String script) {
}

public String getScript() {
return script;
if (script != null && isRelative(script)) {
return makeAbsolute(script);
} else {
return script;
}
}

public void setScript(String script) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public String getProcess() {
}

public String getScript() {
return script;
if (script != null && isRelative(script)) {
return makeAbsolute(script);
} else {
return script;
}
}

public void setScript(String script) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public String getWorkflow() {
}

public String getScript() {
return script;
if (script != null && isRelative(script)) {
return makeAbsolute(script);
} else {
return script;
}
}

public void setScript(String script) {
Expand Down
19 changes: 19 additions & 0 deletions src/test/java/com/askimed/nf/test/lang/ProcessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,23 @@ public void testLoadGzip() throws Exception {
assertEquals(0, exitCode);

}

@Test
public void testScriptWithRelativePath() throws Exception {

App app = new App();
int exitCode = app.run(new String[] { "test", "test-data/process/default/test_process_relative.nf.test" });
assertEquals(0, exitCode);

}

@Test
public void testScriptWithRelativePathInSubfolder() throws Exception {

App app = new App();
int exitCode = app.run(new String[] { "test", "test-data/process/default/tests/test_process_relative.nf.test" });
assertEquals(0, exitCode);

}

}
11 changes: 10 additions & 1 deletion src/test/java/com/askimed/nf/test/lang/WorkflowTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ public void testWorkflowSucces() throws Exception {
assertEquals(0, exitCode);

}

@Test
public void testWorkflowWithRelativePath() throws Exception {

App app = new App();
int exitCode = app.run(new String[] { "test", "test-data/workflow/default/tests/trial.nf.test" });
assertEquals(0, exitCode);

}

@Test
public void testWorkflowWithNoOutputs() throws Exception {
Expand All @@ -57,7 +66,7 @@ public void testOverrideWorkflow() throws Exception {
public void testLibs() throws Exception {

App app = new App();
int exitCode = app.run(new String[] { "test", "test-data/workflow/libs/hello.nf.test", "--lib", "lib" });
int exitCode = app.run(new String[] { "test", "test-data/workflow/libs/hello.nf.test", "--lib", "lib" ,"--debug"});
assertEquals(0, exitCode);

}
Expand Down
40 changes: 40 additions & 0 deletions test-data/process/default/test_process_relative.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
nextflow_process {

name "Test process xy"

script "./test_process.nf"
process "TEST_PROCESS"

test("Should create 5 files") {

when {
params {
outdir = "$outputDir/seb7"
}
process {
"""
input[0] = Channel.of(1..5)
input[1] = "test"
"""
}
}

then {
assert process.success
assert process.out.my_output_numbers == [1,2,3,4,5]

assert process.out.my_output_files
assert process.out.my_output_files.size() == 5
def file1 = path process.out.my_output_files.get(0)
assert file1.fileName.toString() == "1_test.txt"
assert file1.fileName.toString().endsWith("test.txt")
assert file1.readLines() == ['lukas forer']

assert process.out.my_output_tuple
assert process.out.my_output_tuple.size() == 5
assert process.out.my_output_tuple.get(0).size() == 3
}

}

}
40 changes: 40 additions & 0 deletions test-data/process/default/tests/test_process_relative.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
nextflow_process {

name "Test process xy"

script "../test_process.nf"
process "TEST_PROCESS"

test("Should create 5 files") {

when {
params {
outdir = "$outputDir/seb7"
}
process {
"""
input[0] = Channel.of(1..5)
input[1] = "test"
"""
}
}

then {
assert process.success
assert process.out.my_output_numbers == [1,2,3,4,5]

assert process.out.my_output_files
assert process.out.my_output_files.size() == 5
def file1 = path process.out.my_output_files.get(0)
assert file1.fileName.toString() == "1_test.txt"
assert file1.fileName.toString().endsWith("test.txt")
assert file1.readLines() == ['lukas forer']

assert process.out.my_output_tuple
assert process.out.my_output_tuple.size() == 5
assert process.out.my_output_tuple.get(0).size() == 3
}

}

}
26 changes: 26 additions & 0 deletions test-data/workflow/default/tests/trial.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
nextflow_workflow {

name "Test workflow"
script "../trial.nf"
workflow "trial"

test("Should run without failures") {
when {
params {
outdir = "tests/results"
}
workflow {
"""
input[0] = Channel.of('a','b')
"""
}
}

then {
//check if test case succeeded
assert workflow.success
assert workflow.out.lukas.size() == 2
assert workflow.out.sebastian.size() == 2
}
}
}

0 comments on commit 66b825c

Please sign in to comment.