-
Notifications
You must be signed in to change notification settings - Fork 52
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
Refactor module to include a configuration when calling #forRoot #77
Conversation
@willmendesneto Follow-up to your comment... I understand this implementation is repetitive, harder to maintain and not completed (it misses the tests part so far). I need to keep working on it. Currently, the config parameter is a class because it cannot be a type: static forRoot(config: NgxSkeletonLoaderConfig = defaultConfig): ModuleWithProviders<NgxSkeletonLoaderModule> {
return {
ngModule: NgxSkeletonLoaderModule,
providers: [{
provide: NgxSkeletonLoaderConfig, // <-- this cannot be a type
useValue: config
}],
};
} I haven't figured out yet how to implement the feature as you detailed in your comment. If you have any advice, I'd be glad to hear from you! EDIT: see new changes for latest update |
Use an injection token for the module & component configuration
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader-config.service.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader-config.types.ts
Show resolved
Hide resolved
Thanks for your review! I will start working on resolving each later today (I'm from Belgium, it's 3 pm here!).
It is because it is a draft PR. This might be useful in your research: https://ideas.circleci.com/cloud-feature-requests/p/add-support-for-github-draft-prs Also, I look forward to your comments about how to deal with the component, module & service tests for this PR! |
TIL! Good to see that CircleCI/GH is getting smart on that 😄 In regards to test, this is definitely a good question! The way I can see tests is that we can cover that by using some real scenarios on modules and components which are already there. E.G. ModuleThe test is covering the changes on module + service + component integration describe('NgxSkeletonLoaderModule.forRoot() method', () => {
// tslint:disable-next-line: no-any
let fixture: any;
beforeEach(
waitForAsync(() => {
spyOn(console, 'error');
spyOn(console, 'log');
spyOn(console, 'warn');
spyOn(console, 'info');
fixture = TestBed.configureTestingModule({
imports: [NgxSkeletonLoaderModule.forRoot({ appearance: 'circle' })],
declarations: [ContainerComponent],
providers: [{ provide: PLATFORM_ID, useValue: 'browser' }],
}).createComponent(ContainerComponent);
fixture.detectChanges();
}),
);
// This test is now checking if the config was received as expected from the component
it('should render the component using given forRoot() config', () => {
expect(fixture.nativeElement.querySelectorAll('.skeletons-defaults .loader.circle').length).toBe(1);
});
}); ServiceThe tests for the service itself will be simple since it was simplified to cover if:
// Straight Jasmine testing without Angular's testing support
describe('NgxSkeletonLoaderConfigService', () => {
it('should use the default config if service is not receiving any specific config', () => {
const service = new NgxSkeletonLoaderConfigService();
expect(service.config).toEqual({ /* default object values */});
});
it('should combine configuration with the one received via constructor', () => {
const config = {appearance: 'circle' };
const service = new NgxSkeletonLoaderConfigService(config);
expect(service.config).toEqual({ .../* default object values + { } */, ...config});
});
it('should override all defaults with if receives configuration via constructor', () => {
const config = {
appearance: 'circle',
animation: 'pulse',
loadingText: 'Content is loading, please wait ...',
count: 2,
theme: {background: 'red'}
};
const service = new NgxSkeletonLoaderConfigService(config);
expect(service.config).toEqual(config);
});
}); ComponentThe tests for the component is already covered on the other tests, but it would be good if we have just a test - nice to have in that case since it's covered already. So I'll leave it up to you since it's a nice to have |
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader-config.service.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader-config.types.ts
Outdated
Show resolved
Hide resolved
- Remove service to directly inject the config token in the component and use its values in the constructor - Get rid of the DEFAULT_NGX_SKELETON_LOADER_CONFIG as default values are directly set in the component's constructor - Export theme's type to specific type to avoid errors building in SSR mode
I don't feel confident enough with writing the tests. Anyone willing to participate on that part? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, thanks @HunteRoi for this initiative. I'm excited to refactor my app with these defaults 🙏
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
After reading @dev054's comments and placing myself in the point of view of a developer accessing the component's properties (like via |
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
…eady non-optional
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.ts
Outdated
Show resolved
Hide resolved
…duce bundle size and avoid multiple unnecessary checks
What about simply adding this test in the module (as we don't have the service to test anymore) ? @willmendesneto describe('NgxSkeletonLoaderModule.forRoot({}) method', () => {
// tslint:disable-next-line: no-any
let fixture: any;
beforeEach(
waitForAsync(() => {
spyOn(console, 'error');
spyOn(console, 'log');
spyOn(console, 'warn');
spyOn(console, 'info');
fixture = TestBed.configureTestingModule({
imports: [NgxSkeletonLoaderModule.forRoot({ appearance: 'circle' })],
declarations: [ContainerComponent],
providers: [{ provide: PLATFORM_ID, useValue: 'browser' }],
}).createComponent(ContainerComponent);
fixture.detectChanges();
}),
);
it('should render the component using given forRoot() config', () => {
expect(fixture.nativeElement.querySelectorAll('.skeletons-defaults .loader.circle').length).toBe(1);
});
it('should NOT call console.error() method', () => {
expect(console.error).toHaveBeenCalledTimes(0);
});
it('should NOT call console.log() method', () => {
expect(console.log).toHaveBeenCalledTimes(0);
});
it('should NOT call console.warn() method', () => {
expect(console.warn).toHaveBeenCalledTimes(0);
});
it('should NOT call console.info() method', () => {
// tslint:disable-next-line: no-console
expect(console.info).toHaveBeenCalledTimes(0);
});
}); |
Looks good, @HunteRoi . It covers the aspects of module and the existent tests are covering the defaults already |
What happens if someone tries to use |
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.spec.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.component.spec.ts
Outdated
Show resolved
Hide resolved
projects/ngx-skeleton-loader/src/lib/ngx-skeleton-loader.module.spec.ts
Outdated
Show resolved
Hide resolved
Update the tests to use the forRoot configuration
@HunteRoi I just added a comment about the tests here (#77 (comment)). Also, you have to update this line here (https://github.com/willmendesneto/ngx-skeleton-loader/blob/master/package.json#L52) (in this pull request) to be aligned with the bundle size increase and it's good to be merged and published. |
Perfect, I will add that soon!
To what should I change this value to? Also, do you have any tests on your CI that would fail if some of the configuration are not changed? |
Change the tests to a single main describe
Yes, there is. You can find all the details and automated steps in this file (https://github.com/willmendesneto/ngx-skeleton-loader/blob/master/.circleci/config.yml). For some reason this pull request is not starting the pipeline, the reason why you can't see the Circle CI checks here. At the time being, I'm merging this pull request and applying the required change since it's a small one. Once again, thanks @HunteRoi - and @dev054 for the review! |
Did you make a release recently? @willmendesneto |
Please check if the PR fulfills these requirements
guidelines
What kind of change does this PR introduce? (check one with "x")
Fixes #62
What is the current behavior? (You can link to an open issue here, add screenshots…)
You can't pass any global configuration to
NgxSkeletonLoaderModule#forRoot
.What is the new behavior?
You can pass a global configuration to
NgxSkeletonLoaderModule#forRoot
that allows you to avoid repeative set of attributes on thengx-skeleton-loader
components.Does this PR introduce a breaking change? (check one with "x")
Other information (if applicable):
I tried to avoid any breaking change when working on this feature.
Also, I need help with the tests as I have litteraly never experienced writing them!
@willmendesneto