Given the following code and test, implement the ChangeSet class and attribute es6 decorator so that the tests pass. The code should be valid typescript code.
class ChangeSet {
}
class User extends ChangeSet {
@attribute name: string;
@attribute age: number;
}
describe('ChangeSet', () => {
it('should create a new instance from a hash', () => {
const change = new ChangeSet({name: 'John', age: 25});
expect(change.name).to.equal('John');
expect(change.age).to.equal(25);
});
it('should track changes of the attributes', () => {
const change = new ChangeSet({name: 'John', age: 25});
expect(change.name.dirty).to.equal(false);
change.name = 'Jane';
expect(change.dirty).to.equal(true);
expect(change.name.dirty).to.equal(true);
expect(change.changes).to.equal({name: 'Jane'});
});
it('should allow resetting changes of an attribute', () => {
const change = new ChangeSet({name: 'John', age: 25});
change.name = 'Jane';
expect(change.changes).to.equal({name: 'Jane'});
change.name.reset();
expect(change.changes).to.equal({name: 'John'});
expect(change.dirty).to.equal(true);
});
it('should allow resetting changes of all attributes', () => {
const change = new ChangeSet({name: 'John', age: 25});
change.name = 'Jane';
expect(change.changes).to.equal({name: 'Jane'});
expect(change.dirty).to.equal(false);
change.reset();
expect(change.changes).to.equal({name: 'John'});
expect(change.dirty).to.equal(true);
})
it('should allow enumeration of all attribute keys', () => {
const change = new ChangeSet({name: 'John', age: 25});
expect(change.attributes).to.equal(['name', 'age']);
});
it('should express its changes as a hash', () => {
const change = new ChangeSet({name: 'John', age: 25});
change.name = 'Jane';
change.age = 25;
expect(change.changes).to.equal({name: 'Jane', age: 30});
});
it('should allow being constructed from an array of hashes, marking attributes that are not equal amongs the hashes as mixed', () => {
const change1 = new ChangeSet({name: 'John', age: 25});
const change2 = new ChangeSet({name: 'Jane', age: 25});
const change3 = ChangeSet.fromArray([change1, change2]);
expect(change1.name.mixed).to.equal(true);
expect(change1.age.mixed).to.equal(false);
});
});