Skip to content

Commit

Permalink
Merge pull request #191 from zakhenry/feat/deprecate-decorator-pattern
Browse files Browse the repository at this point in the history
Remove decorator pattern, upgrade to Angular 10
  • Loading branch information
zakhenry committed Oct 23, 2020
2 parents 464a851 + a583d26 commit ba2a391
Show file tree
Hide file tree
Showing 23 changed files with 2,868 additions and 1,767 deletions.
2 changes: 1 addition & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"styleext": "scss"
"style": "scss"
}
},
"architect": {
Expand Down
57 changes: 28 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,37 +33,36 @@
"readme:build": "embedme README.md && yarn run prettier README.md --write",
"readme:check": "yarn readme:build && ! git status | grep README.md || (echo 'You must commit build and commit changes to README.md!' && exit 1)",
"ngcc": "[ ! -f ./node_modules/.bin/ngcc ] || node --max_old_space_size=8000 ./node_modules/.bin/ngcc",
"postinstall":"yarn run ngcc"
"postinstall": "yarn run ngcc"
},
"private": true,
"dependencies": {
"@angular/animations": "9.0.1",
"@angular/cdk": "9.0.0",
"@angular/common": "9.0.1",
"@angular/compiler": "9.0.1",
"@angular/core": "9.0.1",
"@angular/forms": "9.0.1",
"@angular/http": "7.2.16",
"@angular/animations": "10.2.0",
"@angular/cdk": "10.2.0",
"@angular/common": "10.2.0",
"@angular/compiler": "10.2.0",
"@angular/core": "10.2.0",
"@angular/forms": "10.2.0",
"@angular/material": "9.0.0",
"@angular/platform-browser": "9.0.1",
"@angular/platform-browser-dynamic": "9.0.1",
"@angular/router": "9.0.1",
"@angular/platform-browser": "10.2.0",
"@angular/platform-browser-dynamic": "10.2.0",
"@angular/router": "10.2.0",
"@types/uuid": "3.4.7",
"commitizen": "4.0.3",
"core-js": "3.6.4",
"fast-deep-equal": "3.1.1",
"ngx-observable-lifecycle": "1.0.1",
"ngx-observable-lifecycle": "2.0.0",
"rxjs": "6.5.4",
"tslib": "1.10.0",
"tslib": "^2.0.0",
"uuid": "3.4.0",
"zone.js": "0.10.2"
"zone.js": "0.10.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "0.900.1",
"@angular-devkit/build-ng-packagr": "0.900.1",
"@angular/cli": "9.0.1",
"@angular/compiler-cli": "9.0.1",
"@angular/language-service": "9.0.1",
"@angular-devkit/build-angular": "0.1001.7",
"@angular-devkit/build-ng-packagr": "0.1001.7",
"@angular/cli": "10.1.7",
"@angular/compiler-cli": "10.2.0",
"@angular/language-service": "10.2.0",
"@bahmutov/add-typescript-to-cypress": "2.1.2",
"@types/jasmine": "3.5.5",
"@types/jasminewd2": "2.0.8",
Expand All @@ -73,21 +72,21 @@
"cz-conventional-changelog": "3.1.0",
"embedme": "1.20.0",
"http-server-spa": "1.3.0",
"jasmine-core": "3.5.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.4.1",
"karma-chrome-launcher": "3.1.0",
"karma-coverage-istanbul-reporter": "2.1.1",
"karma-jasmine": "3.1.1",
"karma-jasmine-html-reporter": "1.5.2",
"ng-packagr": "9.0.1",
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"ng-packagr": "^10.1.0",
"prettier": "1.19.1",
"semantic-release": "17.1.1",
"ts-node": "8.6.2",
"tsconfig-paths-webpack-plugin": "3.2.0",
"tsdef": "0.0.13",
"tslint": "6.0.0",
"typescript": "3.7.5"
"tslint": "~6.1.0",
"typescript": "4.0.3"
},
"repository": {
"type": "git",
Expand Down
16 changes: 2 additions & 14 deletions projects/ngx-sub-form/new/src/ngx-sub-form.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// import { ɵmarkDirty as markDirty } from '@angular/core';
import isEqual from 'fast-deep-equal';
import { decorateObservableLifecycle, getObservableLifecycle } from 'ngx-observable-lifecycle';
import { getObservableLifecycle } from 'ngx-observable-lifecycle';
import { EMPTY, forkJoin, Observable, of } from 'rxjs';
import {
delay,
Expand Down Expand Up @@ -68,7 +67,7 @@ export function createForm<ControlInterface, FormInterface>(
let isRemoved = false;

const lifecyleHooks: ComponentHooks = options.componentHooks ?? {
onDestroy: getObservableLifecycle(componentInstance).onDestroy,
onDestroy: getObservableLifecycle(componentInstance).ngOnDestroy,
};

lifecyleHooks.onDestroy.pipe(take(1)).subscribe(() => {
Expand Down Expand Up @@ -248,14 +247,3 @@ export function createForm<ControlInterface, FormInterface>(
createFormArrayControl: (options as any).createFormArrayControl,
};
}

export function NgxSubForm(): ClassDecorator {
return function(target) {
decorateObservableLifecycle(target, {
hooks: {
onDestroy: true,
},
incompatibleComponentError: new Error(`You must use @NgxSubForm with a directive or component.`),
});
};
}
7 changes: 4 additions & 3 deletions projects/ngx-sub-form/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.0.1"
"fast-deep-equal": "^3.0.1",
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/common": "^9.0.0",
"@angular/core": "^9.0.0"
"@angular/common": "^10.0.0",
"@angular/core": "^10.0.0"
},
"keywords": [
"Angular",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { BehaviorSubject } from 'rxjs';
Expand Down Expand Up @@ -87,12 +87,14 @@ describe(`NgxAutomaticRootFormComponent`, () => {
let component: TestWrapperComponent;
let componentForm: AutomaticRootFormComponent;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [TestWrapperComponent, AutomaticRootFormComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [TestWrapperComponent, AutomaticRootFormComponent],
}).compileComponents();
}),
);

beforeEach(() => {
componentFixture = TestBed.createComponent(TestWrapperComponent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, DebugElement, EventEmitter, Input, Output } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { FormArray, FormControl, ReactiveFormsModule, Validators } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { BehaviorSubject } from 'rxjs';
Expand Down Expand Up @@ -85,12 +85,14 @@ describe(`NgxRootFormComponent`, () => {
let component: TestWrapperComponent;
let componentForm: RootFormComponent;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [TestWrapperComponent, RootFormComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [TestWrapperComponent, RootFormComponent],
}).compileComponents();
}),
);

beforeEach(() => {
componentFixture = TestBed.createComponent(TestWrapperComponent);
Expand Down Expand Up @@ -227,12 +229,14 @@ describe(`NgxRootFormComponent with an array`, () => {
let component: ArrayTestWrapperComponent;
let componentForm: RootFormArrayComponent;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [ArrayTestWrapperComponent, RootFormArrayComponent],
}).compileComponents();
}));
beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [ArrayTestWrapperComponent, RootFormArrayComponent],
}).compileComponents();
}),
);

beforeEach(() => {
componentFixture = TestBed.createComponent(ArrayTestWrapperComponent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '../shared/ngx-sub-form-utils';
import { FormGroupOptions, NgxFormWithArrayControls } from '../shared/ngx-sub-form.types';
import { NgxSubFormComponent, NgxSubFormRemapComponent } from './ngx-sub-form.component';
import { Component, Directive } from '@angular/core';

interface Vehicle {
color?: string | null;
Expand All @@ -33,6 +34,7 @@ const getDefaultValues = (): Required<Vehicle> => ({
crewMemberCount: 10,
});

@Component({ template: '' })
class SubComponent extends NgxSubFormComponent<Vehicle> {
protected getFormControls() {
// even though optional, if we comment out color there should be a TS error
Expand All @@ -49,13 +51,15 @@ class SubComponent extends NgxSubFormComponent<Vehicle> {

const DEBOUNCE_TIMING = 500;

@Component({ template: '' })
class DebouncedSubComponent extends SubComponent {
protected handleEmissionRate(): (obs$: Observable<Vehicle>) => Observable<Vehicle> {
return NGX_SUB_FORM_HANDLE_VALUE_CHANGES_RATE_STRATEGIES.debounce(DEBOUNCE_TIMING);
}
}

class SubComponentWithDefaultValues extends NgxSubFormComponent<Vehicle> {
@Component({ template: '' })
class SubFormWithDefaultValuesComponent extends NgxSubFormComponent<Vehicle> {
protected getFormControls() {
return {
color: new FormControl(),
Expand Down Expand Up @@ -90,12 +94,12 @@ describe(`Common`, () => {
describe(`NgxSubFormComponent`, () => {
let subComponent: SubComponent;
let debouncedSubComponent: DebouncedSubComponent;
let subComponentWithDefaultValues: SubComponentWithDefaultValues;
let subComponentWithDefaultValues: SubFormWithDefaultValuesComponent;

beforeEach((done: () => void) => {
subComponent = new SubComponent();
debouncedSubComponent = new DebouncedSubComponent();
subComponentWithDefaultValues = new SubComponentWithDefaultValues();
subComponentWithDefaultValues = new SubFormWithDefaultValuesComponent();

// we have to call `updateValueAndValidity` within the constructor in an async way
// and here we need to wait for it to run
Expand Down Expand Up @@ -449,6 +453,7 @@ describe(`NgxSubFormComponent`, () => {
numberTwo: number;
}

@Directive()
class ValidatedSubComponent extends NgxSubFormComponent<Numbered> {
protected getFormControls() {
return {
Expand Down Expand Up @@ -481,6 +486,7 @@ describe(`NgxSubFormComponent`, () => {
passwordRepeat: string;
}

@Directive()
class PasswordSubComponent extends NgxSubFormComponent<PasswordForm> {
protected getFormControls() {
return {
Expand Down Expand Up @@ -546,6 +552,7 @@ interface VehicleForm {
vehiclecrewMemberCount: Vehicle['crewMemberCount'] | null;
}

@Component({ template: '' })
class SubRemapComponent extends NgxSubFormRemapComponent<Vehicle, VehicleForm> {
getFormControls() {
// even though optional, if we comment out vehicleColor there should be a TS error
Expand Down Expand Up @@ -652,6 +659,7 @@ interface VehiclesArrayForm {
vehicles: Vehicle[];
}

@Component({ template: '' })
class SubArrayComponent extends NgxSubFormRemapComponent<Vehicle[], VehiclesArrayForm>
implements NgxFormWithArrayControls<VehiclesArrayForm> {
protected getFormControls(): Controls<VehiclesArrayForm> {
Expand Down
File renamed without changes.
34 changes: 34 additions & 0 deletions src/app/app.spec.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,40 @@ context(`EJawa demo`, () => {
});
});

it(`should be able to go from a spaceship to a speeder AND back and restore the original value`, () => {
DOM.list.elements.cy.eq(0).click();
DOM.list.elements.cy.eq(1).click();
DOM.list.elements.cy.eq(0).click();

const x = hardCodedListings[0] as VehicleListing;
const s = x.product as Spaceship;

const expectedObj: FormElement = {
title: x.title,
price: '£' + x.price.toLocaleString(),
inputs: {
id: x.id,
title: x.title,
imageUrl: x.imageUrl,
price: x.price + '',
listingType: x.listingType,
vehicleForm: {
vehicleType: x.product.vehicleType,
spaceshipForm: {
color: s.color,
canFire: s.canFire,
crewMembers: s.crewMembers,
wingCount: s.wingCount,
},
},
},
};

DOM.form.cy.should($el => {
expect(getFormValue($el, VehicleType.SPACESHIP)).to.eql(expectedObj);
});
});

it(`should display the (nested) errors from the form`, () => {
DOM.createNewButton.click();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, forwardRef } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { createForm, FormType, NgxSubForm, subformComponentProviders } from 'ngx-sub-form/new';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form/new';
import { AssassinDroid, AssassinDroidWeapon, DroidType } from 'src/app/interfaces/droid.interface';

export const ASSASSIN_DROID_WEAPON_TEXT: { [K in AssassinDroidWeapon]: string } = {
Expand All @@ -10,7 +10,6 @@ export const ASSASSIN_DROID_WEAPON_TEXT: { [K in AssassinDroidWeapon]: string }
[AssassinDroidWeapon.AXE]: 'Axe',
};

@NgxSubForm()
@Component({
selector: 'app-assassin-droid',
templateUrl: './assassin-droid.component.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Component, forwardRef } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { createForm, FormType, NgxSubForm, subformComponentProviders } from 'ngx-sub-form/new';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form/new';
import { AstromechDroid, AstromechDroidShape, DroidType } from '../../../../../interfaces/droid.interface';

@NgxSubForm()
@Component({
selector: 'app-astromech-droid',
templateUrl: './astromech-droid.component.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, forwardRef } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { createForm, FormType, NgxSubForm, subformComponentProviders } from 'ngx-sub-form/new';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form/new';
import {
AssassinDroid,
AstromechDroid,
Expand All @@ -19,7 +19,6 @@ interface OneDroidForm {
droidType: DroidType | null;
}

@NgxSubForm()
@Component({
selector: 'app-droid-product',
templateUrl: './droid-product.component.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Component, forwardRef } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { createForm, FormType, NgxSubForm, subformComponentProviders } from 'ngx-sub-form/new';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form/new';
import { DroidType, MedicalDroid } from 'src/app/interfaces/droid.interface';

@NgxSubForm()
@Component({
selector: 'app-medical-droid',
templateUrl: './medical-droid.component.html',
Expand Down
Loading

0 comments on commit ba2a391

Please sign in to comment.