3333
3434import static org .junit .Assert .assertEquals ;
3535import static org .junit .Assert .assertFalse ;
36+ import static org .junit .Assert .assertNotNull ;
3637import static org .junit .Assert .assertTrue ;
3738
3839import java .util .concurrent .ExecutionException ;
3940
4041import org .junit .Test ;
4142import org .scijava .Cancelable ;
4243import org .scijava .Context ;
44+ import org .scijava .ItemIO ;
45+ import org .scijava .Priority ;
46+ import org .scijava .log .LogService ;
4347import org .scijava .module .Module ;
48+ import org .scijava .module .ModuleItem ;
4449import org .scijava .module .process .AbstractPreprocessorPlugin ;
4550import org .scijava .module .process .PreprocessorPlugin ;
4651import org .scijava .plugin .Parameter ;
4752import org .scijava .plugin .Plugin ;
53+ import org .scijava .service .Service ;
4854
4955/** Regression tests for {@link CommandModule}. */
5056public class CommandModuleTest {
@@ -64,7 +70,6 @@ public void testCancelable() throws InterruptedException, ExecutionException {
6470 assertFalse (crow .isCanceled ());
6571 }
6672
67-
6873 @ Test
6974 public void testNotCancelable () throws InterruptedException ,
7075 ExecutionException
@@ -96,6 +101,17 @@ public void testDefaultValues() {
96101 assertEquals (null , info .getInput ("thing" ).getDefaultValue ());
97102 }
98103
104+ @ Test
105+ public void testValidation () throws InterruptedException , ExecutionException {
106+ final Context context = new Context (CommandService .class );
107+ final CommandService commandService = context .service (CommandService .class );
108+
109+ final CommandModule module = //
110+ commandService .run (CommandWithValidation .class , true ).get ();
111+ assertNotNull (module .getInput ("stuff" ));
112+ assertEquals ("success" , module .getOutput ("result" ));
113+ }
114+
99115 // -- Helper classes --
100116
101117 /** A command which implements {@link Cancelable}. */
@@ -168,4 +184,55 @@ public void run() {
168184 time = 0 ;
169185 }
170186 }
187+
188+ /** A command which validates an input. */
189+ @ Plugin (type = Command .class )
190+ public static class CommandWithValidation extends ContextCommand {
191+
192+ @ Parameter
193+ private LogService log ;
194+
195+ @ Parameter (validater = "validateStuff" )
196+ private Stuff stuff ;
197+
198+ @ Parameter (type = ItemIO .OUTPUT )
199+ private String result = "default" ;
200+
201+ @ SuppressWarnings ("unused" )
202+ private void validateStuff () {
203+ final StringBuilder sb = new StringBuilder ();
204+ if (log == null ) sb .append ("[null-log] " );
205+ if (stuff == null ) sb .append ("[null-stuff] " );
206+ result = sb .length () == 0 ? "success" : sb .toString ();
207+ }
208+
209+ @ Override
210+ public void run () {
211+ if (!result .equals ("success" )) result += " failure" ;
212+ }
213+ }
214+
215+ /**
216+ * Preprocessor to inject {@link Stuff} instances very early. But (in theory)
217+ * not as early as {@link Service} and {@link Context} parameters get
218+ * populated.
219+ */
220+ @ Plugin (type = PreprocessorPlugin .class ,
221+ priority = Priority .VERY_HIGH_PRIORITY )
222+ public static class StuffPreprocessor extends AbstractPreprocessorPlugin {
223+
224+ @ Override
225+ public void process (final Module module ) {
226+ for (final ModuleItem <?> input : module .getInfo ().inputs ()) {
227+ if (Stuff .class .isAssignableFrom (input .getType ())) {
228+ module .setInput (input .getName (), new Stuff ());
229+ module .resolveInput (input .getName ());
230+ }
231+ }
232+ }
233+
234+ }
235+
236+ /** Placeholder class, for type safety. */
237+ public static class Stuff {}
171238}
0 commit comments