Skip to content

Commit 8be44f3

Browse files
committed
Various improvements
- Typed arguments and methods - Generate entire GraphQL service from running Spring Boot instance - Corrected tests, now `ng test` actually runs w/o errors
1 parent bdab51c commit 8be44f3

20 files changed

+479
-449
lines changed

frontend/angular.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"src/tsconfig.spec.json"
8888
],
8989
"exclude": [
90+
"src/app/api/index.ts",
9091
"**/node_modules/**"
9192
]
9293
}
@@ -134,4 +135,4 @@
134135
"typescriptMismatch": false
135136
}
136137
}
137-
}
138+
}

frontend/codegen.yml

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
schema:
22
- http://localhost:8080/graphql
33
documents:
4-
- src/app/graphql/all-cars.query.graphql
5-
- src/app/graphql/delete-car.mutation.graphql
6-
- src/app/graphql/get-car.query.graphql
7-
- src/app/graphql/save-car.mutation.graphql
4+
- src/app/graphql/delete-car.graphql
5+
- src/app/graphql/get-car.graphql
6+
- src/app/graphql/list-cars.graphql
7+
- src/app/graphql/save-car.graphql
88
config:
99
resolvers: false
10+
overwrite: true
1011
generates:
1112
src/app/generated/graphql.ts:
1213
config:
14+
noNamespaces: true
1315
resolvers: false
16+
enumsAsTypes: true
17+
avoidOptionals: true
18+
immutableTypes: true
19+
scalars:
20+
Long: number
1421
plugins:
1522
- typescript-common
1623
- typescript-client
24+
- typescript-server
1725
- typescript-apollo-angular
1826
require: []

frontend/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
"graphql": "CODEGEN_RESOLVERS=false gql-gen"
1313
},
1414
"private": true,
15+
"config": {
16+
"graphql": "http://localhost:8080/graphql"
17+
},
1518
"dependencies": {
1619
"@angular/animations": "~7.1.0",
1720
"@angular/cdk": "~7.1.0",
@@ -50,6 +53,7 @@
5053
"graphql-code-generator": "^0.14.0",
5154
"graphql-codegen-apollo-angular-template": "^0.14.0",
5255
"graphql-codegen-introspection-template": "^0.14.0",
56+
"graphql-codegen-typescript-server": "^0.14.0",
5357
"jasmine-core": "~3.3.0",
5458
"jasmine-spec-reporter": "~4.2.1",
5559
"karma": "~3.1.1",

frontend/src/app/api/index.ts

+206
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
export interface CarInput {
2+
/** A car's id */
3+
readonly id: number | null;
4+
/** A car's name */
5+
readonly name: string | null;
6+
}
7+
8+
/** Long type */
9+
export type Long = number;
10+
11+
// ====================================================
12+
// Documents
13+
// ====================================================
14+
15+
export type DeleteCarVariables = {
16+
readonly id: number;
17+
};
18+
19+
export type DeleteCarMutation = {
20+
readonly __typename?: 'Mutation';
21+
22+
readonly deleteCar: boolean | null;
23+
};
24+
25+
export type GetCarVariables = {
26+
readonly id: number;
27+
};
28+
29+
export type GetCarQuery = {
30+
readonly __typename?: 'Query';
31+
32+
readonly car: GetCarCar | null;
33+
};
34+
35+
export type GetCarCar = {
36+
readonly __typename?: 'Car';
37+
38+
readonly id: number | null;
39+
40+
readonly name: string | null;
41+
42+
readonly giphyUrl: string | null;
43+
};
44+
45+
export type ListCarsVariables = {};
46+
47+
export type ListCarsQuery = {
48+
readonly __typename?: 'Query';
49+
50+
readonly cars: ReadonlyArray<ListCarsCars> | null;
51+
};
52+
53+
export type ListCarsCars = {
54+
readonly __typename?: 'Car';
55+
56+
readonly id: number | null;
57+
58+
readonly name: string | null;
59+
60+
readonly giphyUrl: string | null;
61+
};
62+
63+
export type SaveCarVariables = {
64+
readonly car: CarInput;
65+
};
66+
67+
export type SaveCarMutation = {
68+
readonly __typename?: 'Mutation';
69+
70+
readonly saveCar: SaveCarSaveCar | null;
71+
};
72+
73+
export type SaveCarSaveCar = {
74+
readonly __typename?: 'Car';
75+
76+
readonly id: number | null;
77+
78+
readonly name: string | null;
79+
80+
readonly giphyUrl: string | null;
81+
};
82+
83+
// ====================================================
84+
// Scalars
85+
// ====================================================
86+
87+
// ====================================================
88+
// Types
89+
// ====================================================
90+
91+
/** Query root type */
92+
export interface Query {
93+
readonly cars: ReadonlyArray<Car> | null;
94+
95+
readonly car: Car | null;
96+
}
97+
98+
export interface Car {
99+
readonly giphyUrl: string | null;
100+
101+
readonly id: number | null;
102+
103+
readonly isCool: boolean;
104+
105+
readonly name: string | null;
106+
}
107+
108+
/** Mutation root type */
109+
export interface Mutation {
110+
readonly deleteCar: boolean | null;
111+
112+
readonly saveCar: Car | null;
113+
}
114+
115+
// ====================================================
116+
// Arguments
117+
// ====================================================
118+
119+
export interface CarQueryArgs {
120+
id: number | null;
121+
}
122+
export interface DeleteCarMutationArgs {
123+
id: number | null;
124+
}
125+
export interface SaveCarMutationArgs {
126+
car: CarInput | null;
127+
}
128+
129+
// ====================================================
130+
// START: Apollo Angular template
131+
// ====================================================
132+
133+
import { Injectable } from '@angular/core';
134+
import * as Apollo from 'apollo-angular';
135+
136+
import gql from 'graphql-tag';
137+
138+
// ====================================================
139+
// Apollo Services
140+
// ====================================================
141+
142+
@Injectable({
143+
providedIn: 'root'
144+
})
145+
export class DeleteCarGQL extends Apollo.Mutation<
146+
DeleteCarMutation,
147+
DeleteCarVariables
148+
> {
149+
document: any = gql`
150+
mutation DeleteCar($id: Long!) {
151+
deleteCar(id: $id)
152+
}
153+
`;
154+
}
155+
@Injectable({
156+
providedIn: 'root'
157+
})
158+
export class GetCarGQL extends Apollo.Query<GetCarQuery, GetCarVariables> {
159+
document: any = gql`
160+
query GetCar($id: Long!) {
161+
car(id: $id) {
162+
id
163+
name
164+
giphyUrl
165+
}
166+
}
167+
`;
168+
}
169+
@Injectable({
170+
providedIn: 'root'
171+
})
172+
export class ListCarsGQL extends Apollo.Query<
173+
ListCarsQuery,
174+
ListCarsVariables
175+
> {
176+
document: any = gql`
177+
query ListCars {
178+
cars {
179+
id
180+
name
181+
giphyUrl
182+
}
183+
}
184+
`;
185+
}
186+
@Injectable({
187+
providedIn: 'root'
188+
})
189+
export class SaveCarGQL extends Apollo.Mutation<
190+
SaveCarMutation,
191+
SaveCarVariables
192+
> {
193+
document: any = gql`
194+
mutation SaveCar($car: CarInput!) {
195+
saveCar(car: $car) {
196+
id
197+
name
198+
giphyUrl
199+
}
200+
}
201+
`;
202+
}
203+
204+
// ====================================================
205+
// END: Apollo Angular template
206+
// ====================================================
+12-5
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
import { async, TestBed } from '@angular/core/testing';
2+
import { RouterTestingModule } from '@angular/router/testing';
3+
4+
import { GraphQLModule } from './graphql.module';
5+
import { MaterialModule } from './material.module';
6+
27
import { AppComponent } from './app.component';
38

49
describe('AppComponent', () => {
510
beforeEach(async(() => {
611
TestBed.configureTestingModule({
7-
declarations: [
8-
AppComponent
9-
],
12+
declarations: [AppComponent],
13+
imports: [RouterTestingModule, GraphQLModule, MaterialModule]
1014
}).compileComponents();
1115
}));
16+
1217
it('should create the app', async(() => {
1318
const fixture = TestBed.createComponent(AppComponent);
1419
const app = fixture.debugElement.componentInstance;
1520
expect(app).toBeTruthy();
1621
}));
22+
1723
it(`should have as title 'app'`, async(() => {
1824
const fixture = TestBed.createComponent(AppComponent);
1925
const app = fixture.debugElement.componentInstance;
20-
expect(app.title).toEqual('app');
26+
expect(app.title).toEqual('CRUD app');
2127
}));
28+
2229
it('should render title in a h1 tag', async(() => {
2330
const fixture = TestBed.createComponent(AppComponent);
2431
fixture.detectChanges();
2532
const compiled = fixture.debugElement.nativeElement;
26-
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
33+
expect(compiled.querySelector('span').textContent).toContain('Welcome to CRUD app!');
2734
}));
2835
});

frontend/src/app/app.module.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { BrowserModule } from '@angular/platform-browser';
22
import { NgModule } from '@angular/core';
33
import { RouterModule, Routes } from '@angular/router';
44
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5-
import { CovalentDialogsModule } from '@covalent/core';
65
import { FlexLayoutModule } from '@angular/flex-layout';
6+
import { FormsModule } from '@angular/forms';
7+
8+
import { CovalentDialogsModule } from '@covalent/core';
79

810
import { AppComponent } from '@app/app.component';
911
import { GraphQLModule } from '@app/graphql.module';
@@ -24,10 +26,13 @@ const routes: Routes = [
2426
BrowserModule,
2527
BrowserAnimationsModule,
2628
FlexLayoutModule,
27-
CovalentDialogsModule,
29+
FormsModule,
2830
RouterModule.forRoot(routes),
31+
32+
CovalentDialogsModule,
2933
GraphQLModule,
3034
MaterialModule,
35+
3136
CarsModule
3237
],
3338
providers: [],

frontend/src/app/cars/car-edit/car-edit.component.spec.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1+
import { FormsModule } from '@angular/forms';
2+
13
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4+
import { RouterTestingModule } from '@angular/router/testing';
5+
6+
import { CovalentDialogsModule } from '@covalent/core';
7+
8+
import { GraphQLModule } from '../../graphql.module';
9+
import { MaterialModule } from '../../material.module';
210

311
import { CarEditComponent } from './car-edit.component';
412

@@ -8,7 +16,15 @@ describe('CarEditComponent', () => {
816

917
beforeEach(async(() => {
1018
TestBed.configureTestingModule({
11-
declarations: [CarEditComponent]
19+
declarations: [CarEditComponent],
20+
imports: [
21+
FormsModule,
22+
RouterTestingModule,
23+
24+
CovalentDialogsModule,
25+
GraphQLModule,
26+
MaterialModule,
27+
],
1228
})
1329
.compileComponents();
1430
}));

0 commit comments

Comments
 (0)