Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can-queues #26

Merged
merged 42 commits into from
Jan 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4bca14a
uses queues
justinbmeyer Oct 8, 2017
ca8e5d9
linting
justinbmeyer Oct 8, 2017
4731a0a
adding pre script
justinbmeyer Oct 8, 2017
a36da70
1.0.0-pre.1
justinbmeyer Oct 8, 2017
31472ec
reads props correctly
justinbmeyer Oct 8, 2017
08c9329
1.0.0-pre.2
justinbmeyer Oct 8, 2017
ef7de3b
able to write simple observables
justinbmeyer Oct 20, 2017
c41f74a
lint
justinbmeyer Oct 20, 2017
729e987
1.0.0-pre.3
justinbmeyer Oct 20, 2017
7b01b6a
check if observable
justinbmeyer Oct 20, 2017
0de00f9
1.0.0-pre.4
justinbmeyer Oct 20, 2017
d6155b4
1.0.0-pre.5
justinbmeyer Oct 20, 2017
61e3461
cleanup dependencies
christopherjbaker Oct 26, 2017
7ef5939
1.0.0-pre.6
christopherjbaker Oct 27, 2017
9380651
tolerate wider event-queue
justinbmeyer Oct 27, 2017
aee30f0
1.0.0-pre.7
justinbmeyer Oct 27, 2017
f056cbf
protect tests
justinbmeyer Oct 27, 2017
cb64514
1.0.0-pre.8
justinbmeyer Oct 27, 2017
d2628ba
nice names for bound methods
justinbmeyer Oct 27, 2017
485a6e7
lint
justinbmeyer Oct 27, 2017
ea08077
1.0.0-pre.9
justinbmeyer Oct 27, 2017
5bb363d
Merge branch 'master' into merge-master-to-major
chasenlehara Nov 10, 2017
f5eceef
Merge pull request #11 from canjs/merge-master-to-major
chasenlehara Nov 10, 2017
abb5c73
1.0.0-pre.10
chasenlehara Nov 10, 2017
421dcab
Merge branch 'master' into major-can-event-queue-update
chasenlehara Nov 21, 2017
c6becd0
Use new legacy module path introduced in can-event-queue 0.9.0
chasenlehara Nov 21, 2017
57ce01d
1.0.0-pre.11
chasenlehara Nov 21, 2017
cd58a24
Merge remote-tracking branch 'origin/master' into major
phillipskevin Nov 21, 2017
3fbf236
1.0.0-pre.12
phillipskevin Nov 21, 2017
855bdd3
giving warnings for @, callMethodsOnObservables, and removing automat…
phillipskevin Nov 22, 2017
7a27d14
1.0.0-pre.13
phillipskevin Nov 22, 2017
8bd8c5c
removing incorrect warning for @
phillipskevin Nov 28, 2017
ca84fd1
1.0.0-pre.14
phillipskevin Nov 28, 2017
0558121
use OR directly
justinbmeyer Dec 1, 2017
c766eb1
1.0.0-pre.15
justinbmeyer Dec 1, 2017
a484584
Use can-event-queue/map/map instead of can-event-queue/map/legacy/legacy
chasenlehara Jan 2, 2018
c728562
1.0.0-pre.16
chasenlehara Jan 2, 2018
3e50ff8
Fix QUnit.ok usages
andrejewski Jan 9, 2018
f4e200d
Merge pull request #19 from canjs/good-test
andrejewski Jan 9, 2018
eb1357d
1.0.0-pre.17
andrejewski Jan 9, 2018
077b703
pointing at the right versions
justinbmeyer Jan 27, 2018
e1e7a6e
Merge branch 'master' into major
justinbmeyer Jan 27, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 55 additions & 88 deletions can-stache-key-test.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
var observeReader = require("can-stache-key");
var QUnit = require('steal-qunit');
var Observation = require('can-observation');
var canEvent = require('can-event');
var eventQueue = require('can-event-queue/map/map');
var SimpleObservable = require("can-simple-observable");
var testHelpers = require('can-test-helpers');
var ObservationRecorder = require("can-observation-recorder");

var assign = require("can-util/js/assign/assign");
var eventAsync = require("can-event/async/async");
var SimpleMap = require("can-simple-map");
var canReflect = require("can-reflect");

QUnit.module('can-observation/reader',{
setup: function(){
eventAsync.sync();
},
teardown: function(){
eventAsync.async();
}
QUnit.module('can-stache-key',{

});

test("can.Compute.read can read a promise (#179)", function(){
test("can read a promise (#179)", function(){
var data = {
promise: new Promise(function(resolve){
setTimeout(function(){
Expand All @@ -29,16 +24,14 @@ test("can.Compute.read can read a promise (#179)", function(){
var calls = 0;
var c = new Observation(function(){
return observeReader.read(data,observeReader.reads("promise.value")).value;
}, null, {
updater: function(newVal, oldVal){
calls++;
equal(calls, 1, "only one call");
equal(newVal, "Something", "new value");
equal(oldVal, undefined, "oldVal");
start();
}
});
c.start();
canReflect.onValue(c, function(newVal, oldVal){
calls++;
equal(calls, 1, "only one call");
equal(newVal, "Something", "new value");
equal(oldVal, undefined, "oldVal");
start();
});

stop();

Expand All @@ -57,16 +50,14 @@ test("can.Compute.read can read a promise-like (#82)", function(){
var calls = 0;
var c = new Observation(function(){
return observeReader.read(data,observeReader.reads("promiseLike.value")).value;
}, null, {
updater: function(newVal, oldVal){
calls++;
equal(calls, 1, "only one call");
equal(newVal, "Something", "new value");
equal(oldVal, undefined, "oldVal");
start();
}
});
c.start();
canReflect.onValue(c, function(newVal, oldVal){
calls++;
equal(calls, 1, "only one call");
equal(newVal, "Something", "new value");
equal(oldVal, undefined, "oldVal");
start();
});

stop();

Expand All @@ -88,11 +79,11 @@ test('can.compute.reads', function(){
});

test('able to read things like can-define', 3, function(){
var obj = assign({}, canEvent);
var obj = eventQueue({});
var prop = "PROP";
Object.defineProperty(obj, "prop",{
get: function(){
Observation.add(obj,"prop");
ObservationRecorder.add(obj,"prop");
return prop;
},
set: function(val){
Expand All @@ -113,41 +104,38 @@ test('able to read things like can-define', 3, function(){
}
}).value;
equal(value, "PROP");
}, null, {
updater: function(){

}
});
c.start();


canReflect.onValue(c, function(){});
});

test("foundObservable called with observable object (#7)", function(){
var map = {
var map = new SimpleMap({
isSaving: function(){
Observation.add(this, "_saving");
ObservationRecorder.add(this, "_saving");
},
addEventListener: function(){}
};
});

// must use an observation to make sure things are listening.
var c = new Observation(function(){
observeReader.read(map,observeReader.reads("isSaving"),{
foundObservable: function(obs){
QUnit.equal(obs, map);
}
},
callMethodsOnObservables: true
});
}, null,{});
c.start();

});
canReflect.onValue(c, function(){});
});

test("can read from strings", function(){
var context = " hi there ";

var result = observeReader.read(context,observeReader.reads("trim"),{});
QUnit.ok(result, context.trim);
QUnit.equal(
result.value(context),
context.trim(context),
'trim method works'
);
});

test("read / write to DefineMap", function(){
Expand All @@ -159,10 +147,10 @@ test("read / write to DefineMap", function(){
}
});
return data.value;
}, null,function(newVal){
});
canReflect.onValue(c, function(newVal){
QUnit.equal(newVal, 1, "got updated");
});
c.start();
observeReader.write(map,"value",1);
});

Expand Down Expand Up @@ -233,63 +221,42 @@ test("it returns null when promise getter is null #2", function(){
QUnit.equal(typeof nullPromise,"object");
});

testHelpers.dev.devOnlyTest("a warning is displayed when functions are called by read()", function() {
var teardown = testHelpers.dev.willWarn(/"func" is being called as a function/);
var func = function() {
QUnit.ok(true, "method called");
};
var data = { func: func };
var reads = observeReader.reads("func");

observeReader.read(data, reads, {
warnOnFunctionCall: "A Warning"
});

QUnit.equal(teardown(), 1, "warning displayed");
});
QUnit.test("set onto observable objects and values", function(){
var map = new SimpleMap();
observeReader.write({map: map},"map", {a: "b"});

testHelpers.dev.devOnlyTest("a warning is displayed when methods on observables are called by read()", function() {
var teardown = testHelpers.dev.willWarn(/"func" is being called as a function/);
var func = function() {
QUnit.ok(true, "method called");
};
var data = new SimpleMap({ func: func });
var reads = observeReader.reads("func");
QUnit.equal(map.get("a"), "b", "merged");

observeReader.read(data, reads, {
callMethodsOnObservables: true
});

QUnit.equal(teardown(), 1, "warning displayed");
var simple = new SimpleObservable();
observeReader.write({simple: simple},"simple", 1);
QUnit.equal(simple.get(), 1);
});

testHelpers.dev.devOnlyTest("a warning is not displayed when functions are read but not called", function() {
var teardown = testHelpers.dev.willWarn(/"func" is being called as a function/);
testHelpers.dev.devOnlyTest("functions are not called by read()", function() {
var func = function() {
QUnit.ok(false, "method called");
};
var data = new SimpleMap({ func: func });
var reads = observeReader.reads("@func");
var data = { func: func };
var reads = observeReader.reads("func");

observeReader.read(data, reads, {
callMethodsOnObservables: true
});
observeReader.read(data, reads);

QUnit.equal(teardown(), 0, "warning not displayed");
QUnit.ok(true);
});

testHelpers.dev.devOnlyTest("a warning is not displayed when functions are read but not called due to proxyMethods=false (#15)", function() {
var teardown = testHelpers.dev.willWarn(/"func" is being called as a function/);
testHelpers.dev.devOnlyTest("a warning is given for `callMethodsOnObservables: true`", function() {
var teardown = testHelpers.dev.willWarn("can-stache-key: read() called with `callMethodsOnObservables: true`.");
var func = function() {
QUnit.ok(false, "method not called");
QUnit.ok(true, "method called");
};
var data = new SimpleMap({ func: func });
var reads = observeReader.reads("func");

observeReader.read(data, reads, {
isArgument: true,
proxyMethods: false
callMethodsOnObservables: true
});

QUnit.equal(teardown(), 0, "warning not displayed");
QUnit.equal(teardown(), 1, "warning displayed");
});

78 changes: 33 additions & 45 deletions can-stache-key.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
var Observation = require('can-observation');
var ObservationRecorder = require('can-observation-recorder');
var dev = require('can-log/dev/dev');
var each = require('can-util/js/each/each');
var canSymbol = require("can-symbol");
Expand All @@ -10,7 +10,20 @@ var getValueSymbol = canSymbol.for("can.getValue");
var setValueSymbol = canSymbol.for("can.setValue");

var isValueLikeSymbol = canSymbol.for("can.isValueLike");
var peek = ObservationRecorder.ignore(canReflect.getKeyValue.bind(canReflect));
var observeReader;

var bindName = Function.prototype.bind;
//!steal-remove-start
bindName = function(source){
var fn = Function.prototype.bind.call(this, source);
Object.defineProperty(fn, "name", {
value: canReflect.getName(source) + "."+canReflect.getName(this)
});
return fn;
};
//!steal-remove-end

var isAt = function(index, reads) {
var prevRead = reads[index-1];
return prevRead && prevRead.at;
Expand All @@ -37,8 +50,8 @@ var specialRead = {index: true, key: true, event: true, element: true, viewModel

var checkForObservableAndNotify = function(options, state, getObserves, value, index){
if(options.foundObservable && !state.foundObservable) {
if(Observation.trapsCount()) {
Observation.addAll( getObserves() );
if(ObservationRecorder.trapsCount()) {
ObservationRecorder.addMany( getObserves() );
options.foundObservable(value, index);
state.foundObservable = true;
}
Expand All @@ -49,8 +62,6 @@ observeReader = {
// there are things that you need to evaluate when you get them back as a property read
// for example a compute or a function you might need to call to get the next value to
// actually check
// - isArgument - should be renamed to something like "onLastPropertyReadReturnFunctionInsteadOfCallingIt".
// This is used to make a compute out of that function if necessary.
// - readCompute - can be set to `false` to prevent reading an ending compute. This is used by component to get a
// compute as a delegate. In 3.0, this should be removed and force people to write "{@prop} change"
// - callMethodsOnObservables - this is an overwrite ... so normal methods won't be called, but observable ones will.
Expand All @@ -68,7 +79,7 @@ observeReader = {
};
var getObserves;
if(options.foundObservable) {
getObserves = Observation.trap();
getObserves = ObservationRecorder.trap();
}

// `cur` is the current value.
Expand Down Expand Up @@ -145,47 +156,13 @@ observeReader = {
return value && canReflect.isFunctionLike(value) && !canReflect.isConstructorLike(value);
},
read: function(value, i, reads, options, state, prev){
if( isAt(i, reads) ) {
return i === reads.length ? value.bind(prev) : value;
}

//!steal-remove-start
var showWarning = function() {
dev.warn(
(options.filename ? options.filename + ':' : '') +
(options.lineNumber ? options.lineNumber + ': ' : '') +
'"' + reads[0].key + '" is being called as a function.\n' +
'\tThis will not happen automatically in an upcoming release.\n' +
'\tYou should call it explicitly using "' + reads[0].key + '()".\n\n'
);
};
//!steal-remove-end


if(options.callMethodsOnObservables && canReflect.isObservableLike(prev) && canReflect.isMapLike(prev)) {
//!steal-remove-start
showWarning();
//!steal-remove-end
dev.warn("can-stache-key: read() called with `callMethodsOnObservables: true`.");

return value.apply(prev, options.args || []);
}
else if ( options.isArgument && i === reads.length ) {
if (options.proxyMethods === false) {
return value;
}

//!steal-remove-start
showWarning();
//!steal-remove-end

return value.bind(prev);
}

//!steal-remove-start
showWarning();
//!steal-remove-end

return value.apply(prev, options.args || []);
return options.proxyMethods !== false ? bindName.call(value, prev) : value;
}
},
{
Expand Down Expand Up @@ -263,7 +240,17 @@ observeReader = {
}
},
write: function(base, prop, newVal){
base[prop] = newVal;
var propValue = base[prop];
// if newVal is observable object, lets try to update
if(canReflect.isMapLike(propValue) && newVal && typeof newVal === "object") {
dev.warn("can-stache-key: Merging data into \"" + prop + "\" because its parent is non-observable");
canReflect.update(propValue, newVal);
} else if(canReflect.isValueLike(propValue) && canReflect.isObservableLike(propValue)){
canReflect.setValue(propValue, newVal);
} else {
base[prop] = newVal;
}

}
}
],
Expand Down Expand Up @@ -315,11 +302,12 @@ observeReader = {
} else {
last = keys[0];
}
var keyValue = peek(parent, last.key);
// here's where we need to figure out the best way to write

// if property being set points at a compute, set the compute
if( observeReader.valueReadersMap.isValueLike.test(parent[last.key], keys.length - 1, keys, options) ) {
observeReader.valueReadersMap.isValueLike.write(parent[last.key], value, options);
if( observeReader.valueReadersMap.isValueLike.test(keyValue, keys.length - 1, keys, options) ) {
observeReader.valueReadersMap.isValueLike.write(keyValue, value, options);
} else {
if(observeReader.valueReadersMap.isValueLike.test(parent, keys.length - 1, keys, options) ) {
parent = parent[getValueSymbol]();
Expand Down
Loading