Skip to content

Commit

Permalink
FLUID-5818: Fix for failure of ginger reference from constructed chil…
Browse files Browse the repository at this point in the history
…d of unconstructed parent. Also, moved over to now-standard Kettle syntax for %moduleName references from fluid.require and resolve
  • Loading branch information
amb26 committed Nov 12, 2015
1 parent 23efd08 commit 3c8dce0
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 22 deletions.
4 changes: 3 additions & 1 deletion src/framework/core/js/Fluid.js
Expand Up @@ -2531,7 +2531,9 @@ var fluid = fluid || fluid_2_0_0;
(error.componentSource ? " which was defined in grade " + error.componentSource : "") + " needs to be overridden with a concrete implementation");
})).join("\n");
}
that.lifecycleStatus = "constructed";
if (that.lifecycleStatus === "constructing") {
that.lifecycleStatus = "constructed";
}
that.events.onCreate.fire(that);
fluid.popActivity();
return that;
Expand Down
33 changes: 31 additions & 2 deletions src/framework/core/js/FluidIoC.js
Expand Up @@ -735,6 +735,8 @@ var fluid_2_0_0 = fluid_2_0_0 || {};
// distributions, collectedClearer: Managing options distributions
// subcomponentLocal: Signalling local record from computeDynamicComponents to assembleCreatorArguments
// dynamicLocal: Local signalling for dynamic grades
// ownScope: A hash of names to components which are in scope from this component - populated in cacheShadowGrades
// childrenScope: A hash of names to components which are in scope because they are children of this component (BELOW own ownScope in resolution order)

fluid.shadowForComponent = function (component) {
var instantiator = fluid.getInstantiator(component);
Expand Down Expand Up @@ -1394,9 +1396,36 @@ var fluid_2_0_0 = fluid_2_0_0 || {};
if (shadow.subcomponentLocal) {
fluid.clear(shadow.subcomponentLocal); // still need repo for event-driven dynamic components - abolish these in time
}
that.lifecycleStatus = "constructed";
fluid.assessTreeConstruction(that, shadow);

fluid.popActivity();
};

fluid.assessTreeConstruction = function (that, shadow) {
var instantiator = fluid.globalInstantiator;
var thatStack = instantiator.getThatStack(that);
var unstableUp = fluid.find_if(thatStack, function (that) {
return that.lifecycleStatus === "constructing";
});
if (unstableUp) {
that.lifecycleStatus = "constructed";
} else {
fluid.markSubtree(instantiator, that, shadow.path, "treeConstructed");
}
};

fluid.markSubtree = function (instantiator, that, path, state) {
that.lifecycleStatus = state;
fluid.visitComponentChildren(that, function (child, name) {
var childPath = instantiator.composePath(path, name);
var childShadow = instantiator.idToShadow[child.id];
var created = childShadow && childShadow.path === childPath;
if (created) {
fluid.markSubtree(instantiator, child, childPath, state);
}
}, {flat: true});
};


/** BEGIN NEXUS METHODS **/
Expand Down Expand Up @@ -2296,10 +2325,10 @@ var fluid_2_0_0 = fluid_2_0_0 || {};
var localRecord = options.localRecord, context = source.expander.context, segs = source.expander.segs;
var inLocal = localRecord[context] !== undefined;
// somewhat hack to anticipate "fits" for FLUID-4925 - we assume that if THIS component is in construction, its reference target might be too
var component = inLocal ? localRecord[context] : fluid.resolveContext(context, options.contextThat, options.contextThat.lifecycleStatus === "constructed");
var component = inLocal ? localRecord[context] : fluid.resolveContext(context, options.contextThat, options.contextThat.lifecycleStatus === "treeConstructed");
if (component) {
var root = component;
if (inLocal || component.lifecycleStatus === "constructed") {
if (inLocal || component.lifecycleStatus === "constructed" || component.lifecycleStatus === "treeConstructed") {
for (var i = 0; i < segs.length; ++ i) {
root = root ? root[segs[i]] : undefined;
}
Expand Down
28 changes: 12 additions & 16 deletions src/module/module.js
Expand Up @@ -79,26 +79,22 @@ fluid.module.canonPath = function (path) {
return path.replace(/\\/g, "/");
};

fluid.module.getDirs = function () {
return fluid.getMembers(fluid.module.modules, "baseDir");
};

// A suitable set of terms for interpolating module root paths into dataSource file paths
fluid.module.terms = function () {
return fluid.module.getDirs();
};

/** Resolve a path expression which may begin with a module reference of the form,
* say, ${module-name}, into an absolute path relative to that module, using the
* say, %moduleName, into an absolute path relative to that module, using the
* database of base directories registered previously with fluid.module.register.
* If the path does not begin with such a module reference, it is returned unchanged.
*/

fluid.module.resolvePath = function (path) {
if (path.indexOf("${") === 0) {
var ic = path.indexOf("}");
if (ic === -1) {
fluid.fail("Malformed context path without }: ", path);
} else {
var context = path.substring(2, ic);
var record = fluid.module.modules[context];
if (!record) {
fluid.fail("Unrecognised module " + context + ": loaded modules are " + fluid.keys(fluid.module.modules).join(", "));
}
return record.baseDir + path.substring(ic + 1);
}
} else {
return path;
}
return fluid.stringTemplate(path, fluid.module.getDirs());
};

42 changes: 42 additions & 0 deletions tests/framework-tests/core/js/FluidIoCTests.js
Expand Up @@ -1323,6 +1323,48 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
jqUnit.assertEquals("Resolved injected component by member name", that.chaundleTileManager, resolved);
});

/** FLUID-5818 - ginger reference from distant construct descendent of incomplete parent **/

fluid.defaults("fluid.tests.FLUID5818root", {
gradeNames: "fluid.component",
components: {
child1: {
type: "fluid.component",
options: {
components: {
child3: {
type: "fluid.component",
options: {
listeners: {
onCreate: {
funcName: "fluid.tests.fluid5818fetch",
args: "{child2}"
}
}
}
}
}
}
},
child2: {
type: "fluid.component"
}

}
});

fluid.tests.fluid5818fetch = function (child2) {
jqUnit.assertValue("Should have caused fetch of child of unconstructed parent", child2);
};

jqUnit.test("FLUID-5818 ginger reference to child of unconstructed parent", function () {
jqUnit.expect(5);
var that = fluid.tests.FLUID5818root();
// White-box testing of lifecycle status
fluid.each([that, that.child1, that.child2, that.child1.child3], function (component) {
jqUnit.assertEquals("All components should have \"treeConstructed\" state", "treeConstructed", component.lifecycleStatus);
});
});

/** FLUID-4135 - event injection and boiling test **/

Expand Down
4 changes: 2 additions & 2 deletions tests/node-tests/basic-node-tests.js
Expand Up @@ -89,11 +89,11 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
});

jqUnit.test("Test module resolvePath", function () {
var resolved = fluid.module.resolvePath("${infusion}/src/components/tableOfContents/html/TableOfContents.html");
var resolved = fluid.module.resolvePath("%infusion/src/components/tableOfContents/html/TableOfContents.html");
var expected = fluid.module.canonPath(path.resolve(__dirname, "../../src/components/tableOfContents/html/TableOfContents.html"));
jqUnit.assertEquals("Resolved path into infusion module", expected, resolved);

var pkg = fluid.require("${test-module}/package.json");
var pkg = fluid.require("%test-module/package.json");
jqUnit.assertEquals("Loaded package.json via resolved path directly via fluid.require", "test-module", pkg.name);
});

Expand Down
2 changes: 1 addition & 1 deletion tests/test-core/utils/js/IoCTestUtils.js
Expand Up @@ -375,7 +375,7 @@ var fluid_2_0_0 = fluid_2_0_0 || {};
namespace: fixture.namespace,
priority: fixture.priority
});
id = fluid.pushDistributions(analysed.head, analysed.selector,
id = fluid.pushDistributions(analysed.head, analysed.selector, fixture.event,
[{options: options, recordType: "distribution", priority: fluid.mergeRecordTypes.distribution}]
);
};
Expand Down

0 comments on commit 3c8dce0

Please sign in to comment.