Compare commits

3 Commits

Author SHA1 Message Date
Vu Tuan Minh
494fc36e5a Update README.md 2025-01-01 23:14:52 +00:00
dbb8a8e919 readme 2025-01-02 00:12:53 +01:00
04ed988a05 Revert "fini etape 8"
This reverts commit a9bf3781e0.
2024-12-30 03:19:15 +01:00
23 changed files with 397 additions and 6877 deletions

View File

@@ -79,6 +79,26 @@
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n" "builder": "@angular-devkit/build-angular:extract-i18n"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
{
"glob": "**/*",
"input": "public"
}
],
"styles": [
"src/styles.css"
],
"scripts": []
}
} }
} }
} }

View File

@@ -1,10 +0,0 @@
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
"baseUrl": "http://localhost:4200"
},
});

View File

@@ -1,57 +0,0 @@
const login = require("../../fixtures/login");
context("Login and buy stuff", () => {
before(() => {
cy.visit('/');
});
describe("Attempt to sign in", () => {
it('should have link to sign in', () => {
cy.get('[data-cy=signInBtn]').click();
});
it("Type data and submit form", () => {
cy.get('[data-cy=email]')
.type(login.email)
.should("have.value", login.email);
cy.get('[data-cy=password]')
.type(login.password)
.should("have.value", login.password);
cy.get('[data-cy=submit]').click();
});
});
describe("Buy stuff process", () => {
it('url should be /shop', () => {
cy.url().should("include", "/shop");
});
it('check the cart to be zero', () => {
cy.get('[data-cy=cart]').contains(0);
})
it('click on stuff 2', () => {
cy.get('[data-cy=stuff-1]').contains('Add');
cy.get('[data-cy=stuff-1]').click();
});
it('increment the cart', () => {
cy.get('[data-cy=cart]').contains(1);
})
it('click on cart', () => {
cy.get('[data-cy=cart]').click();
});
it('redirect to cart view', () => {
cy.url().should("include", "/cart");
});
it('purchase stuff and see confirm message', () => {
cy.get('[data-cy=submit]').contains('PURCHASE');
cy.get('[data-cy=submit]').click();
cy.get('[data-cy=success]').contains('Thank you for your purchase');
});
})
});

View File

@@ -1,13 +0,0 @@
describe('AppComponent', () => {
beforeEach(() => {
cy.visit('http://localhost:4200')
})
it('should display title', () => {
cy.get('h1').should('contain', 'pokedemo!')
})
it('should load the page', () => {
cy.get('app-root').should('exist')
})
})

View File

@@ -1,25 +0,0 @@
describe('FilterPokemonPipe', () => {
beforeEach(() => {
cy.visit('http://localhost:4200')
})
it('should test search', () => {
/* class using . */
cy.get('.filter_pokedex').clear()
cy.get('.filter_pokedex').type('charm')
cy.get('.select_pokedex').select(1)
cy.get('button').contains('GO').click()
cy.get('.pokemon').should('be.visible')
})
it('should use combo box', () => {
cy.get('.select_pokedex').select(0)
cy.get('button').contains('GO').click()
cy.get('.pokemon').should('be.visible')
})
it('should navigate to previous pokemon', () => {
cy.get('.select_pokedex').select(1)
cy.get('button').contains('GO').click()
})
})

View File

@@ -1,21 +0,0 @@
describe('Pokemon API Tests', () => {
beforeEach(() => {
cy.visit('http://localhost:4200')
})
it('should get the database', () => {
/*https://docs.cypress.io/api/commands/request*/
cy.request('GET', 'https://pokeapi.co/api/v2/pokemon')
.then((response) => {
// 200 = OK
expect(response.status).to.eq(200)
const pokeData = response.body
expect(pokeData).to.have.property('count')
expect(pokeData.count).to.be.a('number')
expect(pokeData.next).to.be.a('string')
expect(pokeData.results[0]).to.have.property('name')
expect(pokeData.results[0].name).to.eq('bulbasaur')
})
})
})

View File

@@ -1,5 +0,0 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -1,37 +0,0 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }

View File

@@ -1,17 +0,0 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'

View File

@@ -1,199 +0,0 @@
/**
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/configuration
*/
import type {Config} from 'jest';
const config: Config = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls, instances, contexts and results before every test
clearMocks: true,
// Indicates whether the coverage information should be collected while executing the test
collectCoverage: true,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: undefined,
// The directory where Jest should output its coverage files
coverageDirectory: "coverage",
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// Indicates which provider should be used to instrument code for coverage
coverageProvider: "v8",
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: undefined,
// A path to a custom dependency extractor
// dependencyExtractor: undefined,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// The default configuration for fake timers
// fakeTimers: {
// "enableGlobally": false
// },
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: undefined,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: undefined,
// A set of global variables that need to be available in all test environments
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "mjs",
// "cjs",
// "jsx",
// "ts",
// "tsx",
// "json",
// "node"
// ],
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
preset: 'jest-preset-angular',
// Run tests from one or more projects
// projects: undefined,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state before every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: undefined,
// Automatically restore mock state and implementation before every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: undefined,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
// The number of seconds after which a test is considered as slow and reported as such in the results.
// slowTestThreshold: 5,
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
testEnvironment: "jsdom",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
// testMatch: [
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
// ],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: undefined,
// This option allows use of a custom test runner
//testRunner: "jest-circus/runner",
// A map from regular expressions to paths to transformers
// transform: undefined,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/",
// "\\.pnp\\.[^\\/]+$"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: undefined,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};
export default config;

6625
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -6,10 +6,7 @@
"start": "ng serve", "start": "ng serve",
"build": "ng build", "build": "ng build",
"watch": "ng build --watch --configuration development", "watch": "ng build --watch --configuration development",
"test": "jest --verbose", "test": "ng test"
"test:coverage": "jest --coverage",
"test:watch": "jest --watch",
"cypress": "cypress open"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
@@ -22,7 +19,6 @@
"@angular/platform-browser-dynamic": "^18.2.0", "@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0", "@angular/router": "^18.2.0",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
"ts-node": "^10.9.2",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.14.10" "zone.js": "~0.14.10"
}, },
@@ -30,10 +26,13 @@
"@angular-devkit/build-angular": "^18.2.8", "@angular-devkit/build-angular": "^18.2.8",
"@angular/cli": "^18.2.8", "@angular/cli": "^18.2.8",
"@angular/compiler-cli": "^18.2.0", "@angular/compiler-cli": "^18.2.0",
"@types/jest": "^29.5.14", "@types/jasmine": "~5.1.0",
"cypress": "^13.17.0", "jasmine-core": "~5.2.0",
"jest": "^29.7.0", "karma": "~6.4.0",
"jest-preset-angular": "^14.4.2", "karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.5.2" "typescript": "~5.5.2"
} }
} }

View File

@@ -1 +0,0 @@
import 'jest-preset-angular/setup-jest';

View File

@@ -1,44 +1,35 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideRouter } from '@angular/router';
describe('AppComponent', () => { describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
// si AppComponent est un composant standalone imports: [
//imports: [AppComponent], RouterModule.forRoot([])
// si AppComponent n'est PAS un composant standalone ],
declarations: [AppComponent], declarations: [
AppComponent
providers: [
provideHttpClient(),
provideHttpClientTesting(),
provideRouter([]),
], ],
}).compileComponents(); }).compileComponents();
}); });
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create the app', () => { it('should create the app', () => {
expect(component).toBeTruthy(); const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
}); });
it(`should have as title 'pokedemo'`, () => { it(`should have as title 'pokedemo'`, () => {
expect(component.title).toEqual('pokedemo'); const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('pokedemo');
}); });
it('should render the title', () => { it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement; const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('pokedemo!'); expect(compiled.querySelector('h1')?.textContent).toContain('Hello, pokedemo');
}); });
}); });

View File

@@ -4,7 +4,7 @@ import { Component } from '@angular/core';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrl: './app.component.css', styleUrl: './app.component.css'
}) })
export class AppComponent { export class AppComponent {
title = 'pokedemo'; title = 'pokedemo';

View File

@@ -1,45 +1,8 @@
import { pipe } from 'rxjs';
import { FilterPokemonPipePipe } from './filter-pokemon--pipe.pipe'; import { FilterPokemonPipePipe } from './filter-pokemon--pipe.pipe';
describe('FilterPokemonPipePipe', () => { describe('FilterPokemonPipePipe', () => {
let pipe: FilterPokemonPipePipe;
beforeEach(() => {
pipe = new FilterPokemonPipePipe();
});
it('create an instance', () => { it('create an instance', () => {
const pipe = new FilterPokemonPipePipe(); const pipe = new FilterPokemonPipePipe();
expect(pipe).toBeTruthy(); expect(pipe).toBeTruthy();
}); });
it('search is undefined so return original', () => {
const pokes = [{ name: 'bulbasaur' }, { name: 'ivysaur' }];
const result = pipe.transform(pokes, 'name');
expect(result).toEqual(pokes);
});
it('filtre by property', () => {
const pokes = [{ name: 'bulbasaur' }, { name: 'ivysaur' }, { name: 'venusaur' }];
const result = pipe.transform(pokes, 'name', 'ivy');
expect(result).toEqual([{ name: 'ivysaur' }]);
});
it('pokes is undefined', () => {
const result = pipe.transform(undefined, 'name', 'ivy');
expect(result).toEqual([]);
});
it('property is undefined', () => {
const pokes = [{ name: 'bulbasaur' }, { name: 'ivysaur' }];
const result = pipe.transform(pokes, undefined, 'ivy');
expect(result).toEqual([]);
});
it('emty array because no matched', () => {
const pokes = [{ name: 'bulbasaur' }, { name: 'ivysaur' }];
const result = pipe.transform(pokes, 'name', 'charmander');
expect(result).toEqual([]);
});
}); });

View File

@@ -1,67 +1,16 @@
import { ComponentFixture, fakeAsync, flush, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PokeDetail, Pokemon } from '../pokemon';
import { PokeAPIServiceService } from '../poke-apiservice.service';
import { PokeShareInfoService } from '../poke-share-info.service';
import { MyComponentComponent } from './my-component.component'; import { MyComponentComponent } from './my-component.component';
describe('MyComponentComponent', () => { describe('MyComponentComponent', () => {
let component: MyComponentComponent; let component: MyComponentComponent;
let fixture: ComponentFixture<MyComponentComponent>; let fixture: ComponentFixture<MyComponentComponent>;
let pokeAPI: PokeAPIServiceService;
let pokeShare: PokeShareInfoService;
const mockPokemonList = {
results: [
{ name: 'bulbasaur' },
{ name: 'ivysaur' },
{ name: 'venusaur' }
]
};
const mockPokeDetail: PokeDetail = {
id: 1,
name: 'bulbasaur',
height: 7,
weight: 69,
types: [],
sprites: {
front_default: 'https://raw.githubuserco…er/sprites/pokemon/1.png"',
back_default: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png',
back_female: null,
back_shiny: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png',
back_shiny_female: null,
front_female: null,
front_shiny: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png',
front_shiny_female: null
},
abilities: [],
base_experience: 64,
cries: undefined,
forms: [],
game_indices: [],
held_items: [],
is_default: true,
location_area_encounters: 'https://pokeapi.co/api/v2/pokemon/1/encounters',
moves: [],
order: 1,
past_abilities: [],
past_types: [],
species: undefined,
stats: []
};
beforeEach(async () => { beforeEach(async () => {
pokeAPI = jasmine.createSpyObj('PokeAPIServiceService', ['getPokemons', 'getPokemonInfo']);
pokeShare = jasmine.createSpyObj('PokeShareInfoService', ['setValue']);
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [MyComponentComponent] declarations: [MyComponentComponent]
, })
providers: [ .compileComponents();
{ provide: PokeAPIServiceService, useValue: pokeAPI },
{ provide: PokeShareInfoService, useValue: pokeShare}
]
}).compileComponents();
fixture = TestBed.createComponent(MyComponentComponent); fixture = TestBed.createComponent(MyComponentComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
@@ -71,25 +20,4 @@ describe('MyComponentComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
//ngOnINIT
it('should load pokemon list on init', fakeAsync(() => {
fixture.detectChanges();
flush();
expect(pokeAPI.getPokemons).toHaveBeenCalled();
expect(component.pokes.length).toBe(3);
expect(component.pokes[0]).toEqual(jasmine.objectContaining({
id: '1',
name: 'bulbasaur'
}));
}));
it('go()', fakeAsync(() => {
component.selectedPokeId = '1';
component.go();
flush();
expect(pokeAPI.getPokemonInfo).toHaveBeenCalledWith('1');
expect(component.pokeDetail).toEqual(mockPokeDetail);
}));
}); });

View File

@@ -1,40 +1,16 @@
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { HttpTestingController } from '@angular/common/http/testing';
import { PokeAPIServiceService } from './poke-apiservice.service'; import { PokeAPIServiceService } from './poke-apiservice.service';
import { PokeServiceRes, PokeDetail } from './pokemon';
describe('PokeAPIServiceService', () => { describe('PokeAPIServiceService', () => {
let service: PokeAPIServiceService; let service: PokeAPIServiceService;
let httpMock: HttpTestingController;
beforeEach(() => { beforeEach(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({});
providers: [PokeAPIServiceService],
});
service = TestBed.inject(PokeAPIServiceService); service = TestBed.inject(PokeAPIServiceService);
httpMock = TestBed.inject(HttpTestingController);
}); });
it('should be created', () => { it('should be created', () => {
expect(service).toBeTruthy(); expect(service).toBeTruthy();
}); });
/*
it('should create', () => {
const mock: PokeServiceRes = {
results: [
{ name: 'bulbasaur', url: 'https://pokeapi.co/api/v2/pokemon/1/' },
{ name: 'ivysaur', url: 'https://pokeapi.co/api/v2/pokemon/2/' },
],
count: 0,
next: '',
previous: null
};
service.getPokemons().subscribe((response) => {
expect(response).toEqual(mock);
expect(response.results.length).toBe(2);
expect(response.results[0].name).toBe('bulbasaur');
});
});
*/
}); });

View File

@@ -13,14 +13,4 @@ describe('PokeShareInfoService', () => {
it('should be created', () => { it('should be created', () => {
expect(service).toBeTruthy(); expect(service).toBeTruthy();
}); });
it('should set value when setValue is called', (done) => {
const testValue = 'Test Value';
service.getObservable().subscribe((value) => {
expect(value).toBe(testValue);
done();
});
service.setValue(testValue);
});
}); });

View File

@@ -1,16 +1,14 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PokedetailComponent } from './pokedetail.component'; import { PokedetailComponent } from './pokedetail.component';
import { PokeShareInfoService } from '../poke-share-info.service';
describe('PokedetailComponent', () => { describe('PokedetailComponent', () => {
let component: PokedetailComponent; let component: PokedetailComponent;
let fixture: ComponentFixture<PokedetailComponent>; let fixture: ComponentFixture<PokedetailComponent>;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [PokedetailComponent], declarations: [PokedetailComponent]
providers: [PokeShareInfoService]
}) })
.compileComponents(); .compileComponents();
@@ -19,7 +17,7 @@ describe('PokedetailComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
}); });
it('should be created', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
}); });

View File

@@ -2,9 +2,6 @@ import { Pokemon } from './pokemon';
describe('Pokemon', () => { describe('Pokemon', () => {
it('should create an instance', () => { it('should create an instance', () => {
const pokemon = new Pokemon('1', 'Bulbasaur'); //expect(new Pokemon("1","test")).toBeTruthy();
expect(pokemon).toBeTruthy();
expect(pokemon.id).toBe('1');
expect(pokemon.name).toBe('Bulbasaur');
}); });
}); });

View File

@@ -191,7 +191,13 @@ export interface Type {
type: Species; type: Species;
} }
export class Pokemon { export class Pokemon {
constructor(public id:string, public name:string){ constructor(public id:string, public name:string){
} }
} }

View File

@@ -5,10 +5,8 @@
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/spec", "outDir": "./out-tsc/spec",
"types": [ "types": [
"jest" "jasmine"
], ]
"esModuleInterop": true,
"emitDecoratorMetadata": true
}, },
"include": [ "include": [
"src/**/*.spec.ts", "src/**/*.spec.ts",