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 undoChanges method to accept an only option. #25

Merged
merged 4 commits into from Mar 25, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 22 additions & 4 deletions spec/model_spec.js
Expand Up @@ -2126,21 +2126,39 @@ describe('Model', function () {
});

it('does not undo changes to the owned association specified in the except option as a string', function() {
var li = this.invoice.lineItems.at(0);

this.invoice.billingAddress.name = 'Bob Smith';
this.invoice.undoChanges({except: 'billingAddress'});
expect(this.invoice.billingAddress.name).toBe('Bob Smith');
});

it('does not undo changes to owned associations specified in the exception option as an array', function() {
var li = this.invoice.lineItems.at(0);
it('undoes only the assocations specified in the only option as a string', function() {
this.invoice.lineItems.pop();
expect(this.invoice.lineItems.length).toEqual(2);
this.invoice.billingAddress.name = "Tom Smith";

this.invoice.undoChanges({only: 'lineItems'});

expect(this.invoice.billingAddress.name).toBe('Tom Smith');
expect(this.invoice.lineItems.length).toEqual(3);
});

it('does not undo changes to owned associations specified in the exception option as an array', function() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@burrows While working on the only option, noticed a bug with the except option. If you write the test this way it would fail. This is because the check was not happing in for (let prop in this.ownChanges) {

Copy link
Contributor

Choose a reason for hiding this comment

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

@stallings Originally the except option was designed to only avoid recursively calling undoChanges on associated objects. This change makes it work with attributes as well. I think this makes sense, but please update the documentation to reflect that.

this.invoice.billingAddress.name = 'Bob Smith';
this.invoice.undoChanges({except: ['billingAddress']});
expect(this.invoice.billingAddress.name).toBe('Bob Smith');
});

it('undoes only the assocations specified in the only option as an array', function() {
this.invoice.lineItems.pop();
expect(this.invoice.lineItems.length).toEqual(2);
this.invoice.billingAddress.name = 'Tom Smith';

this.invoice.undoChanges({only: ['lineItems']});

expect(this.invoice.billingAddress.name).toBe('Tom Smith');
expect(this.invoice.lineItems.length).toEqual(3);
});

it('re-runs validations', function() {
this.invoice.addError('name', 'foo');
this.invoice.undoChanges();
Expand Down
5 changes: 5 additions & 0 deletions src/model.js
Expand Up @@ -1033,6 +1033,8 @@ var Model = TransisObject.extend(function() {
// opts - An object containing zero or more of the following keys:
// except - Either a string or an array of strings of owned association names to skip over when
// undoing changes on owned associations.
// only - Either a string or an array of strings of owned association names that limit the undoing of changes
// to only the provided associations.
//
// Returns the receiver.
this.prototype.undoChanges = function(opts = {}) {
Expand All @@ -1059,6 +1061,9 @@ var Model = TransisObject.extend(function() {
if (opts.except === name) { continue; }
if (Array.isArray(opts.except) && opts.except.indexOf(name) >= 0) { continue; }

if (opts.only && opts.only !== name) { continue; }
Copy link
Contributor

Choose a reason for hiding this comment

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

If opts.only is an array and name is in the array, then this will skip processing name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. How does this look?

        if(opts.only) {
          if(Array.isArray(opts.only)) {
            if (opts.only.indexOf(name) === -1) { continue; }
          }
          else {
            if (opts.only !== name) { continue; }
          }
        }

Copy link
Contributor

Choose a reason for hiding this comment

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

That looks better. Make sure you add a spec for the scenario I described.

if (Array.isArray(opts.only) && opts.only.indexOf(name) === -1) { continue; }

if (desc.type === 'hasOne') {
this[name] && this[name].undoChanges();
}
Expand Down