Skip to content

Commit

Permalink
Merge branch 'master' into FLUID-5599
Browse files Browse the repository at this point in the history
  • Loading branch information
cindyli committed Apr 30, 2015
2 parents a72a3c7 + c0c1716 commit 85c2066
Show file tree
Hide file tree
Showing 14 changed files with 595 additions and 59 deletions.
12 changes: 5 additions & 7 deletions src/framework/core/js/DataBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ var fluid_2_0 = fluid_2_0 || {};
fluid.each(transRec, function (value, key) {
if (typeof(value) === "number") {
transRec[key] = 0;
} else if (relaysAlso && value.options && typeof(value.options.relayCount) === "number") {
value.options.relayCount = 0;
} else if (relaysAlso && value.options && typeof(value.relayCount) === "number") {
value.relayCount = 0;
}
});
};
Expand Down Expand Up @@ -468,7 +468,7 @@ var fluid_2_0 = fluid_2_0 || {};
++transRec[linkId];
if (!existing) {
var newTrans = targetApplier.initiate("relay", transId); // non-top-level transaction will defeat postCommit
existing = transRec[applierId] = {transaction: newTrans, options: options};
existing = transRec[applierId] = {transaction: newTrans, relayCount: 0, options: options};
}
if (transducer && !options.targetApplier) {
// TODO: This is just for safety but is still unusual and now abused. The transducer doesn't need the "newValue" since all the transform information
Expand Down Expand Up @@ -521,7 +521,6 @@ var fluid_2_0 = fluid_2_0 || {};
fluid.registerDirectChangeRelay(source, sourceSegs, target, targetSegs, linkId, null, {
transactional: false,
targetApplier: options.targetApplier,
relayCount: options.relayCount,
update: options.update
});
} else {
Expand Down Expand Up @@ -584,7 +583,6 @@ var fluid_2_0 = fluid_2_0 || {};
}
that.update = that.invalidator.fire; // necessary so that both routes to fluid.connectModelRelay from here hit the first branch
var implicitOptions = {
relayCount: 0, // this count is updated in fluid.model.updateRelays
targetApplier: that.forwardApplier, // this special field identifies us to fluid.connectModelRelay
update: that.update,
refCount: 0
Expand Down Expand Up @@ -702,8 +700,8 @@ var fluid_2_0 = fluid_2_0 || {};
fluid.each(transRec, function (transEl) {
// TODO: integrate the "source" if any into this computation, and fire the relay if it has changed - perhaps by adding a listener
// to it that updates changeRecord.changes (assuming we can find it)
if (transEl.options && transEl.transaction && transEl.transaction.changeRecord.changes > 0 && transEl.options.relayCount < 2 && transEl.options.update) {
transEl.options.relayCount++;
if (transEl.options && transEl.transaction && transEl.transaction.changeRecord.changes > 0 && transEl.relayCount < 2 && transEl.options.update) {
transEl.relayCount++;
fluid.clearLinkCounts(transRec);
transEl.options.update(transEl.transaction, transRec);
++updates;
Expand Down
23 changes: 23 additions & 0 deletions src/framework/core/js/Fluid.js
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,21 @@ var fluid = fluid || fluid_2_0;
});
return togo;
};

/** Converts an array consisting of a mixture of arrays and non-arrays into the concatenation of any inner arrays
* with the non-array elements
*/
fluid.flatten = function (array) {
var togo = [];
fluid.each(array, function (element) {
if (fluid.isArrayable(element)) {
togo = togo.concat(element);
} else {
togo.push(element);
}
});
return togo;
};

/**
* Clears an object or array of its contents. For objects, each property is deleted.
Expand Down Expand Up @@ -712,6 +727,14 @@ var fluid = fluid || fluid_2_0;
};
};

/**
* Returns the converted integer if the input string can be converted to an integer. Otherwise, return NaN.
* @param {String} a string to be returned in integer
*/
fluid.parseInteger = function (string) {
return isFinite(string) && ((string % 1) === 0) ? Number(string) : NaN;
};

fluid.logLevelsSpec = {
"FATAL": 0,
"FAIL": 5,
Expand Down
6 changes: 1 addition & 5 deletions src/framework/core/js/FluidIoC.js
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ var fluid_2_0 = fluid_2_0 || {};
instantiator.clearComponent(that, "", that, null, true);
};
};

// NON-API function
fluid.fabricateDestroyMethod = function (that, name, instantiator, child) {
return function () {
Expand Down Expand Up @@ -1578,10 +1578,6 @@ outer: for (var i = 0; i < exist.length; ++i) {

var argPrefix = "{arguments}.";

fluid.parseInteger = function (string) {
return isFinite(string) && ((string % 1) === 0) ? Number(string) : NaN;
};

fluid.makeFastInvoker = function (invokeSpec, func) {
var argMap;
if (invokeSpec.preExpand) {
Expand Down
57 changes: 53 additions & 4 deletions src/framework/core/js/ModelTransformationTransforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,14 +209,12 @@ var fluid = fluid || fluid_2_0;
return inputs[condition ? "true" : "false"]();
};


fluid.defaults("fluid.transforms.valueMapper", {
gradeNames: ["fluid.transformFunction", "fluid.lens"],
invertConfiguration: "fluid.transforms.valueMapper.invert",
collectInputPaths: "fluid.transforms.valueMapper.collect"
});


// unsupported, NON-API function
fluid.model.transform.compareMatches = function (speca, specb) {
return specb.matchValue - speca.matchValue;
Expand Down Expand Up @@ -591,12 +589,63 @@ var fluid = fluid || fluid_2_0;
};

fluid.defaults("fluid.transforms.indexOf", {
gradeNames: "fluid.standardTransformFunction"
gradeNames: ["fluid.standardTransformFunction", "fluid.lens"],
invertConfiguration: "fluid.transforms.indexOf.invert"
});

fluid.transforms.indexOf = function (value, transformSpec) {
var offset = fluid.transforms.parseIndexationOffset(transformSpec.offset, "indexOf");
var array = fluid.makeArray(transformSpec.array);
return array.indexOf(value);
var originalIndex = array.indexOf(value);
return originalIndex === -1 && transformSpec.notFound ? transformSpec.notFound : originalIndex + offset;
};

fluid.transforms.indexOf.invert = function (transformSpec, transformer) {
var togo = fluid.transforms.invertArrayIndexation(transformSpec, transformer);
togo.type = "fluid.transforms.dereference";
return togo;
};

fluid.defaults("fluid.transforms.dereference", {
gradeNames: ["fluid.standardTransformFunction", "fluid.lens"],
invertConfiguration: "fluid.transforms.dereference.invert"
});

fluid.transforms.dereference = function (value, transformSpec) {
if (typeof (value) !== "number") {
fluid.fail("dereference requires \"value\" to be a number. " + value + " is invalid.");
}
var offset = fluid.transforms.parseIndexationOffset(transformSpec.offset, "dereference");
var array = fluid.makeArray(transformSpec.array);
var index = value + offset;
return index === -1 && transformSpec.notFound ? transformSpec.notFound : array[index];
};

fluid.transforms.dereference.invert = function (transformSpec, transformer) {
var togo = fluid.transforms.invertArrayIndexation(transformSpec, transformer);
togo.type = "fluid.transforms.indexOf";
return togo;
};

fluid.transforms.parseIndexationOffset = function (offset, transformName) {
var parsedOffset = 0;
if (offset !== undefined) {
parsedOffset = fluid.parseInteger(offset);
if (isNaN(parsedOffset)) {
fluid.fail(transformName + " requires the value of \"offset\" to be an integer or a string that can be converted to an integer. " + offset + " is invalid.");
}
}
return parsedOffset;
};

fluid.transforms.invertArrayIndexation = function (transformSpec, transformer) {
var togo = fluid.copy(transformSpec);
togo.inputPath = fluid.model.composePaths(transformer.outputPrefix, transformSpec.outputPath);
togo.outputPath = fluid.model.composePaths(transformer.inputPrefix, transformSpec.inputPath);
if (!isNaN(Number(togo.offset))) {
togo.offset = Number(togo.offset) * (-1);
}
return togo;
};

fluid.defaults("fluid.transforms.free", {
Expand Down
6 changes: 4 additions & 2 deletions src/framework/preferences/js/AuxBuilder.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2013 OCAD University
Copyright 2013-2015 OCAD University
Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Expand All @@ -23,7 +23,9 @@ var fluid_2_0 = fluid_2_0 || {};

fluid.defaults("fluid.prefs.auxSchema", {
gradeNames: ["fluid.littleComponent", "autoInit"],
auxiliarySchema: {}
auxiliarySchema: {
"loaderGrades": ["fluid.prefs.separatedPanel"]
}
});

/**
Expand Down
17 changes: 11 additions & 6 deletions src/framework/preferences/js/Builder.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2013 OCAD University
Copyright 2013-2015 OCAD University
Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Expand Down Expand Up @@ -27,7 +27,8 @@ var fluid_2_0 = fluid_2_0 || {};
func: "fluid.prefs.builder.generateGrade",
args: ["prefsEditor", "{that}.options.auxSchema.namespace", {
gradeNames: ["fluid.viewRelayComponent", "autoInit", "fluid.prefs.assembler.prefsEd"],
componentGrades: "{that}.options.constructedGrades"
componentGrades: "{that}.options.constructedGrades",
loaderGrades: "{that}.options.auxSchema.loaderGrades"
}]
}
},
Expand Down Expand Up @@ -119,8 +120,12 @@ var fluid_2_0 = fluid_2_0 || {};
container: "{fluid.prefs.assembler.prefsEd}.container",
priority: "last",
options: {
gradeNames: ["{fluid.prefs.assembler.prefsEd}.options.componentGrades.templatePrefix", "{fluid.prefs.assembler.prefsEd}.options.componentGrades.messagePrefix", "{fluid.prefs.assembler.prefsEd}.options.componentGrades.messages", "{that}.options.prefsEditorType"],
prefsEditorType: "fluid.prefs.separatedPanel",
gradeNames: [
"{fluid.prefs.assembler.prefsEd}.options.componentGrades.templatePrefix",
"{fluid.prefs.assembler.prefsEd}.options.componentGrades.messagePrefix",
"{fluid.prefs.assembler.prefsEd}.options.componentGrades.messages",
"{that}.options.loaderGrades"
],
templateLoader: {
gradeNames: ["{fluid.prefs.assembler.prefsEd}.options.componentGrades.templateLoader"]
},
Expand All @@ -147,9 +152,9 @@ var fluid_2_0 = fluid_2_0 || {};
}
},
distributeOptions: [{
source: "{that}.options.prefsEditorType",
source: "{that}.options.loaderGrades",
removeSource: true,
target: "{that > prefsEditorLoader}.options.prefsEditorType"
target: "{that > prefsEditorLoader}.options.loaderGrades"
}, {
source: "{that}.options.prefsEditor",
removeSource: true,
Expand Down
3 changes: 2 additions & 1 deletion src/framework/preferences/js/StarterSchemas.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2013 OCAD University
Copyright 2013-2015 OCAD University
Licensed under the Educational Community License (ECL), Version 2.0 or the New
BSD license. You may not use this file except in compliance with one these
Expand All @@ -24,6 +24,7 @@ var fluid_2_0 = fluid_2_0 || {};
fluid.defaults("fluid.prefs.auxSchema.starter", {
gradeNames: ["fluid.prefs.auxSchema", "autoInit"],
auxiliarySchema: {
"loaderGrades": ["fluid.prefs.separatedPanel"],
"namespace": "fluid.prefs.constructed", // The author of the auxiliary schema will provide this and will be the component to call to initialize the constructed PrefsEditor.
"templatePrefix": "../../framework/preferences/html/", // The common path to settings panel templates. The template defined in "panels" element will take precedence over this definition.
"template": "%prefix/SeparatedPanelPrefsEditor.html",
Expand Down
1 change: 1 addition & 0 deletions tests/framework-tests/core/html/DataBinding-test.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<!-- These are the jqUnit test js files -->
<script type="text/javascript" src="../../../lib/qunit/js/qunit.js"></script>
<script type="text/javascript" src="../../../test-core/jqUnit/js/jqUnit.js"></script>
<script type="text/javascript" src="../../../test-core/utils/js/IoCTestUtils.js"></script>

<!-- These are tests that have been written using this page as data -->
<script type="text/javascript" src="../js/DataBindingTests.js"></script>
Expand Down
100 changes: 100 additions & 0 deletions tests/framework-tests/core/js/DataBindingTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2014,4 +2014,104 @@ https://github.com/fluid-project/infusion/raw/master/Infusion-LICENSE.txt
jqUnit.assertNoValue("The change request has destroyed the child component", that.child);
});

// FLUID-5659: Saturating relay counts through back-to-back transactions

fluid.defaults("fluid.tests.fluid5659relay", {
gradeNames: ["fluid.modelRelayComponent", "autoInit"],
model: {
lang: "none"
},
lang: ["en", "fr", "es", "de", "ne", "sv"],
modelRelay: [{
target: "langIndex",
singleTransform: {
type: "fluid.transforms.indexOf",
array: "{that}.options.lang",
value: "{that}.model.lang",
offset: 1
}
}, {
target: "firstLangSelected",
singleTransform: {
type: "fluid.transforms.binaryOp",
left: "{that}.model.langIndex",
operator: "===",
right: 1
}
}, {
target: "lastLangSelected",
singleTransform: {
type: "fluid.transforms.binaryOp",
left: "{that}.model.langIndex",
operator: "===",
right: "{that}.options.lang.length"
}
}]
});

fluid.defaults("fluid.tests.fluid5659root", {
gradeNames: ["fluid.test.testEnvironment", "autoInit"],
components: {
relayComponent: {
type: "fluid.tests.fluid5659relay"
},
testCaseHolder: {
type: "fluid.test.testCaseHolder",
options: {
moduleSource: {
funcName: "fluid.tests.fluid5659source",
args: "{fluid5659relay}.options.lang"
}
}
}
}
});

fluid.tests.fluid5659modules = {
name: "FLUID-5659 repeated relay test",
tests: {
name: "relay test",
expect: 1,
sequence: []
}
};

fluid.tests.fluid5659verify = function (model, langs, lang) {
var index = langs.indexOf(lang) + 1;
var firstLangSelected = index === 1;
var lastLangSelected = index === langs.length;
var expected = {
lang: lang,
langIndex: index,
firstLangSelected: firstLangSelected,
lastLangSelected: lastLangSelected
};
jqUnit.assertDeepEq("Expected model for selected language " + lang, expected, model);
};

fluid.tests.fluid5659sequence = [{
func: "{fluid5659relay}.applier.change",
args: ["lang", "fr"]
}, {
listener: "fluid.tests.fluid5659verify",
args: ["{fluid5659relay}.model", "{fluid5659relay}.options.lang", "fr"],
spec: {path: "lang", priority: "last"},
changeEvent: "{fluid5659relay}.applier.modelChanged"
}];

fluid.tests.fluid5659source = function (langs) {
var togo = fluid.copy(fluid.tests.fluid5659modules);
togo.tests.expect = langs.length;
var sequence = fluid.transform(langs, function (lang) {
var pair = fluid.copy(fluid.tests.fluid5659sequence);
pair[0].args[1] = lang;
pair[1].args[2] = lang;
return pair;
});
togo.tests.sequence = fluid.flatten(sequence);
return togo;
};

fluid.test.runTests(["fluid.tests.fluid5659root"]);

})(jQuery);
Loading

0 comments on commit 85c2066

Please sign in to comment.