Skip to content

Commit

Permalink
fix: Dependency now checks against modified values instead of actua…
Browse files Browse the repository at this point in the history
…l values when checking numeric properties.
  • Loading branch information
spuxx1701 committed Jun 9, 2024
1 parent 3d46bf1 commit 2bcbe2c
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 21 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [UNRELEASED]

### Fixed

- `Dependency` now checks against modified values instead of actual values when checking numeric properties.

## [0.1.0] 2024-06-09

🌟 Initial release.
123 changes: 106 additions & 17 deletions lib/dependency/dependency.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, expect, test } from 'vitest';
import { describe, expect, it } from 'vitest';
import { GameObject } from '../game-object';
import { Dependency } from './dependency';
import { Modifier } from '@/modifier';

class UnrelatedObject extends GameObject {
name = 'unrelated.object' as any;
Expand All @@ -25,7 +26,7 @@ describe('regular dependencies', () => {
declare dependencies: Dependency<DependencyTarget>[];
}

test('should pass if the dependency is met (existence check)', () => {
it('should pass if the dependency is met (existence check)', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -37,7 +38,7 @@ describe('regular dependencies', () => {
expect(result).toBe(true);
});

test("should fail if the dependency isn't met (existence check)", () => {
it("should fail if the dependency isn't met (existence check)", () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -50,7 +51,7 @@ describe('regular dependencies', () => {
expect(result).toHaveLength(1);
});

test('should pass if the dependency is met (exact value check)', () => {
it('should pass if the dependency is met (exact value check)', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -64,7 +65,7 @@ describe('regular dependencies', () => {
expect(result).toBe(true);
});

test("should fail if the dependency isn't met (exact value check)", () => {
it("should fail if the dependency isn't met (exact value check)", () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -79,7 +80,7 @@ describe('regular dependencies', () => {
expect(result).toHaveLength(1);
});

test('should pass if the dependency is met (numeric value check)', () => {
it('should pass if the dependency is met (numeric value check)', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -93,7 +94,7 @@ describe('regular dependencies', () => {
expect(result).toBe(true);
});

test("should fail if the dependency isn't met (numeric value check)", () => {
it("should fail if the dependency isn't met (numeric value check)", () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -108,7 +109,50 @@ describe('regular dependencies', () => {
expect(result).toHaveLength(1);
});

test('should fail if the referenced child collection does not exist on the entity', () => {
it('should check against the modified value and pass (numeric value check)', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
name: 'dependency.target',
key: 'answer',
value: 52,
}),
];
const entity = new Entity({} as any);
entity.modifiers = [
new Modifier<DependencyTarget>({
targetName: 'dependency.target' as any,
keys: ['answer'],
amount: 10,
}),
];
const result = dependent.checkDependencies(entity);
expect(result).toBe(true);
});

it('should check against the modified value and fail (numeric value check)', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
name: 'dependency.target',
key: 'answer',
value: 52,
}),
];
dependent.modifiers = [
new Modifier<DependencyTarget>({
targetName: 'dependency.target' as any,
keys: ['answer'],
amount: -10,
}),
];
const entity = new Entity({} as any);
const result = dependent.checkDependencies(entity);
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
});

it('should fail if the referenced child collection does not exist on the entity', () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -121,7 +165,7 @@ describe('regular dependencies', () => {
expect(result).toHaveLength(1);
});

test("should throw an error if the dependency references a value that doesn't exist", () => {
it("should throw an error if the dependency references a value that doesn't exist", () => {
const dependent = new Dependent({} as any);
dependent.dependencies = [
new Dependency({
Expand All @@ -141,7 +185,7 @@ describe('conflict dependencies', () => {
declare dependencies: Dependency<DependencyTarget>[];
}

test('should pass if there is no conflict (existence check)', () => {
it('should pass if there is no conflict (existence check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -154,7 +198,7 @@ describe('conflict dependencies', () => {
expect(result).toBe(true);
});

test('should fail if there is a conflict (existence check)', () => {
it('should fail if there is a conflict (existence check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -168,7 +212,7 @@ describe('conflict dependencies', () => {
expect(result).toHaveLength(1);
});

test('should pass if there is no conflict (exact value check)', () => {
it('should pass if there is no conflict (exact value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -183,7 +227,7 @@ describe('conflict dependencies', () => {
expect(result).toBe(true);
});

test('should fail if there is a conflict (exact value check)', () => {
it('should fail if there is a conflict (exact value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -199,7 +243,7 @@ describe('conflict dependencies', () => {
expect(result).toHaveLength(1);
});

test('should pass if there is no conflict (numeric value check)', () => {
it('should pass if there is no conflict (numeric value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -214,7 +258,7 @@ describe('conflict dependencies', () => {
expect(result).toBe(true);
});

test('should fail if there is a conflict (numeric value check)', () => {
it('should fail if there is a conflict (numeric value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -230,7 +274,52 @@ describe('conflict dependencies', () => {
expect(result).toHaveLength(1);
});

test('should pass if the referenced child collection does not exist on the entity', () => {
it('should check against the modified value and pass (numeric value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
name: 'dependency.target',
key: 'answer',
value: 42,
isConflict: true,
}),
];
const entity = new Entity({} as any);
entity.modifiers = [
new Modifier<DependencyTarget>({
targetName: 'dependency.target' as any,
keys: ['answer'],
amount: -10,
}),
];
const result = conflict.checkDependencies(entity);
expect(result).toBe(true);
});

it('should check against the modified value and fail (numeric value check)', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
name: 'dependency.target',
key: 'answer',
value: 42,
isConflict: true,
}),
];
const entity = new Entity({} as any);
entity.modifiers = [
new Modifier<DependencyTarget>({
targetName: 'dependency.target' as any,
keys: ['answer'],
amount: 10,
}),
];
const result = conflict.checkDependencies(entity);
expect(result).toBeInstanceOf(Array);
expect(result).toHaveLength(1);
});

it('should pass if the referenced child collection does not exist on the entity', () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand All @@ -242,7 +331,7 @@ describe('conflict dependencies', () => {
expect(conflict.checkDependencies(entity)).toBe(true);
});

test("should throw an error if the dependency references a value that doesn't exist", () => {
it("should throw an error if the dependency references a value that doesn't exist", () => {
const conflict = new Conflict({} as any);
conflict.dependencies = [
new Dependency({
Expand Down
10 changes: 6 additions & 4 deletions lib/dependency/dependency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ export class Dependency<TDependency extends GameObject | unknown> implements IDe
throw new Error(`The property "${String(this.key)}" does not exist on the dependency.`);
} else if (typeof value === 'number' && typeof this.value === 'number') {
// If we look for a number, a conflict will depend on whether that number is greater than
// `this.value`, which we consider to be the maximum allowed value.
return value <= this.value;
// `this.value`, which we consider to be the maximum allowed value. We also need to make
// sure to check against the modified value.
return dependency.getModifiedValue<typeof dependency>(this.key as never, gameObject) <= this.value;
} else {
// If we look for a value that is not a number, a conflict will depend on whether that value
// is equal to `this.value`.
Expand All @@ -66,8 +67,9 @@ export class Dependency<TDependency extends GameObject | unknown> implements IDe
throw new Error(`The property "${String(this.key)}" does not exist on the dependency.`);
} else if (typeof value === 'number' && typeof this.value === 'number') {
// If we look for a number, the dependency check will depend on whether that number is greater
// than `this.value`, which we consider to be the minimum required value.
return value >= this.value;
// than `this.value`, which we consider to be the minimum required value. We also need to make
// sure to check against the modified value.
return dependency.getModifiedValue<typeof dependency>(this.key as never, gameObject) >= this.value;
} else {
// If we look for a value that is not a number, the dependency will depend on whether that value
// is equal to `this.value`.
Expand Down
1 change: 1 addition & 0 deletions lib/dependency/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface IDependency<TDependency extends GameObject | unknown> {
/**
* The value that the checked property should have. Numbers will be considered as a minimum value.
* Other types will be checked for equality. `key` must be provided for the value to be checked.
* Note that dependencies are being checked against modified values.
*/
value?: unknown;
/**
Expand Down

0 comments on commit 2bcbe2c

Please sign in to comment.