isset-php
Version:
Safe and simple PHP isset() for JavaScript
158 lines (129 loc) • 6.76 kB
JavaScript
/* global describe it */
const assert = require('assert/strict')
const isset = require('../src')
describe('isset-php', () => {
// Ensuring our export declaration stays the same
it('exports a named function signature', () => {
assert.equal('function', typeof isset, 'default export for isset-php is not a function')
assert.equal('isset', isset.name, 'default export for isset-php is not named "isset"')
})
// Ensuring TypeErrors are thrown
it('accepts only function arguments', () => {
// Require at least one parameter
assert.throws(() => isset(), {
name: 'TypeError',
message: 'isset requires at least one accessor function'
})
// All accessors must be functions
assert.throws(() => isset(0), {
name: 'TypeError',
message: 'isset requires accessors to be functions'
})
})
// Ensure single argument behaviour
it('mimics single argument behaviour', () => {
// Values that should all return true
assert.equal(true, isset(() => 0), '0 is a set value')
assert.equal(true, isset(() => 1), '1 is a set value')
assert.equal(true, isset(() => 0.0), '0.0 is a set value')
assert.equal(true, isset(() => 1.0), '1.0 is a set value')
assert.equal(true, isset(() => true), 'true is a set value')
assert.equal(true, isset(() => false), 'false is a set value')
assert.equal(true, isset(() => ''), '"" is a set value')
assert.equal(true, isset(() => 'string'), '"string" is a set value')
assert.equal(true, isset(() => []), '[] is a set value')
assert.equal(true, isset(() => [0, 1]), '[0, 1] is a set value')
assert.equal(true, isset(() => ({})), '{} is a set value')
assert.equal(true, isset(() => ({ 0: 1 })), '{ 0: 1 } is a set value')
assert.equal(true, isset(() => '\0'), '"\0" is a set value')
assert.equal(true, isset(() => String.fromCharCode(0)), '"\0" is a set value')
// Accessor that returns functions are still set values
assert.equal(true, isset(() => () => {}), 'functions are set values')
assert.equal(true, isset(() => () => 0), 'functions are set values')
// Values that should return false like accessor that don't return anything
assert.equal(false, isset(() => {}), 'empty accessor does not return a set value')
assert.equal(false, isset(() => undefined), 'undefined is not a set value')
assert.equal(false, isset(() => null), 'null is not a set value')
})
// Ensure multiple arguments are supported
it('mimics multiple argument behaviour', () => {
// All accesors returning values
assert.equal(true, isset(() => 0, () => 1), 'all accessors return set values')
assert.equal(true, isset(() => 0, () => 1, () => 2), 'all accessors return set values')
// One accessor returning a null value
assert.equal(false, isset(() => {}, () => 1), 'first accessor does not return a value')
assert.equal(false, isset(() => 0, () => undefined), 'last accessor returns undefined')
assert.equal(false, isset(() => 0, () => null, () => 2), 'second accessor returns null')
})
// Ensure short cicuiting works
it('mimics short circuit behaviour', () => {
// Mock functions that increment the number of times they were called
const calls = { a: 0, b: 0, c: 0 }
const a = () => calls.a++
const b = () => { calls.b++ }
const c = () => { calls.c++ }
// Ensure the last mock function wasn't called
assert.equal(false, isset(a, b, c), 'short circuit returns false')
assert.equal(1, calls.a, 'first accessor called and set')
assert.equal(1, calls.b, 'second accessor called but not set')
assert.equal(0, calls.c, 'last accessor not called')
})
// Ensure similar variable declaration functionality
it('mimics variable declaration behaviour', () => {
// Checking variables before they are declared
assert.equal(false, isset(() => value), 'value has not been declared')
assert.equal(false, isset(() => object.value), 'object has not been declared')
// Simply declaring variables does not give them a value
const object = {}
let value
assert.equal(false, isset(() => value), 'value has been declared with no value')
assert.equal(false, isset(() => object.value), 'object has been declared with no value')
// Setting null is still not a value
value = null
object.value = null
assert.equal(false, isset(() => value), 'value has been set to null')
assert.equal(false, isset(() => object.value), 'object value has been set to null')
// Setting a value
value = 0
object.value = 0
assert.equal(true, isset(() => value), 'value has been set')
assert.equal(true, isset(() => object.value), 'object value has been set')
// Clearing the value by setting it to undefined
value = undefined
object.value = undefined
assert.equal(false, isset(() => value), 'value has been set to undefined')
assert.equal(false, isset(() => object.value), 'object value has been set to undefined')
// delete value // strict mode violation
delete object.value
// assert.equal(false, isset(() => value), 'value has been deleted')
assert.equal(false, isset(() => object.value), 'object value has been deleted')
})
// Ensure similar array like functionality
it('mimics array behaviour', () => {
const object = { test: 1, hello: null, pie: { a: 'apple' } }
// Checking top level properties
assert.equal(true, isset(() => object.test), 'object.test is a set value')
assert.equal(false, isset(() => object.foo), 'object.foo has not been declared')
assert.equal(false, isset(() => object.hello), 'object.hello has been declared as null')
// Example array_key_exists
assert.equal(true, Object.prototype.hasOwnProperty.call(object, 'hello'), 'object.hello is a valid property')
// Checking deep properties
assert.equal(true, isset(() => object.pie.a), 'object.pie.a is a set value')
assert.equal(false, isset(() => object.pie.b), 'object.pie.b has not been declared')
assert.equal(false, isset(() => object.cake.a.b), 'object.cake has not been declared')
})
it('mimics string behaviour', () => {
const string = 'somestring'
assert.equal(false, isset(() => string.some_key), 'string has no keys')
assert.equal(true, isset(() => string[0]), 'character at 0 is set')
assert.equal(true, isset(() => string['0']), 'character at 0 is set')
// !
// ! This is the only difference between PHP and JS
// v
assert.equal(false, isset(() => string[0.5]), '0.5 is NOT cast to 0 unlike in PHP')
// ^
// !
assert.equal(false, isset(() => string['0.5']), 'string has no keys')
assert.equal(false, isset(() => string['0 Mostel']), 'string has no keys')
})
})