blob: aef3299d129732d28b39e0b2ba4592338eba8131 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library barback.test.package_graph.declaring_transformer_test;
import 'package:barback/src/utils.dart';
import 'package:scheduled_test/scheduled_test.dart';
import '../utils.dart';
main() {
initConfig();
test("gets a declared output with a different path", () {
initGraph([
"app|foo.blub"
], {
"app": [
[new DeclaringRewriteTransformer("blub", "blab")]
]
});
updateSources(["app|foo.blub"]);
expectAsset("app|foo.blab", "foo.blab");
buildShouldSucceed();
});
test("gets a declared output with the same path", () {
initGraph([
"app|foo.blub"
], {
"app": [
[new DeclaringRewriteTransformer("blub", "blub")]
]
});
updateSources(["app|foo.blub"]);
expectAsset("app|foo.blub", "foo.blub");
buildShouldSucceed();
});
test("gets a passed-through asset", () {
initGraph([
"app|foo.blub"
], {
"app": [
[new DeclaringRewriteTransformer("blub", "blab")]
]
});
updateSources(["app|foo.blub"]);
expectAsset("app|foo.blub", "foo");
buildShouldSucceed();
});
test("doesn't get a consumed asset", () {
initGraph([
"app|foo.blub"
], {
"app": [
[new DeclaringRewriteTransformer("blub", "blab")..consumePrimary = true]
]
});
updateSources(["app|foo.blub"]);
expectNoAsset("app|foo.blub");
buildShouldSucceed();
});
test("gets a passed-through asset before apply is finished", () {
var transformer = new DeclaringRewriteTransformer("blub", "blab");
initGraph([
"app|foo.blub"
], {
"app": [
[transformer]
]
});
transformer.pauseApply();
updateSources(["app|foo.blub"]);
expectAsset("app|foo.blub", "foo");
transformer.resumeApply();
buildShouldSucceed();
});
test("fails to get a consumed asset before apply is finished", () {
var transformer = new DeclaringRewriteTransformer("blub", "blab")
..consumePrimary = true;
initGraph([
"app|foo.blub"
], {
"app": [
[transformer]
]
});
transformer.pauseApply();
updateSources(["app|foo.blub"]);
expectNoAsset("app|foo.blub");
transformer.resumeApply();
buildShouldSucceed();
});
test("blocks on getting a declared asset that wasn't generated last run", () {
var transformer = new DeclaringCheckContentAndRenameTransformer(
oldExtension: "txt",
oldContent: "yes",
newExtension: "out",
newContent: "done");
initGraph({
"app|foo.txt": "no"
}, {
"app": [
[transformer]
]
});
updateSources(["app|foo.txt"]);
expectNoAsset("app|foo.out");
buildShouldSucceed();
// The transform should remember that foo.out was declared, so it should
// expect that it might still be generated even though it wasn't last time.
transformer.pauseApply();
modifyAsset("app|foo.txt", "yes");
updateSources(["app|foo.txt"]);
expectAssetDoesNotComplete("app|foo.out");
transformer.resumeApply();
expectAsset("app|foo.out", "done");
buildShouldSucceed();
});
test(
"doesn't block on on getting an undeclared asset that wasn't generated "
"last run", () {
var transformer = new DeclaringCheckContentAndRenameTransformer(
oldExtension: "txt",
oldContent: "yes",
newExtension: "out",
newContent: "done");
initGraph({
"app|foo.txt": "no"
}, {
"app": [
[transformer]
]
});
updateSources(["app|foo.txt"]);
expectNoAsset("app|foo.out");
buildShouldSucceed();
transformer.pauseApply();
modifyAsset("app|foo.txt", "yes");
updateSources(["app|foo.txt"]);
expectNoAsset("app|undeclared.out");
transformer.resumeApply();
buildShouldSucceed();
});
test(
"fails to get a consumed asset before apply is finished when a sibling "
"has finished applying", () {
var transformer = new DeclaringRewriteTransformer("blub", "blab")
..consumePrimary = true;
initGraph([
"app|foo.blub",
"app|foo.txt"
], {
"app": [
[transformer, new RewriteTransformer("txt", "out")]
]
});
transformer.pauseApply();
updateSources(["app|foo.blub", "app|foo.txt"]);
expectAsset("app|foo.out", "foo.out");
expectNoAsset("app|foo.blub");
transformer.resumeApply();
buildShouldSucceed();
});
test(
"blocks getting a consumed asset before apply is finished when a "
"sibling hasn't finished applying", () {
var declaring = new DeclaringRewriteTransformer("blub", "blab")
..consumePrimary = true;
var eager = new RewriteTransformer("txt", "out");
initGraph([
"app|foo.blub",
"app|foo.txt"
], {
"app": [
[declaring, eager]
]
});
declaring.pauseApply();
eager.pauseApply();
updateSources(["app|foo.blub", "app|foo.txt"]);
expectAssetDoesNotComplete("app|foo.blub");
declaring.resumeApply();
eager.resumeApply();
expectNoAsset("app|foo.blub");
buildShouldSucceed();
});
test("waits until apply is finished to get an overwritten asset", () {
var transformer = new DeclaringRewriteTransformer("blub", "blub");
initGraph([
"app|foo.blub"
], {
"app": [
[transformer]
]
});
transformer.pauseApply();
updateSources(["app|foo.blub"]);
expectAssetDoesNotComplete("app|foo.blub");
transformer.resumeApply();
expectAsset("app|foo.blub", "foo.blub");
buildShouldSucceed();
});
// Regression test for #64.
test("a declaring transformer's output passes through a lazy transformer",
() {
var declaring = new DeclaringRewriteTransformer("one", "two");
initGraph([
"app|foo.one"
], {
"app": [
[declaring],
[new LazyRewriteTransformer("two", "three")]
]
});
updateSources(["app|foo.one"]);
// Give the transformers time to declare their assets.
schedule(pumpEventQueue);
expectAsset("app|foo.one", "foo");
expectAsset("app|foo.two", "foo.two");
expectAsset("app|foo.three", "foo.two.three");
buildShouldSucceed();
modifyAsset("app|foo.one", "bar");
updateSources(["app|foo.one"]);
expectAsset("app|foo.one", "bar");
expectAsset("app|foo.two", "bar.two");
expectAsset("app|foo.three", "bar.two.three");
buildShouldSucceed();
expect(declaring.numRuns, completion(equals(2)));
});
test(
"a declaring transformer following a lazy transformer runs eagerly once "
"its input is available", () {
var declaring = new DeclaringRewriteTransformer("two", "three");
initGraph([
"app|foo.in"
], {
"app": [
[
new LazyAssetsTransformer(["app|out.one", "app|out.two"])
],
[declaring]
]
});
updateSources(["app|foo.in"]);
// Give the transformers time to declare their assets.
schedule(pumpEventQueue);
expectAsset("app|out.one", "app|out.one");
buildShouldSucceed();
expect(declaring.numRuns, completion(equals(1)));
});
test(
"a declaring transformer following a lazy transformer doesn't re-run if "
"its input becomes available and then unavailable", () {
var declaring = new DeclaringRewriteTransformer("two", "three");
initGraph([
"app|foo.in"
], {
"app": [
[
new LazyAssetsTransformer(["app|out.one", "app|out.two"])
],
[declaring]
]
});
declaring.pauseApply();
updateSources(["app|foo.in"]);
// Give the transformers time to declare their assets.
schedule(pumpEventQueue);
// Start [declaring] running, because its input became available.
expectAsset("app|out.one", "app|out.one");
// Make sure we're blocking on [declaring.apply].
schedule(pumpEventQueue);
// Now [declaring]'s input is dirty, so it shouldn't re-run without an
// explicit request.
updateSources(["app|foo.in"]);
declaring.resumeApply();
buildShouldSucceed();
// [declaring] should only have run once, despite its input changing. After
// the first run, it should be awaiting a force() call.
expect(declaring.numRuns, completion(equals(1)));
// Once we make a request, [declaring] should force the lazy transformer and
// then run itself.
expectAsset("app|out.three", "app|out.two.three");
buildShouldSucceed();
// Now [declaring] should have run twice. This ensures that it didn't use
// its original output for some reason.
expect(declaring.numRuns, completion(equals(2)));
});
test(
"a declaring transformer following a lazy transformer does re-run if "
"its input becomes available, it's forced, and then its input becomes "
"unavailable", () {
var declaring = new DeclaringRewriteTransformer("two", "three");
initGraph([
"app|foo.in"
], {
"app": [
[
new LazyAssetsTransformer(["app|out.one", "app|out.two"])
],
[declaring]
]
});
declaring.pauseApply();
updateSources(["app|foo.in"]);
// Give the transformers time to declare their assets.
schedule(pumpEventQueue);
// Start [declaring] running, because its input became available.
expectAsset("app|out.one", "app|out.one");
// This shouldn't complete because [declaring.apply] is paused, but it
// should force the transformer.
expectAssetDoesNotComplete("app|out.three");
// Make sure we're blocking on [declaring.apply]
schedule(pumpEventQueue);
// Now [declaring]'s input is dirty, so it shouldn't re-run without an
// explicit request.
updateSources(["app|foo.in"]);
declaring.resumeApply();
buildShouldSucceed();
// [declaring] should have run twice, once for its original input and once
// after the input changed because it was forced.
expect(declaring.numRuns, completion(equals(2)));
});
group("with an error in declareOutputs", () {
test("still runs apply", () {
initGraph([
"app|foo.txt"
], {
"app": [
[
new DeclaringBadTransformer("app|out.txt",
declareError: true, applyError: false)
]
]
});
updateSources(["app|foo.txt"]);
expectAsset("app|out.txt", "bad out");
expectAsset("app|foo.txt", "foo");
buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
});
test(
"waits for apply to complete before passing through the input even if "
"consumePrimary was called", () {
var transformer = new DeclaringBadTransformer("app|out.txt",
declareError: true, applyError: false)
..consumePrimary = true;
initGraph([
"app|foo.txt"
], {
"app": [
[transformer]
]
});
transformer.pauseApply();
updateSources(["app|foo.txt"]);
expectAssetDoesNotComplete("app|out.txt");
expectAssetDoesNotComplete("app|foo.txt");
transformer.resumeApply();
expectAsset("app|out.txt", "bad out");
expectNoAsset("app|foo.txt");
buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
});
});
test("with an error in apply still passes through the input", () {
initGraph([
"app|foo.txt"
], {
"app": [
[
new DeclaringBadTransformer("app|out.txt",
declareError: false, applyError: true)
]
]
});
updateSources(["app|foo.txt"]);
expectNoAsset("app|out.txt");
expectAsset("app|foo.txt", "foo");
buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
});
test("can emit outputs it didn't declare", () {
initGraph([
"app|foo.txt"
], {
"app": [
[
new DeclareAssetsTransformer([], emitted: ["app|out.txt"])
]
]
});
updateSources(["app|foo.txt"]);
// There's probably going to be some time when "out.txt" is unavailable,
// since it was undeclared.
schedule(pumpEventQueue);
expectAsset("app|out.txt", "app|out.txt");
buildShouldSucceed();
});
test("can overwrite the primary input even if it declared that it wouldn't",
() {
var transformer =
new DeclareAssetsTransformer([], emitted: ["app|foo.txt"]);
initGraph([
"app|foo.txt"
], {
"app": [
[transformer]
]
});
transformer.pauseApply();
updateSources(["app|foo.txt"]);
expectAsset("app|foo.txt", "foo");
transformer.resumeApply();
schedule(pumpEventQueue);
expectAsset("app|foo.txt", "app|foo.txt");
buildShouldSucceed();
});
test("can declare outputs it doesn't emit", () {
initGraph([
"app|foo.txt"
], {
"app": [
[
new DeclareAssetsTransformer(["app|out.txt"], emitted: [])
]
]
});
updateSources(["app|foo.txt"]);
expectNoAsset("app|out.txt");
buildShouldSucceed();
});
}