From ab85c8490cf965dd7a0d7ea2432e24afc6a31533 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Sat, 19 Dec 2020 09:51:21 -0500 Subject: [PATCH] WIP. adding validation tests. refactoring --- src/main/java/jvc/main/Jvc.java | 23 +++++++++-- src/main/java/jvc/model/JAsset.java | 4 +- .../java/jvc/model/operation/JOperation.java | 8 +++- .../java/jvc/model/operation/JValidation.java | 18 ++++++-- .../model/operation/JValidationResult.java | 41 +++++++++++++++++++ .../java/jvc/operation/HasWidthAndHeight.java | 3 +- .../jvc/operation/exec/AdjustSpeedExec.java | 4 +- .../java/jvc/operation/exec/ConcatExec.java | 5 ++- .../java/jvc/operation/exec/ExecBase.java | 2 +- .../java/jvc/operation/exec/KenBurnsExec.java | 9 ++-- .../jvc/operation/exec/LetterboxExec.java | 4 +- .../jvc/operation/exec/MergeAudioExec.java | 4 +- .../java/jvc/operation/exec/OverlayExec.java | 11 ++--- .../java/jvc/operation/exec/ScaleExec.java | 3 +- .../exec/SingleOrMultiSourceExecBase.java | 11 ++--- .../java/jvc/operation/exec/SplitExec.java | 5 ++- .../java/jvc/operation/exec/TrimExec.java | 4 +- .../service/JOperationValidationFailure.java | 16 ++++++++ src/main/java/jvc/service/JvcEngine.java | 28 ++++++++++++- src/main/java/jvc/service/Toolbox.java | 11 ++++- src/test/resources/tests/test_add_silence.jvc | 12 +++++- utils/cobbzilla-utils | 2 +- 22 files changed, 184 insertions(+), 44 deletions(-) create mode 100644 src/main/java/jvc/model/operation/JValidationResult.java create mode 100644 src/main/java/jvc/service/JOperationValidationFailure.java diff --git a/src/main/java/jvc/main/Jvc.java b/src/main/java/jvc/main/Jvc.java index 5565e8d..a1fb99a 100644 --- a/src/main/java/jvc/main/Jvc.java +++ b/src/main/java/jvc/main/Jvc.java @@ -2,11 +2,15 @@ package jvc.main; import jvc.model.JSpec; +import jvc.model.operation.JValidationResult; import jvc.service.AssetManager; +import jvc.service.JOperationValidationFailure; import jvc.service.JvcEngine; import jvc.service.Toolbox; import org.cobbzilla.util.main.BaseMain; +import java.util.List; + import static org.cobbzilla.util.daemon.ZillaRuntime.empty; public class Jvc extends BaseMain { @@ -31,10 +35,23 @@ public class Jvc extends BaseMain { final AssetManager assetManager = new AssetManager(toolbox, getOptions().scratchDir()); final JvcEngine opEngine = new JvcEngine(toolbox, assetManager, noExec); - opEngine.runSpec(spec); + try { + opEngine.runSpec(spec); + printCompleted(opEngine); + + } catch (JOperationValidationFailure e) { + printCompleted(opEngine); + final List results = e.getResults(); + err(">>> jvc: operation (index="+e.getOperation().execIndex()+") failed: "); + for (JValidationResult r : results) { + err(r.toString()); + } + } + } - final int opCount = spec.getOperations().length; - err(">>> jvc: completed " + opCount + " operation"+(opCount>1?"s":"")); + private void printCompleted(JvcEngine opEngine) { + final int opCount = opEngine.getCompleted().size(); + err(">>> jvc: completed " + opCount + " operation" + (opCount > 1 ? "s" : "")); } } diff --git a/src/main/java/jvc/model/JAsset.java b/src/main/java/jvc/model/JAsset.java index bfd2cb9..71c3bf8 100644 --- a/src/main/java/jvc/model/JAsset.java +++ b/src/main/java/jvc/model/JAsset.java @@ -286,12 +286,12 @@ public class JAsset implements JsObjectView { @Override public Object toJs() { return new JAssetJs(this); } public static class JAssetJs { - public Integer duration; + public Double duration; public Integer width; public Integer height; public JAssetJs (JAsset asset) { final BigDecimal d = asset.duration(); - this.duration = d == null ? null : d.intValue(); + this.duration = d == null ? null : d.doubleValue(); final BigDecimal w = asset.width(); this.width = w == null ? null : w.intValue(); diff --git a/src/main/java/jvc/model/operation/JOperation.java b/src/main/java/jvc/model/operation/JOperation.java index ff9c4fc..9d5ec21 100644 --- a/src/main/java/jvc/model/operation/JOperation.java +++ b/src/main/java/jvc/model/operation/JOperation.java @@ -1,5 +1,6 @@ package jvc.model.operation; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.JsonNode; import jvc.model.JAsset; @@ -32,12 +33,17 @@ public abstract class JOperation { @Getter @Setter private String operation; @Getter @Setter private JsonNode creates; - @Getter @Setter private JValidation[] validate; @Getter @Setter private boolean noExec = false; + @Getter @Setter private JValidation[] validate; + public boolean hasValidate() { return !empty(validate); } + @Getter @Setter private String comment; public boolean hasComment () { return !empty(comment); } + @JsonIgnore @Getter @Setter private Integer execIndex; + public String execIndex() { return execIndex != null ? ""+execIndex : "(null)"; } + public String hash(JAsset[] sources) { return hash(sources, null); } public String hash(JAsset[] sources, Object[] args) { diff --git a/src/main/java/jvc/model/operation/JValidation.java b/src/main/java/jvc/model/operation/JValidation.java index 7acd458..6873014 100644 --- a/src/main/java/jvc/model/operation/JValidation.java +++ b/src/main/java/jvc/model/operation/JValidation.java @@ -6,13 +6,25 @@ import org.cobbzilla.util.javascript.JsEngine; import java.util.Map; +import static jvc.service.Toolbox.evalBoolean; +import static org.cobbzilla.util.daemon.ZillaRuntime.empty; + public class JValidation { - @Getter @Setter private String comment; @Getter @Setter private String test; + @Getter @Setter private String comment; + public boolean hasComment () { return !empty(comment); } + + public JValidationResult eval(Map ctx, JsEngine js) { + try { + return new JValidationResult(this, evalBoolean(test, ctx, js)); + } catch (Exception e) { + return new JValidationResult(this, e); + } + } - public boolean eval(Map ctx, JsEngine js) { - return js.evaluateBoolean(test, ctx); + @Override public String toString() { + return (hasComment() ? getComment() + " - " : "") + "TEST=" + getTest(); } } diff --git a/src/main/java/jvc/model/operation/JValidationResult.java b/src/main/java/jvc/model/operation/JValidationResult.java new file mode 100644 index 0000000..5fb1e4b --- /dev/null +++ b/src/main/java/jvc/model/operation/JValidationResult.java @@ -0,0 +1,41 @@ +package jvc.model.operation; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +import static org.cobbzilla.util.daemon.ZillaRuntime.shortError; + +@AllArgsConstructor +public class JValidationResult { + + public JValidationResult(JValidation validation, boolean pass) { + this.validation = validation; + this.pass = pass; + } + + public JValidationResult(JValidation validation, Exception e) { + this.validation = validation; + this.pass = false; + this.exception = e; + } + + @Getter private final JValidation validation; + + @Getter private final boolean pass; + public boolean passed () { return pass; } + public boolean failed () { return !passed(); } + + @Getter @Setter private Exception exception; + public boolean hasException () { return exception != null; } + + @Override public String toString () { + return validation.toString()+" : " + + (passed() + ? "PASS" + : hasException() + ? shortError(exception) + : "FAIL"); + } + +} diff --git a/src/main/java/jvc/operation/HasWidthAndHeight.java b/src/main/java/jvc/operation/HasWidthAndHeight.java index 508e1c1..b7fbadd 100644 --- a/src/main/java/jvc/operation/HasWidthAndHeight.java +++ b/src/main/java/jvc/operation/HasWidthAndHeight.java @@ -2,7 +2,6 @@ package jvc.operation; import jvc.model.JAsset; import org.cobbzilla.util.javascript.JsEngine; -import org.cobbzilla.util.javascript.StandardJsEngine; import java.math.BigDecimal; import java.util.Map; @@ -23,7 +22,7 @@ public interface HasWidthAndHeight { default BigDecimal getHeight(Map ctx, JsEngine js) { return evalBig(getHeight(), ctx, js); } default void setProportionalWidthAndHeight(Map ctx, - StandardJsEngine js, + JsEngine js, JAsset asset) { if (hasWidth()) { final BigDecimal width = getWidth(ctx, js); diff --git a/src/main/java/jvc/operation/exec/AdjustSpeedExec.java b/src/main/java/jvc/operation/exec/AdjustSpeedExec.java index a3e5d66..c72983b 100644 --- a/src/main/java/jvc/operation/exec/AdjustSpeedExec.java +++ b/src/main/java/jvc/operation/exec/AdjustSpeedExec.java @@ -3,7 +3,7 @@ package jvc.operation.exec; import jvc.model.operation.JSingleOperationContext; import jvc.operation.AdjustSpeedOperation; import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.util.javascript.StandardJsEngine; +import org.cobbzilla.util.javascript.JsEngine; import java.math.BigDecimal; import java.util.Map; @@ -34,7 +34,7 @@ public class AdjustSpeedExec extends SingleOrMultiSourceExecBase ctx) { - final StandardJsEngine js = opCtx.toolbox.getJs(); + final JsEngine js = opCtx.toolbox.getJs(); final BigDecimal factor = op.getFactor(ctx, js); ctx.put(op.getAudio().name(), true); diff --git a/src/main/java/jvc/operation/exec/ConcatExec.java b/src/main/java/jvc/operation/exec/ConcatExec.java index 82e5e7a..6b6bdfd 100644 --- a/src/main/java/jvc/operation/exec/ConcatExec.java +++ b/src/main/java/jvc/operation/exec/ConcatExec.java @@ -31,7 +31,7 @@ public class ConcatExec extends ExecBase { // output combined result + "-map \"[v]\" -map \"[a]\" -y {{{output.path}}}"; - @Override public void operate(ConcatOperation op, Toolbox toolbox, AssetManager assetManager) { + @Override public Map operate(ConcatOperation op, Toolbox toolbox, AssetManager assetManager) { final JMultiOperationContext opCtx = op.getMultiInputContext(assetManager, toolbox); final List sources = opCtx.sources; @@ -40,7 +40,7 @@ public class ConcatExec extends ExecBase { final File defaultOutfile = assetManager.assetPath(op, sources, formatType); final File path = resolveOutputPath(output, defaultOutfile); - if (path == null) return; + if (path == null) return null; output.setPath(abs(path)); final Map ctx = new HashMap<>(); @@ -53,6 +53,7 @@ public class ConcatExec extends ExecBase { final String scriptOutput = exec(script, op.isNoExec()); log.debug("operate: command output: "+scriptOutput); assetManager.addOperationAsset(output); + return ctx; } } diff --git a/src/main/java/jvc/operation/exec/ExecBase.java b/src/main/java/jvc/operation/exec/ExecBase.java index 325d5f0..46e5acf 100644 --- a/src/main/java/jvc/operation/exec/ExecBase.java +++ b/src/main/java/jvc/operation/exec/ExecBase.java @@ -21,7 +21,7 @@ import static org.cobbzilla.util.system.CommandShell.execScript; @Slf4j public abstract class ExecBase { - public abstract void operate(OP operation, Toolbox toolbox, AssetManager assetManager); + public abstract Map operate(OP operation, Toolbox toolbox, AssetManager assetManager); protected String renderScript(Toolbox toolbox, Map ctx, String template) { return HandlebarsUtil.apply(toolbox.getHandlebars(), template, ctx); diff --git a/src/main/java/jvc/operation/exec/KenBurnsExec.java b/src/main/java/jvc/operation/exec/KenBurnsExec.java index 015da36..8f4b6ad 100644 --- a/src/main/java/jvc/operation/exec/KenBurnsExec.java +++ b/src/main/java/jvc/operation/exec/KenBurnsExec.java @@ -8,7 +8,7 @@ import jvc.operation.KenBurnsOperation; import jvc.service.AssetManager; import jvc.service.Toolbox; import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.util.javascript.StandardJsEngine; +import org.cobbzilla.util.javascript.JsEngine; import java.io.File; import java.math.BigDecimal; @@ -39,7 +39,7 @@ public class KenBurnsExec extends ExecBase { + "s={{width}}x{{height}}" + "\" -y {{{output.path}}}"; - @Override public void operate(KenBurnsOperation op, Toolbox toolbox, AssetManager assetManager) { + @Override public Map operate(KenBurnsOperation op, Toolbox toolbox, AssetManager assetManager) { final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JAsset source = opCtx.source; @@ -48,10 +48,10 @@ public class KenBurnsExec extends ExecBase { final File defaultOutfile = assetManager.assetPath(op, source, formatType); final File path = resolveOutputPath(output, defaultOutfile); - if (path == null) return; + if (path == null) return null; output.setPath(abs(path)); - final StandardJsEngine js = toolbox.getJs(); + final JsEngine js = toolbox.getJs(); final Map ctx = initialContext(toolbox, source); ctx.put("output", output); ctx.put("width", op.getWidth(ctx, js)); @@ -96,6 +96,7 @@ public class KenBurnsExec extends ExecBase { final String scriptOutput = exec(script, op.isNoExec()); log.debug("operate: command output: "+scriptOutput); assetManager.addOperationAsset(output); + return ctx; } } diff --git a/src/main/java/jvc/operation/exec/LetterboxExec.java b/src/main/java/jvc/operation/exec/LetterboxExec.java index f2444aa..43a95db 100644 --- a/src/main/java/jvc/operation/exec/LetterboxExec.java +++ b/src/main/java/jvc/operation/exec/LetterboxExec.java @@ -3,7 +3,7 @@ package jvc.operation.exec; import jvc.model.operation.JSingleOperationContext; import jvc.operation.LetterboxOperation; import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.util.javascript.StandardJsEngine; +import org.cobbzilla.util.javascript.JsEngine; import java.util.Map; @@ -33,7 +33,7 @@ public class LetterboxExec extends SingleOrMultiSourceExecBase ctx) { final JAsset audio = opCtx.assetManager.resolve(op.getInsert()); - final StandardJsEngine js = opCtx.toolbox.getJs(); + final JsEngine js = opCtx.toolbox.getJs(); final BigDecimal insertAt = op.getAt(ctx, js); ctx.put("start", insertAt); diff --git a/src/main/java/jvc/operation/exec/OverlayExec.java b/src/main/java/jvc/operation/exec/OverlayExec.java index 0945530..71b828e 100644 --- a/src/main/java/jvc/operation/exec/OverlayExec.java +++ b/src/main/java/jvc/operation/exec/OverlayExec.java @@ -7,7 +7,7 @@ import jvc.operation.OverlayOperation; import jvc.service.AssetManager; import jvc.service.Toolbox; import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.util.javascript.StandardJsEngine; +import org.cobbzilla.util.javascript.JsEngine; import java.io.File; import java.math.BigDecimal; @@ -24,7 +24,7 @@ public class OverlayExec extends ExecBase { + "[0:v][1v] overlay={{{overlayFilterConfig}}} " + "\" -y {{{output.path}}}"; - @Override public void operate(OverlayOperation op, Toolbox toolbox, AssetManager assetManager) { + @Override public Map operate(OverlayOperation op, Toolbox toolbox, AssetManager assetManager) { final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JAsset source = opCtx.source; @@ -36,10 +36,10 @@ public class OverlayExec extends ExecBase { final File defaultOutfile = assetManager.assetPath(op, source, formatType); final File path = resolveOutputPath(output, defaultOutfile); - if (path == null) return; + if (path == null) return null; output.setPath(abs(path)); - final StandardJsEngine js = toolbox.getJs(); + final JsEngine js = toolbox.getJs(); final Map ctx = initialContext(toolbox, source); ctx.put("overlay", overlaySource); @@ -58,6 +58,7 @@ public class OverlayExec extends ExecBase { final String scriptOutput = exec(script, op.isNoExec()); log.debug("operate: command output: "+scriptOutput); assetManager.addOperationAsset(output); + return ctx; } private String buildOverlayFilter(OverlayOperation op, @@ -65,7 +66,7 @@ public class OverlayExec extends ExecBase { JAsset overlaySource, OverlayOperation.OverlayConfig overlay, Map ctx, - StandardJsEngine js) { + JsEngine js) { final StringBuilder b = new StringBuilder(); final BigDecimal startTime = overlay.getStartTime(ctx, js); final BigDecimal endTime = overlay.hasEndTime() ? overlay.getEndTime(ctx, js) : overlaySource.duration(); diff --git a/src/main/java/jvc/operation/exec/ScaleExec.java b/src/main/java/jvc/operation/exec/ScaleExec.java index 16ae03d..4aaeb92 100644 --- a/src/main/java/jvc/operation/exec/ScaleExec.java +++ b/src/main/java/jvc/operation/exec/ScaleExec.java @@ -4,6 +4,7 @@ import jvc.model.JAsset; import jvc.model.operation.JSingleOperationContext; import jvc.operation.ScaleOperation; import lombok.extern.slf4j.Slf4j; +import org.cobbzilla.util.javascript.JsEngine; import org.cobbzilla.util.javascript.StandardJsEngine; import java.math.BigDecimal; @@ -22,7 +23,7 @@ public class ScaleExec extends SingleOrMultiSourceExecBase { @Override protected void addCommandContext(ScaleOperation op, JSingleOperationContext opCtx, Map ctx) { - final StandardJsEngine js = opCtx.toolbox.getJs(); + final JsEngine js = opCtx.toolbox.getJs(); final JAsset source = opCtx.source; if (op.hasFactor()) { final BigDecimal factor = op.getFactor(ctx, js); diff --git a/src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java b/src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java index 5cb616f..62929b5 100644 --- a/src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java +++ b/src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java @@ -17,19 +17,19 @@ import static org.cobbzilla.util.io.FileUtil.*; @Slf4j public abstract class SingleOrMultiSourceExecBase extends ExecBase { - @Override public void operate(OP op, Toolbox toolbox, AssetManager assetManager) { + @Override public Map operate(OP op, Toolbox toolbox, AssetManager assetManager) { final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JAsset source = opCtx.source; final JAsset output = opCtx.output; final JFileExtension formatType = opCtx.formatType; final Map ctx = initialContext(toolbox, source); addCommandContext(op, opCtx, ctx); - operate(op, toolbox, assetManager, source, output, formatType, ctx); + return operate(op, toolbox, assetManager, source, output, formatType, ctx); } protected void addCommandContext(OP op, JSingleOperationContext opCtx, Map ctx) {} - protected void operate(OP op, Toolbox toolbox, AssetManager assetManager, JAsset source, JAsset output, JFileExtension formatType, Map ctx) { + protected Map operate(OP op, Toolbox toolbox, AssetManager assetManager, JAsset source, JAsset output, JFileExtension formatType, Map ctx) { if (source.hasList()) { if (output.hasDest()) { if (!output.destIsDirectory()) die("operate: dest is not a directory: "+output.getDest()); @@ -43,7 +43,7 @@ public abstract class SingleOrMultiSourceExecBase { public static final String SPLIT_TEMPLATE = "{{ffmpeg}} -i {{{source.path}}} -ss {{startSeconds}} -t {{interval}} -y {{{output.path}}}"; - @Override public void operate(SplitOperation op, Toolbox toolbox, AssetManager assetManager) { + @Override public Map operate(SplitOperation op, Toolbox toolbox, AssetManager assetManager) { final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JAsset source = opCtx.source; @@ -49,7 +49,7 @@ public class SplitExec extends ExecBase { outfile = sliceFile(output, formatType, i, incr); } else { die("dest exists and is not a directory: "+output.getDest()); - return; + return null; } } } else { @@ -77,6 +77,7 @@ public class SplitExec extends ExecBase { assetManager.addOperationAssetSlice(output, slice); } log.info("operate: completed"); + return ctx; } private File sliceFile(JAsset output, JFileExtension formatType, BigDecimal i, BigDecimal incr) { diff --git a/src/main/java/jvc/operation/exec/TrimExec.java b/src/main/java/jvc/operation/exec/TrimExec.java index 7ae3c37..b41fd77 100644 --- a/src/main/java/jvc/operation/exec/TrimExec.java +++ b/src/main/java/jvc/operation/exec/TrimExec.java @@ -5,7 +5,7 @@ import jvc.operation.TrimOperation; import jvc.service.AssetManager; import jvc.service.Toolbox; import lombok.extern.slf4j.Slf4j; -import org.cobbzilla.util.javascript.StandardJsEngine; +import org.cobbzilla.util.javascript.JsEngine; import java.math.BigDecimal; import java.util.Map; @@ -28,7 +28,7 @@ public class TrimExec extends SingleOrMultiSourceExecBase { JAsset subOutput, Toolbox toolbox, AssetManager assetManager) { - final StandardJsEngine js = toolbox.getJs(); + final JsEngine js = toolbox.getJs(); final BigDecimal startTime = op.getStartTime(ctx, js); ctx.put("startSeconds", startTime); if (op.hasEndTime()) ctx.put("interval", op.getEndTime(ctx, js).subtract(startTime)); diff --git a/src/main/java/jvc/service/JOperationValidationFailure.java b/src/main/java/jvc/service/JOperationValidationFailure.java new file mode 100644 index 0000000..aa4994b --- /dev/null +++ b/src/main/java/jvc/service/JOperationValidationFailure.java @@ -0,0 +1,16 @@ +package jvc.service; + +import jvc.model.operation.JOperation; +import jvc.model.operation.JValidationResult; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@AllArgsConstructor +public class JOperationValidationFailure extends RuntimeException { + + @Getter private final JOperation operation; + @Getter private final List results; + +} diff --git a/src/main/java/jvc/service/JvcEngine.java b/src/main/java/jvc/service/JvcEngine.java index 2f2f5b9..3bf00b6 100644 --- a/src/main/java/jvc/service/JvcEngine.java +++ b/src/main/java/jvc/service/JvcEngine.java @@ -2,9 +2,16 @@ package jvc.service; import jvc.model.JSpec; import jvc.model.operation.JOperation; +import jvc.model.operation.JValidationResult; +import jvc.operation.exec.ExecBase; import lombok.Getter; +import org.cobbzilla.util.javascript.JsEngine; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; public class JvcEngine { @@ -12,6 +19,8 @@ public class JvcEngine { private final AssetManager assetManager; @Getter private final boolean noExec; + @Getter private final List completed = new ArrayList<>(); + public JvcEngine(Toolbox toolbox, AssetManager assetManager, boolean noExec) { this.toolbox = toolbox; this.assetManager = assetManager; @@ -24,7 +33,24 @@ public class JvcEngine { } private void runOp(JOperation op) { - op.setNoExec(noExec).getExec().operate(op, toolbox, assetManager); + + final ExecBase exec = op + .setExecIndex(completed.size()) + .setNoExec(noExec) + .getExec(); + final Map ctx = exec.operate(op, toolbox, assetManager); + + if (op.hasValidate()) { + final JsEngine js = toolbox.getJs(); + final List results = Arrays.stream(op.getValidate()) + .map(v -> v.eval(ctx, js)) + .collect(Collectors.toList()); + if (results.stream().anyMatch(JValidationResult::failed)) { + throw new JOperationValidationFailure(op, results); + } + } + + completed.add(op); } } diff --git a/src/main/java/jvc/service/Toolbox.java b/src/main/java/jvc/service/Toolbox.java index 173cb85..a5960c6 100644 --- a/src/main/java/jvc/service/Toolbox.java +++ b/src/main/java/jvc/service/Toolbox.java @@ -39,7 +39,7 @@ public class Toolbox { @Getter(lazy=true) private final Handlebars handlebars = initHandlebars(); - @Getter(lazy=true) private final StandardJsEngine js = new StandardJsEngine(); + @Getter(lazy=true) private final JsEngine js = new StandardJsEngine(); public static String eval(String val, Map ctx, JsEngine js) { final Map jsCtx = Toolbox.jsContext(ctx); @@ -51,6 +51,15 @@ public class Toolbox { } } + public static boolean evalBoolean(String val, Map ctx, JsEngine js) { + final Map jsCtx = Toolbox.jsContext(ctx); + try { + return js.evaluateBoolean(val, jsCtx); + } catch (Exception e) { + return die("eval: error evaluating: '"+val+"': "+shortError(e)); + } + } + public static BigDecimal evalBig(String val, Map ctx, JsEngine js) { return big(eval(val, ctx, js)); } diff --git a/src/test/resources/tests/test_add_silence.jvc b/src/test/resources/tests/test_add_silence.jvc index 3c83010..bf895fa 100644 --- a/src/test/resources/tests/test_add_silence.jvc +++ b/src/test/resources/tests/test_add_silence.jvc @@ -14,7 +14,11 @@ "creates": "v2", "source": "vid2", "start": "10", - "end": "30" + "end": "30", + "validate": [{ + "comment": "expect output to be about 20 seconds long, give or take 0.1 seconds", + "test": "is_within(output.duration, 20, 0.1)" + }] }, // create 20 seconds of silent audio, combine with input video, produce silent video output. { @@ -22,7 +26,11 @@ "creates": "v2_silent", // output asset name "source": "v2", // main video asset "channelLayout": "stereo", // optional channel layout, usually 'mono' or 'stereo'. Default is 'stereo' - "samplingRate": 48000 // optional sampling rate, in Hz. default is 48000 + "samplingRate": 48000, // optional sampling rate, in Hz. default is 48000 + "validate": [{ + "comment": "expect output to be about 20 seconds long, give or take 0.1 seconds", + "test": "is_within(output.duration, 20, 0.1)" + }] } ] } diff --git a/utils/cobbzilla-utils b/utils/cobbzilla-utils index 8cdea3a..f87d3b7 160000 --- a/utils/cobbzilla-utils +++ b/utils/cobbzilla-utils @@ -1 +1 @@ -Subproject commit 8cdea3ac79f5d890ba765665624c981990076c98 +Subproject commit f87d3b74f46775143dfffd2182e43eb91f94a0b7