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

test(component): test different notations #574

Merged
merged 1 commit into from
Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/component/base-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,10 @@ export default class BaseComponent extends events.EventEmitter {
}
}

setClassName(className) {
this.className = className;
}

getClassName() {
// Note: we cannot use Class.prototype.name as this is overwritten by minifiers like UglifyJS.
//
Expand Down
169 changes: 169 additions & 0 deletions src/component/component.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Component from './component';
import Form from '../form/form';
import TextField from '../fields/text-field';

it('should concat schemas', () => {
const c = new Component({
Expand All @@ -14,3 +16,170 @@ it('should concat schemas', () => {
'three',
]);
});

const shouldSupportComponentNotations = (component, className) => {
expect(component.get('isStore')).toEqual(true);
expect(component.get('docLevel')).toEqual('basic');
expect(component.getClassName()).toEqual(className);
expect(component.get('song')).toEqual('Bamboleo');
};

const songField = new TextField({
name: 'song',
});

const artistField = new TextField({
name: 'artist',
});

// Legacy notation where className is specified separately
class LegacyNotationComponent extends Component {
className = 'app.LegacyNotationComponent';

create(props) {
super.create(props);
this.set({
schema: new Form({
fields: [songField],
}),
docLevel: 'basic',
});
}
}

it('should support legacy component notation', () => {
const component = new LegacyNotationComponent({
isStore: true,
song: 'Bamboleo',
});
shouldSupportComponentNotations(component, 'app.LegacyNotationComponent');
});

class ExtendedLegacyNotationComponent extends LegacyNotationComponent {
className = 'app.ExtendedLegacyNotationComponent';

// NOTE: we need to call this.set() after super.create() so that we don't overwrite the schema set
// in LegacyNotationComponent
create(props) {
super.create(props);
this.set({
schema: new Form({
fields: [artistField],
}),
});
}
}

it('should support extended legacy component notation', () => {
const component = new ExtendedLegacyNotationComponent({
isStore: true,
song: 'Bamboleo',
artist: 'Gipsy Kings',
});
shouldSupportComponentNotations(
component,
'app.ExtendedLegacyNotationComponent'
);
expect(component.get('artist')).toEqual('Gipsy Kings');
});

// As per https://github.com/redgeoff/mson/pull/570, the support of a className property causes
// issues with the existing legacy notation (className class member variable). In the future, we may
// want to dig deeper to identify a path forward where a className property can be utilized.
//
// // Use className property
// class CondensedNotationComponent extends Component {
// create(props) {
// super.create(props);
// this.set({
// className: 'app.CondensedNotationComponent',
// schema: new Form({
// fields: [songField],
// }),
// docLevel: 'basic',
// });
// }
// }
//
// it('should support condensed component notation', () => {
// const component = new CondensedNotationComponent({
// isStore: true,
// song: 'Bamboleo',
// });
// shouldSupportComponentNotations(component, 'app.CondensedNotationComponent');
// });
//
// class ExtendedCondensedNotationComponent extends CondensedNotationComponent {
// // NOTE: we need to call this.set() after super.create() so that we don't overwrite the schema set
// // in CondensedNotationComponent
// create(props) {
// super.create(props);
// this.set({
// className: 'app.ExtendedCondensedNotationComponent',
// schema: new Form({
// fields: [artistField],
// }),
// });
// }
// }
//
// it('should support extended condensed component notation', () => {
// const component = new ExtendedCondensedNotationComponent({
// isStore: true,
// song: 'Bamboleo',
// artist: 'Gipsy Kings',
// });
// shouldSupportComponentNotations(
// component,
// 'app.ExtendedCondensedNotationComponent'
// );
// expect(component.get('artist')).toEqual('Gipsy Kings');
// });

const createFunctionalNotationComponent = (props) => {
const component = new Component();
component.setClassName('app.FunctionalNotationComponent');
component.set({
schema: new Form({
fields: [songField],
}),
docLevel: 'basic',
...props,
});
return component;
};

it('should support functional component notation', () => {
const component = createFunctionalNotationComponent({
isStore: true,
song: 'Bamboleo',
});
shouldSupportComponentNotations(component, 'app.FunctionalNotationComponent');
});

// TODO: make component.set() return component so that can chain? The difficulty is that many
// components extend set() and all these instances would have to be modified to support chaining.
const createExtendedFunctionalNotationComponent = (props) => {
const component = createFunctionalNotationComponent();
component.setClassName('app.ExtendedFunctionalNotationComponent');
component.set({
schema: new Form({
fields: [artistField],
}),
...props,
});
return component;
};

it('should support extended functional component notation', () => {
const component = createExtendedFunctionalNotationComponent({
isStore: true,
song: 'Bamboleo',
artist: 'Gipsy Kings',
});
shouldSupportComponentNotations(
component,
'app.ExtendedFunctionalNotationComponent'
);
expect(component.get('artist')).toEqual('Gipsy Kings');
});