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

Update a test to fail #14843 #15110

Closed

Conversation

hjdivad
Copy link
Member

@hjdivad hjdivad commented Apr 5, 2017

Update a test to fail #14843 and provide example code to illustrate the change suggested in that issue.

Before this can be merged we'd need to decide to deprecate the current semantics of firstObject and lastObject. The trade-off is between having objectAt called in nearly every case for array mutations, or not detecting that [A, B].insertAt(0, A) does not change firstObject.

If that tradeoff is made, we should probably feature flag & deprecate the existing behaviour.

Copy link
Member

@stefanpenner stefanpenner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some notes, if we decide to proceed.

Would love @krisselden's input

if (cache.firstObject !== undefined &&
objectAt(array, 0) !== cacheFor.get(cache, 'firstObject')) {
((startIdx === 0 && (addAmt > 0 || removeAmt > 0)) ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we still include objectAt(array, 0) !== cacheFor.get(cache, 'firstObject') guard?

objectAt(array, get(array, 'length') - 1) !== cacheFor.get(cache, 'lastObject')) {
((startIdx >= length && addAmt > 0) ||
(startIdx >= 0 && (startIdx + removeAmt >= length)) ||
(startIdx < 0 && (removeAmt >= -startIdx)))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we still include objectAt(array, get(array, 'length') - 1) !== cacheFor.get(cache, 'lastObject')) { guard ?

@@ -142,17 +142,23 @@ export function arrayContentDidChange(array, startIdx, removeAmt, addAmt) {
let cache = meta && meta.readableCache();

if (cache) {
let length = get(array, 'length') + removeAmt - addAmt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should likely avoid this get if we are not needing it.

This is getting complicated, if we go down this path we should do a helper function that can be unit tested (and more readable).

@@ -135,11 +135,22 @@ suite.test('[A,B,C].insertAt(1,X) => [A,X,B,C] + notify', function() {
let after = [before[0], item, before[1], before[2]];
let obj = this.newObject(before);
let observer = this.newObserver(obj, '[]', '@each', 'length', 'firstObject', 'lastObject');
let objectAtCalls = [];

let objectAt = obj.objectAt;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we will require more test permutations, as the above code has many bounds

@hjdivad
Copy link
Member Author

hjdivad commented Apr 5, 2017

Three possible courses of action:

  1. do nothing
  2. check the index ranges before calling objectAt
  3. remove objectAt entirely and only check index ranges

@homu
Copy link
Contributor

homu commented May 6, 2017

☔ The latest upstream changes (presumably #15210) made this pull request unmergeable. Please resolve the merge conflicts.

@stefanpenner
Copy link
Member

@bekzod if you happen to have cycles. I think we would like to move forward with this PR, maybe you can lend @hjdivad a hand and help him land it?

@bekzod
Copy link
Contributor

bekzod commented Jul 14, 2017

@stefanpenner sure, will look at it

@bekzod
Copy link
Contributor

bekzod commented Jul 14, 2017

maybe following code is a bit clearer (tested with new test) ? @stefanpenner @hjdivad

 if (cache !== undefined) {
    if (cache.firstObject !== undefined && startIdx === 0 && objectAt(array, 0) !== cacheFor.get(cache, 'firstObject')) {
      propertyWillChange(array, 'firstObject');
      propertyDidChange(array, 'firstObject');
    }

    if (cache.lastObject !== undefined) {
      let delta = (addAmt === -1 ? 0 : addAmt) - (removeAmt === -1 ? 0 : removeAmt);
      let length = get(array, 'length');

      let lastIndex = length - delta - 1;
      if ((lastIndex === -1 || delta === 0 || !(startIdx < lastIndex && lastIndex < length)) && objectAt(array, length - 1) !== cacheFor.get(cache, 'lastObject')) {
        propertyWillChange(array, 'lastObject');
        propertyDidChange(array, 'lastObject');
      }
   }
  }

also can startIdx be negative in arrayContentDidChange ?

@bekzod
Copy link
Contributor

bekzod commented Jul 15, 2017

I think the approach suggested is good enough, cannot think of better way for now will improve this once merged if I get any better ideas

@stefanpenner
Copy link
Member

@bekzod nice, are you able to do the rebase + fix any failing tests? Feel free to open a new PR.

@hjdivad
Copy link
Member Author

hjdivad commented Jul 17, 2017

Closed in favour of #15510

@hjdivad hjdivad closed this Jul 17, 2017
@hjdivad
Copy link
Member Author

hjdivad commented Jul 17, 2017

also can startIdx be negative in arrayContentDidChange ?

Yes, the semantics mirror those of splice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants