Skip to content

Commit

Permalink
Add coverage preprocessor, refactor style, and adjust tests
Browse files Browse the repository at this point in the history
Added TS files to the coverage preprocessor in karma.conf.js and updated coverage reporters. Refactored fight component to use single quotes and improved test cases for hp-event component to handle both regeneration and damage scenarios.
  • Loading branch information
dhAlcojor committed Aug 19, 2024
1 parent ee5ce76 commit 02304c9
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 68 deletions.
5 changes: 4 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ module.exports = function (config) {
lines: 80,
},
},
preprocessors: {
"src/**/*.ts": ["coverage"],
},
coverageReporter: {
dir: require("path").join(__dirname, "./coverage/comic-fight"),
subdir: ".",
reporters: [{ type: "html" }, { type: "text-summary" }],
reporters: [{ type: "html" }, { type: "text" }],
},
reporters: ["progress", "kjhtml"],
browsers: ["Chrome"],
Expand Down
37 changes: 28 additions & 9 deletions src/app/components/hp-event/hp-event.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'
import { HpEventComponent } from './hp-event.component'
import { Component } from '@angular/core'
import { appConfig } from '../../app.config'

const event = {
hpChange: 10,
left: 10,
top: 10,
}
import { HPEvent } from '../event/event.component'

describe('HpEventComponent', () => {
let component: HpEventComponent
Expand All @@ -27,12 +22,32 @@ describe('HpEventComponent', () => {
fixture = TestBed.createComponent(TestHostComponent)
testHost = fixture.componentInstance
hpEventEl = fixture.nativeElement.querySelector('cf-hp-event')
fixture.detectChanges()
})

it('should create the hp event', () => {
it('should create the hp regenerate event', () => {
testHost.event = {
hpChange: 10,
left: 10,
top: 10,
}
fixture.detectChanges()
const span = hpEventEl.querySelector('span') as HTMLElement
expect(span.className).toContain('text-regenerate')
expect(hpEventEl.textContent).toContain('+10')
})

it('should create the hp damage event', () => {
testHost.event = {
hpChange: -10,
left: 10,
top: 10,
}
fixture.detectChanges()
hpEventEl = fixture.nativeElement.querySelector('cf-hp-event')
const span = hpEventEl.querySelector('span') as HTMLElement
expect(span.className).toContain('text-damage')
expect(hpEventEl.textContent).toContain('-10')
})
})

/*
Expand All @@ -45,5 +60,9 @@ describe('HpEventComponent', () => {
template: ` <cf-hp-event [hpEvent]="event"></cf-hp-event>`,
})
class TestHostComponent {
event = event
event: HPEvent = {
hpChange: 0,
left: 0,
top: 0,
}
}
3 changes: 1 addition & 2 deletions src/app/fight/fight.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'

import { FightComponent } from './fight.component'
import { provideRouter } from '@angular/router'
import { AboutComponent } from '../about/about.component'
import { provideHttpClient } from '@angular/common/http'
import { provideHttpClientTesting } from '@angular/common/http/testing'

Expand All @@ -14,7 +13,7 @@ describe('FightComponent', () => {
await TestBed.configureTestingModule({
imports: [FightComponent],
providers: [
provideRouter([{ path: '**', component: AboutComponent }]),
provideRouter([{ path: '**', component: FightComponent }]),
provideHttpClient(),
provideHttpClientTesting(),
],
Expand Down
145 changes: 89 additions & 56 deletions src/app/fight/fight.component.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,55 @@
import { Component, ElementRef, Input, OnInit, signal, WritableSignal } from "@angular/core"
import { RouterLink } from "@angular/router"
import { Character, DEADPOOL, WOLVERINE } from "../characters/character"
import { Event, EventComponent, HPEvent, RoundEvent } from "../components/event/event.component"
import { HealthBarComponent } from "../components/health-bar/health-bar.component"
import { getRandomFromRange } from "../utils"
import { HeaderComponent } from "../header/header.component";
import { HpEventComponent } from "../components/hp-event/hp-event.component";
import {
Component,
ElementRef,
Input,
OnInit,
signal,
WritableSignal,
} from '@angular/core'
import { RouterLink } from '@angular/router'
import { Character, DEADPOOL, WOLVERINE } from '../characters/character'
import {
Event,
EventComponent,
HPEvent,
RoundEvent,
} from '../components/event/event.component'
import { HealthBarComponent } from '../components/health-bar/health-bar.component'
import { getRandomFromRange } from '../utils'
import { HeaderComponent } from '../header/header.component'
import { HpEventComponent } from '../components/hp-event/hp-event.component'

const DELAY = 1000

@Component({
selector: "cf-fight",
selector: 'cf-fight',
standalone: true,
imports: [HealthBarComponent, EventComponent, RouterLink, HeaderComponent, HpEventComponent],
templateUrl: "./fight.component.html",
styleUrl: "./fight.component.css",
imports: [
HealthBarComponent,
EventComponent,
RouterLink,
HeaderComponent,
HpEventComponent,
],
templateUrl: './fight.component.html',
styleUrl: './fight.component.css',
})
export class FightComponent implements OnInit {
leftCharacter = DEADPOOL
leftCharacterHealth = signal(this.leftCharacter.health)
leftCharacterIdleImage?: HTMLImageElement
leftLoserClass = signal("")
leftLoserClass = signal('')
rightCharacter = WOLVERINE
rightCharacterHealth = signal(this.rightCharacter.health)
rightCharacterIdleImage?: HTMLImageElement
rightLoserClass = signal("")
rightLoserClass = signal('')
currentRound = signal(0)
roundEvents = signal<RoundEvent[]>([])
hpEvents = signal<HPEvent[]>([])
winnerEvent = signal<Event | null>(null)
gameOver = signal(false)
doubleKoBackgroundStyle = `linear-gradient(90deg, ${this.leftCharacter.mainColor} 0%, ${this.rightCharacter.mainColor} 100%)`

constructor(public elementRef: ElementRef) {}

/** Input parameter read from the URL path */
@Input()
set leftCharacterInitialHealth(value: number) {
Expand All @@ -46,8 +64,6 @@ export class FightComponent implements OnInit {
this.rightCharacter.maxHealth = value
}

constructor(public elementRef: ElementRef) {}

ngOnInit(): void {
this.runFight()
}
Expand All @@ -58,8 +74,8 @@ export class FightComponent implements OnInit {
this.rightCharacterHealth.set(this.rightCharacter.maxHealth)
this.leftCharacter.canAttack = true
this.rightCharacter.canAttack = true
this.leftLoserClass.set("")
this.rightLoserClass.set("")
this.leftLoserClass.set('')
this.rightLoserClass.set('')
this.currentRound.set(0)
this.roundEvents.set([])
this.winnerEvent.set(null)
Expand Down Expand Up @@ -95,10 +111,7 @@ export class FightComponent implements OnInit {
round: this.currentRound(),
events: [leftEvent, rightEvent],
}
this.roundEvents.set([
roundEvent,
...this.roundEvents(),
])
this.roundEvents.set([roundEvent, ...this.roundEvents()])
}

/**
Expand All @@ -113,12 +126,12 @@ export class FightComponent implements OnInit {
defender: Character,
defenderHealth: WritableSignal<number>,
): Event {
const side = attacker === this.leftCharacter ? "left" : "right"
const side = attacker === this.leftCharacter ? 'left' : 'right'
if (attacker.canAttack) {
const isDodged = Math.random() < defender.dodgeRating
if (isDodged) {
return {
type: "dodge",
type: 'dodge',
attacker: attacker.name,
defender: defender.name,
alignment: side,
Expand All @@ -135,10 +148,13 @@ export class FightComponent implements OnInit {
critical = true
}

this.showDamage(attacker === this.leftCharacter ? "right" : "left", -damage)
this.showDamage(
attacker === this.leftCharacter ? 'right' : 'left',
-damage,
)

return {
type: "attack",
type: 'attack',
attacker: attacker.name,
defender: defender.name,
damage,
Expand All @@ -148,19 +164,23 @@ export class FightComponent implements OnInit {
}
} else {
attacker.canAttack = true
let regen = 0
let regen: number
if (attacker === this.leftCharacter) {
regen = Math.floor(this.leftCharacter.maxHealth * attacker.regenerationRating)
console.log("regenerating", this.leftCharacterHealth(), regen)
regen = Math.floor(
this.leftCharacter.maxHealth * attacker.regenerationRating,
)
console.log('regenerating', this.leftCharacterHealth(), regen)
this.leftCharacterHealth.set(this.leftCharacterHealth() + regen)
} else {
regen = Math.floor(this.rightCharacter.maxHealth * attacker.regenerationRating)
console.log("regenerating", this.rightCharacterHealth(), regen)
regen = Math.floor(
this.rightCharacter.maxHealth * attacker.regenerationRating,
)
console.log('regenerating', this.rightCharacterHealth(), regen)
this.rightCharacterHealth.set(this.rightCharacterHealth() + regen)
}
this.showDamage(side, regen)
return {
type: "regenerate",
type: 'regenerate',
attacker: attacker.name,
defender: defender.name,
regen,
Expand All @@ -173,51 +193,64 @@ export class FightComponent implements OnInit {
declareWinner() {
if (this.leftCharacterHealth() === 0 && this.rightCharacterHealth() === 0) {
const event: Event = {
type: "winner",
attacker: "",
defender: "",
alignment: "center",
color: "black",
type: 'winner',
attacker: '',
defender: '',
alignment: 'center',
color: 'black',
}
this.winnerEvent.set(event)
return
}

const winner = this.leftCharacterHealth() > 0 ? this.leftCharacter : this.rightCharacter
const winner =
this.leftCharacterHealth() > 0 ? this.leftCharacter : this.rightCharacter
const event: Event = {
type: "winner",
type: 'winner',
attacker: winner.name,
defender: "",
alignment: "center",
defender: '',
alignment: 'center',
color: winner.mainColor,
}
this.winnerEvent.set(event)
const damageTexts = this.elementRef.nativeElement.querySelectorAll(".damage-text")
const damageTexts =
this.elementRef.nativeElement.querySelectorAll('.damage-text')
damageTexts.forEach((damageText: HTMLElement) => {
damageText.textContent = ""
damageText.textContent = ''
})

if (this.leftCharacterHealth() === 0) {
this.leftLoserClass.set("grayscale")
this.leftLoserClass.set('grayscale')
}

if (this.rightCharacterHealth() === 0) {
this.rightLoserClass.set("grayscale")
this.rightLoserClass.set('grayscale')
}
}

showDamage(character: "left" | "right", damage: number) {
showDamage(character: 'left' | 'right', damage: number) {
const el = this.elementRef.nativeElement
const image = el.querySelector(`#${character}CharacterIdleImage`) as HTMLImageElement
const image = el.querySelector(
`#${character}CharacterIdleImage`,
) as HTMLImageElement
const boundingRect = image.getBoundingClientRect()
const offset = 20
const x = getRandomFromRange(boundingRect.left + offset, boundingRect.right - offset)
const y = getRandomFromRange(boundingRect.top + offset, boundingRect.bottom - offset)
this.hpEvents.set([...this.hpEvents(), {
hpChange: damage,
left: x,
top: y,
}])
const x = getRandomFromRange(
boundingRect.left + offset,
boundingRect.right - offset,
)
const y = getRandomFromRange(
boundingRect.top + offset,
boundingRect.bottom - offset,
)
this.hpEvents.set([
...this.hpEvents(),
{
hpChange: damage,
left: x,
top: y,
},
])
}

delay(ms: number) {
Expand Down

0 comments on commit 02304c9

Please sign in to comment.