generated from graasp/graasp-app-starter-ts-vite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement tests for TemperatureIterator
- Loading branch information
Showing
2 changed files
with
208 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { SIMULATION_SLIDING_WINDOW } from '@/config/simulation'; | ||
// Import your class | ||
import { TemperatureRow } from '@/types/temperatures'; | ||
import { TimeUnit, TimeUnitType } from '@/types/time'; | ||
import { timeConversionFactors } from '@/utils/time'; | ||
|
||
import { TemperatureIterator } from './TemperatureIterator'; | ||
|
||
const createDummyTemperatures = ( | ||
count: number, | ||
measurementFrequency: TimeUnitType, | ||
): TemperatureRow[] => | ||
Array.from( | ||
{ | ||
length: | ||
(count * timeConversionFactors[TimeUnit.days]) / | ||
timeConversionFactors[measurementFrequency], | ||
}, | ||
(_, i) => ({ | ||
time: new Date(Date.UTC(2024, 0, i + 1, i)).toISOString(), // Create dates for each day or hour | ||
temperature: 10 + i, | ||
}), | ||
); | ||
|
||
describe('TemperatureIterator', () => { | ||
it('should initialize correctly by hours', () => { | ||
const temperatures = createDummyTemperatures(10, TimeUnit.hours); | ||
expect(temperatures.length).toBe(240); // Should have more initially | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
}); | ||
expect(iterator.hasMore()).toBe(true); // Should have more initially | ||
}); | ||
|
||
it('should initialize correctly by days', () => { | ||
const temperatures = createDummyTemperatures(10, TimeUnit.days); | ||
expect(temperatures.length).toBe(10); // Should have more initially | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
}); | ||
expect(iterator.hasMore()).toBe(true); // Should have more initially | ||
}); | ||
|
||
it('should iterate through the temperatures with the correct sliding window', () => { | ||
const temperatures = createDummyTemperatures(10, TimeUnit.days); | ||
|
||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 3, unit: TimeUnit.days }, | ||
}); | ||
|
||
let window = iterator.getNext(); | ||
expect(window.temperatures).toEqual([10, 11, 12]); | ||
expect(window.mean).toEqual(11); | ||
expect(window.size).toEqual(3); | ||
expect(window.totalCount).toEqual(10); | ||
|
||
window = iterator.getNext(); | ||
expect(window.temperatures).toEqual([13, 14, 15]); | ||
expect(window.mean).toEqual(14); | ||
|
||
window = iterator.getNext(); | ||
expect(window.temperatures).toEqual([16, 17, 18]); | ||
expect(window.mean).toEqual(17); | ||
|
||
window = iterator.getNext(); | ||
expect(window.temperatures).toEqual([19]); // Last window might be smaller | ||
expect(window.mean).toEqual(19); | ||
|
||
expect(iterator.hasMore()).toBe(false); // Should have no more after iterating | ||
}); | ||
|
||
it('should handle different measurement frequencies and sliding window units', () => { | ||
const temperaturesHourly = createDummyTemperatures(5, TimeUnit.hours); // 5 days of hourly data | ||
const iteratorHourly = new TemperatureIterator({ | ||
temperatures: temperaturesHourly, | ||
measurementFrequency: TimeUnit.hours, | ||
slidingWindow: { window: 2, unit: TimeUnit.days }, // 2-day window | ||
}); | ||
|
||
const firstWindowHourly = iteratorHourly.getNext(); | ||
expect(firstWindowHourly.size).toBe(48); // 2 days * 24 hours/day | ||
|
||
const temperaturesDaily = createDummyTemperatures(5, TimeUnit.days); // 5 days of daily data | ||
const iteratorDaily = new TemperatureIterator({ | ||
temperatures: temperaturesDaily, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 2, unit: TimeUnit.days }, // 2-day window | ||
}); | ||
|
||
const firstWindowDaily = iteratorDaily.getNext(); | ||
expect(firstWindowDaily.size).toBe(2); // 2 days | ||
}); | ||
|
||
it('should not throw an error if the window size is greater than the number of temperatures', () => { | ||
const temperatures = createDummyTemperatures(2, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 3, unit: TimeUnit.days }, | ||
}); | ||
|
||
const firstWindowDaily = iterator.getNext(); // Get the first (and only) window | ||
expect(firstWindowDaily.size).toBe(2); // 2 days | ||
}); | ||
|
||
it('should throw an error if there are no temperatures', () => { | ||
const temperatures = createDummyTemperatures(0, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 3, unit: TimeUnit.days }, | ||
}); | ||
|
||
expect(() => iterator.getNext()).toThrowError( | ||
'There is no more temperatures!', | ||
); | ||
}); | ||
|
||
it('should throw an error if there are no more temperatures', () => { | ||
const temperatures = createDummyTemperatures(2, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 2, unit: TimeUnit.days }, | ||
}); | ||
|
||
iterator.getNext(); // get first window | ||
|
||
expect(() => iterator.getNext()).toThrowError( | ||
'There is no more temperatures!', | ||
); | ||
}); | ||
|
||
it('should reset the iterator correctly', () => { | ||
const temperatures = createDummyTemperatures(5, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 2, unit: TimeUnit.days }, | ||
}); | ||
|
||
iterator.getNext(); // Move to the second window | ||
iterator.reset(); // Reset the iterator | ||
|
||
const resetWindow = iterator.getNext(); // Get the first window again | ||
expect(resetWindow.temperatures).toEqual([10, 11]); // Should be back to the first window's data | ||
}); | ||
|
||
it('should use the default sliding window if none is provided', () => { | ||
const temperatures = createDummyTemperatures(10, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
}); | ||
|
||
const window = iterator.getNext(); | ||
expect(window.size).toBe(SIMULATION_SLIDING_WINDOW.window); // Should use the default window size | ||
Check failure on line 163 in src/models/TemperatureIterator.test.ts GitHub Actions / cypress-runsrc/models/TemperatureIterator.test.ts > TemperatureIterator > should use the default sliding window if none is provided
|
||
}); | ||
|
||
it('should handle edge cases with small datasets and large sliding windows', () => { | ||
const temperatures = createDummyTemperatures(2, TimeUnit.days); | ||
const iterator = new TemperatureIterator({ | ||
temperatures, | ||
measurementFrequency: TimeUnit.days, | ||
slidingWindow: { window: 5, unit: TimeUnit.days }, // Window larger than dataset | ||
}); | ||
|
||
const window = iterator.getNext(); | ||
expect(window.temperatures).toEqual([10, 11]); // Should include all available data | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters