<commit_before>// import 'es.js'
let es = require('../src/picoes.js')
let assert = require('chai').assert
let World = es.World

describe('World', function() {
	describe('component()', function() {
		it('define a component', function() {
			let world = new World()
			world.component('position', function(x = 0, y = 0) {
				this.x = x
				this.y = y

				this.inc = (a) => {
					return a + 1
				}
			})
			let ent = world.entity().set('position', 1, 2)
			assert('position' in world.components)
			assert(Object.keys(world.components).length == 1)
			assert(ent.has('position'))
			assert(ent.get('position').x === 1)
			assert(ent.get('position').y === 2)
			assert(ent.get('position').inc(5) === 6)

			// Using class syntax
			world.component('velocity', class {
				constructor(x = 0, y = 0) {
					this.x = x
					this.y = y
				}

				inc(a) {
					return a + 1
				}
			})
			let ent2 = world.entity().set('velocity', 1, 2)
			assert('velocity' in world.components)
			assert(Object.keys(world.components).length == 2)
			assert(ent2.has('velocity'))
			assert(ent2.get('velocity').x === 1)
			assert(ent2.get('velocity').y === 2)
			assert(ent2.get('velocity').inc(5) === 6)
		})
		it('README example', function() {
			let world = new World()

			// Create player
			let player = world.entity().set('health', { value: 100 })

			// Create enemies
			world.entity().set('damages', 10)
			world.entity().set('damages', 30)

			// Apply damage
			world.every(['damages'], (amount) => {
				player.get('health').value -= amount
			})

			// Player now has reduced health
			assert(player.get('health').value === 60)
		})
		it('define an object component (should be invalid)', function() {
			let world = new World()
			let result = world.component('position', {
				x: 0,
				y: 0
			})
			assert(result === undefined)
			let result2 = world.component('invalid', 555)
			assert(result2 === undefined)
			assert(Object.keys(world.components).length === 0)
		})
		it('define an empty component', function() {
			let world = new World()
			let result = world.component('position')
			assert(result === undefined)
		})
		it('use an empty component', function() {
			let world = new World()
			let ent = world.entity().update('position', {
				x: 1
			})
			assert(ent.has('position'))
			assert(ent.get('position').x === 1)

			let ent2 = world.entity().set('velocity', {
				x: 2
			})
			assert(ent2.has('velocity'))
			assert(ent2.get('velocity').x === 2)
			ent2.set('velocity', {
				y: 3
			})
			assert(ent2.get('velocity').x === undefined)
			assert(ent2.get('velocity').y === 3)
			ent2.update('velocity', {
				x: 42
			})
			assert(ent2.get('velocity').x === 42)
			assert(ent2.get('velocity').y === 3)

			let ent3 = world.entity().set('singleValue', 5)
			assert(ent3.has('singleValue'))
			assert(ent3.get('singleValue') === 5)
			ent3.set('singleValue', 500)
			assert(ent3.get('singleValue') === 500)

			let ent4 = world.entity().set('string', 'hello')
			assert(ent4.has('string'))
			assert(ent4.get('string') === 'hello')
			ent4.set('string', 'goodbye')
			assert(ent4.get('string') === 'goodbye')

			ent4.remove('string')
			assert(!ent4.has('string'))
		})
		it('test clearing with indexes', function() {
			let world = new World()
			world.component('position', function(x = 0, y = 0) {
				this.x = x
				this.y = y
			})
			world.component('velocity')
			world.component('sprite')
			let results = world.every([])
			results = world.every(['position'])
			results = world.every(['position', 'velocity'])

			world.entity().set('position', 1, 2).set('velocity')
			world.entity().set('position', 3, 4).set('velocity')
			world.entity().set('position', 5, 6)
			world.entity().set('velocity')

			let count = 0
			world.every(['position'], (position) => {
				assert(position.x >= 1)
				assert(position.y >= 2)
				++count
			})
			assert(count === 3)

			world.clear()

			count = 0
			world.every(['position'], (position) => {
				++count
			})
			world.every([], (ent) => {
				++count
			})
			assert(count === 0)
		})
	})

	describe('system()', function() {
		it('define a system', function() {
			let world = new World()
			world.component('position')
			world.system(['position'], class {})
			assert(world.systems.length == 1)
		})
		it('system iteration', function() {
			let world = new World()
			world.component('position')
			world.component('velocity')
			world.system(['position', 'velocity'], class {
				every(position, velocity, ent) {
					assert(position)
					assert(velocity)
					position.x += velocity.x
					position.y += velocity.y
					assert(ent)
					assert(ent.has('position'))
					assert(ent.has('velocity'))
				}
			})
			let entA = world.entity()
			let entB = world.entity()
			let entC = world.entity()
			entA.update('position', {x: 1, y: 1}).update('velocity', {x: 1, y: 0})
			entB.update('position', {x: 30, y: 40}).update('velocity', {x: -1, y: 2})

			world.init()

			assert(entA.get('position').x == 1 && entA.get('position').y == 1)
			assert(entB.get('position').x == 30 && entB.get('position').y == 40)

			world.run()

			assert(entA.get('position').x == 2 && entA.get('position').y == 1)
			assert(entB.get('position').x == 29 && entB.get('position').y == 42)

			world.run()

			assert(entA.get('position').x == 3 && entA.get('position').y == 1)
			assert(entB.get('position').x == 28 && entB.get('position').y == 44)
		})
		it('system methods', function() {
			let world = new World()
			world.component('position')

			let methodsCalled = 0

			world.system(['position'], class {
				constructor() {
					this.val = 10
				}
				init() {
					++methodsCalled
					assert(this.val === 10)
				}
				pre() {
					++methodsCalled
					assert(this.val === 10)
				}
				every(position) {
					position.x = 1
					++methodsCalled
					assert(this.val === 10)
				}
				post() {
					++methodsCalled
					assert(this.val === 10)
				}
			})

			world.system(['invalid'], class {})
			world.system()

			let ent = world.entity().set('position')
			world.init()
			assert(methodsCalled == 1)
			world.run()
			assert(methodsCalled == 4)
		})
		it('system edge cases', function() {
			let world = new World()
			world.component('position')
			world.component('velocity')

			let testEnt2 = null
			for (let i = 0; i < 100; ++i) {
				let tmpEnt = world.entity()
				tmpEnt.set('position').set('velocity')
				if (i == 80) {
					testEnt2 = tmpEnt
				}
			}

			let testEnt = world.entity().set('position').set('velocity')
			let count = 0

			world.system(['position', 'velocity'], class {
				every(position, velocity, ent) {
					++count
					if (count == 1) {
						testEnt.removeAll()
						testEnt2.remove('position')
						return
					}
					assert(position)
					assert(velocity)
					position.x += velocity.x
					position.y += velocity.y
					assert(ent)
					assert(ent.has('position'))
					assert(ent.has('velocity'))
				}
			})
			let entA = world.entity()
			let entB = world.entity()
			let entC = world.entity()
			entA.update('position', {x: 1, y: 1}).update('velocity', {x: 1, y: 0})
			entB.update('position', {x: 30, y: 40}).update('velocity', {x: -1, y: 2})

			world.init()

			assert(entA.get('position').x == 1 && entA.get('position').y == 1)
			assert(entB.get('position').x == 30 && entB.get('position').y == 40)

			world.run()

			assert(entA.get('position').x == 2 && entA.get('position').y == 1)
			assert(entB.get('position').x == 29 && entB.get('position').y == 42)

			world.run()

			assert(entA.get('position').x == 3 && entA.get('position').y == 1)
			assert(entB.get('position').x == 28 && entB.get('position').y == 44)
		})
		it('use the every() method', function() {
			let world = new World()
			world.component('position')
			world.component('velocity')
			let ent1 = world.entity().set('position').set('velocity')
			let ent2 = world.entity().set('position')
			let externalVar = 5
			world.every(['position'], (pos, ent) => {
				assert(pos)
				assert(ent)
				assert(ent.has('position'))
				assert(externalVar === 5)
			})
			world.every(['position'], function(pos, ent) {
				assert(pos)
				assert(ent)
				assert(ent.has('position'))
				assert(externalVar === 5)
			})
		})
		it('test indexing with every()', function() {
			let world = new World()
			world.component('position', function(val = 0) {
				this.val = val
			})
			world.component('velocity')
			world.component('sprite', {texture: 'image.png'})
			let ent1 = world.entity().set('position', 1).set('velocity')
			let ent2 = world.entity().set('position', 10)
			let ent3 = world.entity().set('position', 100).set('velocity').set('sprite')
			let count = 0
			world.every(['position', 'velocity'], (pos, vel, ent) => {
				assert(ent.has('position', 'velocity'))
				count += pos.val
			})
			assert(count == 101)
			count = 0
<commit_msg>Added test for hash collisions<commit_after>// import 'es.js'
let es = require('../src/picoes.js')
let assert = require('chai').assert
let World = es.World

describe('World', function() {
	describe('component()', function() {
		it('define a component', function() {
			let world = new World()
			world.component('position', function(x = 0, y = 0) {
				this.x = x
				this.y = y

				this.inc = (a) => {
					return a + 1
				}
			})
			let ent = world.entity().set('position', 1, 2)
			assert('position' in world.components)
			assert(Object.keys(world.components).length == 1)
			assert(ent.has('position'))
			assert(ent.get('position').x === 1)
			assert(ent.get('position').y === 2)
			assert(ent.get('position').inc(5) === 6)

			// Using class syntax
			world.component('velocity', class {
				constructor(x = 0, y = 0) {
					this.x = x
					this.y = y
				}

				inc(a) {
					return a + 1
				}
			})
			let ent2 = world.entity().set('velocity', 1, 2)
			assert('velocity' in world.components)
			assert(Object.keys(world.components).length == 2)
			assert(ent2.has('velocity'))
			assert(ent2.get('velocity').x === 1)
			assert(ent2.get('velocity').y === 2)
			assert(ent2.get('velocity').inc(5) === 6)
		})
		it('README example', function() {
			let world = new World()

			// Create player
			let player = world.entity().set('health', { value: 100 })

			// Create enemies
			world.entity().set('damages', 10)
			world.entity().set('damages', 30)

			// Apply damage
			world.every(['damages'], (amount) => {
				player.get('health').value -= amount
			})

			// Player now has reduced health
			assert(player.get('health').value === 60)
		})
		it('define an object component (should be invalid)', function() {
			let world = new World()
			let result = world.component('position', {
				x: 0,
				y: 0
			})
			assert(result === undefined)
			let result2 = world.component('invalid', 555)
			assert(result2 === undefined)
			assert(Object.keys(world.components).length === 0)
		})
		it('define an empty component', function() {
			let world = new World()
			let result = world.component('position')
			assert(result === undefined)
		})
		it('use an empty component', function() {
			let world = new World()
			let ent = world.entity().update('position', {
				x: 1
			})
			assert(ent.has('position'))
			assert(ent.get('position').x === 1)

			let ent2 = world.entity().set('velocity', {
				x: 2
			})
			assert(ent2.has('velocity'))
			assert(ent2.get('velocity').x === 2)
			ent2.set('velocity', {
				y: 3
			})
			assert(ent2.get('velocity').x === undefined)
			assert(ent2.get('velocity').y === 3)
			ent2.update('velocity', {
				x: 42
			})
			assert(ent2.get('velocity').x === 42)
			assert(ent2.get('velocity').y === 3)

			let ent3 = world.entity().set('singleValue', 5)
			assert(ent3.has('singleValue'))
			assert(ent3.get('singleValue') === 5)
			ent3.set('singleValue', 500)
			assert(ent3.get('singleValue') === 500)

			let ent4 = world.entity().set('string', 'hello')
			assert(ent4.has('string'))
			assert(ent4.get('string') === 'hello')
			ent4.set('string', 'goodbye')
			assert(ent4.get('string') === 'goodbye')

			ent4.remove('string')
			assert(!ent4.has('string'))
		})
		it('test clearing with indexes', function() {
			let world = new World()
			world.component('position', function(x = 0, y = 0) {
				this.x = x
				this.y = y
			})
			world.component('velocity')
			world.component('sprite')
			let results = world.every([])
			results = world.every(['position'])
			results = world.every(['position', 'velocity'])

			world.entity().set('position', 1, 2).set('velocity')
			world.entity().set('position', 3, 4).set('velocity')
			world.entity().set('position', 5, 6)
			world.entity().set('velocity')

			let count = 0
			world.every(['position'], (position) => {
				assert(position.x >= 1)
				assert(position.y >= 2)
				++count
			})
			assert(count === 3)

			world.clear()

			count = 0
			world.every(['position'], (position) => {
				++count
			})
			world.every([], (ent) => {
				++count
			})
			assert(count === 0)
		})
	})

	describe('system()', function() {
		it('define a system', function() {
			let world = new World()
			world.component('position')
			world.system(['position'], class {})
			assert(world.systems.length == 1)
		})
		it('system iteration', function() {
			let world = new World()
			world.component('position')
			world.component('velocity')
			world.system(['position', 'velocity'], class {
				every(position, velocity, ent) {
					assert(position)
					assert(velocity)
					position.x += velocity.x
					position.y += velocity.y
					assert(ent)
					assert(ent.has('position'))
					assert(ent.has('velocity'))
				}
			})
			let entA = world.entity()
			let entB = world.entity()
			let entC = world.entity()
			entA.update('position', {x: 1, y: 1}).update('velocity', {x: 1, y: 0})
			entB.update('position', {x: 30, y: 40}).update('velocity', {x: -1, y: 2})

			world.init()

			assert(entA.get('position').x == 1 && entA.get('position').y == 1)
			assert(entB.get('position').x == 30 && entB.get('position').y == 40)

			world.run()

			assert(entA.get('position').x == 2 && entA.get('position').y == 1)
			assert(entB.get('position').x == 29 && entB.get('position').y == 42)

			world.run()

			assert(entA.get('position').x == 3 && entA.get('position').y == 1)
			assert(entB.get('position').x == 28 && entB.get('position').y == 44)
		})
		it('system methods', function() {
			let world = new World()
			world.component('position')

			let methodsCalled = 0

			world.system(['position'], class {
				constructor() {
					this.val = 10
				}
				init() {
					++methodsCalled
					assert(this.val === 10)
				}
				pre() {
					++methodsCalled
					assert(this.val === 10)
				}
				every(position) {
					position.x = 1
					++methodsCalled
					assert(this.val === 10)
				}
				post() {
					++methodsCalled
					assert(this.val === 10)
				}
			})

			world.system(['invalid'], class {})
			world.system()

			let ent = world.entity().set('position')
			world.init()
			assert(methodsCalled == 1)
			world.run()
			assert(methodsCalled == 4)
		})
		it('system edge cases', function() {
			let world = new World()
			world.component('position')
			world.component('velocity')

			let testEnt2 = null
			for (let i = 0; i < 100; ++i) {
				let tmpEnt = world.entity()
				tmpEnt.set('position').set('velocity')
				if (i == 80) {
					testEnt2 = tmpEnt
				}
			}

			let testEnt = world.entity().set('position').set('velocity')
			let count = 0

			world.system(['position', 'velocity'], class {
				every(position, velocity, ent) {
					++count
					if (count == 1) {
						testEnt.removeAll()
						testEnt2.remove('position')
						return
					}
					assert(position)
					assert(velocity)
					position.x += velocity.x
					position.y += velocity.y
					assert(ent)
					assert(ent.has('position'))
					assert(ent.has('velocity'))
				}
			})
			let entA = world.entity()
			let entB = world.entity()
			let entC = world.entity()
			entA.update('position', {x: 1, y: 1}).update('velocity', {x: 1, y: 0})
			entB.update('position', {x: 30, y: 40}).update('velocity', {x: -1, y: 2})

			world.init()

			assert(entA.get('position').x == 1 && entA.get('position').y == 1)
			assert(entB.get('position').x == 30 && entB.get('position').y == 40)

			world.run()

			assert(entA.get('position').x == 2 && entA.get('position').y == 1)
			assert(entB.get('position').x == 29 && entB.get('position').y == 42)

			world.run()

			assert(entA.get('position').x == 3 && entA.get('position').y == 1)
			assert(entB.get('position').x == 28 && entB.get('position').y == 44)
		})
		it('use the every() method', function() {
			let world = new World()
			let ent1 = world.entity().set('position').set('velocity')
			let ent2 = world.entity().set('position')
			let ent3 = world.entity().set('position:velocity')
			let externalVar = 5
			world.every(['position'], (pos, ent) => {
				assert(pos)
				assert(ent)
				assert(ent.has('position'))
				assert(externalVar === 5)
			})
			world.every(['position'], function(pos, ent) {
				assert(pos)
				assert(ent)
				assert(ent.has('position'))
				assert(externalVar === 5)
			})

			// Test hash collisions
			// Note: Seems to work, but will probably be slower due to combined results
			let count = 0
			world.every(['position', 'velocity'], function(pos, vel, ent) {
				assert(pos)
				assert(vel)
				assert(ent)
				assert(ent.has('position', 'velocity'))
				++count
			})
			assert(count === 1)
		})
		it('test indexing with every()', function() {
			let world = new World()
			world.component('position', function(val = 0) {
				this.val = val
			})
			world.component('velocity')
			world.component('sprite', {texture: 'image.png'})
			let ent1 = world.entity().set('position', 1).set('velocity')
			let ent2 = world.entity().set('position', 10)
			let ent3 = world.entity().set('position', 100).set('velocity').set('sprite')
			let count = 0
			world.every(['position', 'velocity'], (pos, vel, ent) => {
				assert(ent.has('position', 'velocity'))
				count += pos.val
			})
			assert(count == 101)
			count = 0

{'fraction_non_alphanumeric': 0.2023577823499972, 'fraction_numerical': 0.022187621642662515, 'mean_word_length': 3.1106285714285713, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5645475', 'n_tokens_mistral': 7790, 'n_tokens_neox': 5954, 'n_words': 1279}