Skip to content

Commit

Permalink
feat(grid): add from() static method that accepts an iterable of hexe…
Browse files Browse the repository at this point in the history
…s and returns a new grid
  • Loading branch information
flauwekeul committed Apr 22, 2021
1 parent dd39813 commit 83b25ad
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,10 @@ These methods exist in v3 and they need to be considered for v4.

#### API

- [ ] **Creation**:
- [x] **Creation**:
- [x] `new Grid<T extends Hex>(hexPrototype: T, traverserOrStore?: Traverser<T> | Map<string, T>)`: ~~can be traversed indefinitely, determine default traverser (spiral?) the default traverser doesn't emit hexes~~ A grid without hexes isn't very helpful, so it makes sense to pass a traverser or store (`Map`) to the constructor.
- [x] ~~`Grid.of<T extends Hex>(/* same args as constructor */)`~~
- [ ] `Grid.from<T extends Hex>(iterable: Iterable<T>)`
- [x] `Grid.from<T extends Hex>(iterable: Iterable<T>)`
- [ ] **Traversal**:
- [x] `grid.rectangle(options)`
- [ ] `grid.hexagon(options)`
Expand Down
35 changes: 35 additions & 0 deletions src/grid/grid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,41 @@ describe('creation', () => {

expect(callback).not.toBeCalled()
})

describe('Grid.from()', () => {
const hex = createHex(hexPrototype)
const store = new Map([[hex.toString(), hex]])

test('accepts a store', () => {
const grid = Grid.from(store)

expect(grid.store).toEqual(store)
expect(grid.hexPrototype).toBe(hexPrototype)

const callback = jest.fn()
grid.run(callback)

expect(callback.mock.calls).toEqual([[hex, grid]])
})

test('accepts an iterable', () => {
const iterable = store.values()
const grid = Grid.from(iterable)

expect(grid.store).toEqual(store)
expect(grid.hexPrototype).toBe(hexPrototype)

const callback = jest.fn()
grid.run(callback)

expect(callback.mock.calls).toEqual([[hex, grid]])
})

test('throws an error when passed an empty store or iterable', () => {
expect(() => Grid.from(new Map())).toThrowError(`Can't create grid from empty iterable: ${new Map()}`)
expect(() => Grid.from([])).toThrowError(`Can't create grid from empty iterable: ${[]}`)
})
})
})

test('implements toStringTag', () => {
Expand Down
19 changes: 19 additions & 0 deletions src/grid/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,25 @@ import { flatTraverse } from './functions'
import { Callback, Traverser } from './types'

export class Grid<T extends Hex> {
static from<T extends Hex>(iterable: Map<string, T> | Iterable<T>) {
let firstHex: T
let store: Map<string, T>

if (iterable instanceof Map) {
firstHex = iterable.values()[Symbol.iterator]().next().value
store = iterable
} else {
const array = Array.from(iterable)
firstHex = array[0]
store = new Map(array.map((hex) => [hex.toString(), hex]))
}

if (!firstHex) {
throw new Error(`Can't create grid from empty iterable: ${iterable}`)
}

return new Grid<T>(Object.getPrototypeOf(firstHex), store)
}

get [Symbol.toStringTag]() {
return 'Grid'
Expand Down

0 comments on commit 83b25ad

Please sign in to comment.