'use strict';

// MODULES //

var tape = require( 'tape' );
var proxyquire = require( 'proxyquire' );
var constructorName = require( './../lib' );


// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof constructorName, 'function', 'export is a function' );
	t.end();
});

tape( 'the function returns the name of a value\'s constructor', function test( t ) {
	var expected;
	var values;
	var v;
	var i;

	values = [
		'a',
		new String( 'a' ),
		5,
		new Number( 5 ),
		NaN,
		true,
		new Boolean( true ),
		false,
		new Boolean( false ),
		undefined,
		null,
		[],
		{},
		function noop(){},
		/./,
		new Date(),
		Math,
		JSON,
		new Error(),
		new TypeError(),
		new SyntaxError(),
		new URIError(),
		new EvalError(),
		new ReferenceError(),
		new RangeError(),
		new Int8Array(),
		new Uint8Array(),
		new Uint8ClampedArray(),
		new Int16Array(),
		new Uint16Array(),
		new Int32Array(),
		new Uint32Array(),
		new Float32Array(),
		new Float64Array(),
		new ArrayBuffer(),
		new Buffer( 'beep' )
	];

	expected = [
		'String',
		'String',
		'Number',
		'Number',
		'Number',
		'Boolean',
		'Boolean',
		'Boolean',
		'Boolean',
		'Undefined',
		'Null',
		'Array',
		'Object',
		'Function',
		'RegExp',
		'Date',
		'Math',
		'JSON',
		'Error',
		'TypeError',
		'SyntaxError',
		'URIError',
		'EvalError',
		'ReferenceError',
		'RangeError',
		'Int8Array',
		'Uint8Array',
		'Uint8ClampedArray',
		'Int16Array',
		'Uint16Array',
		'Int32Array',
		'Uint32Array',
		'Float32Array',
		'Float64Array',
		'ArrayBuffer',
		'Buffer'
	];

	for ( i = 0; i < values.length; i++ ) {
		v = constructorName( values[i] );
		t.equal( v, expected[i], 'returns '+expected[i]+' when provided '+values[i] );
	}
	t.end();
});

tape( 'the function supports environments lacking `Function.name` support', function test( t ) {
	var constructorName;
	var foo;
	var v;

	constructorName = proxyquire( './../lib', {
		'@stdlib/utils/constructor-name': getName
	});

	function Foo() {
		var ctor = {};

		// Intercept simple constructor access by setting a `constructor` property to a plain object lacking a `name` property...
		ctor.toString = toString;
		this.constructor = ctor;

		return this;
	}
	foo = new Foo();
	v = constructorName( foo );

	t.equal( v, 'Foo', 'returns Foo' );
	t.end();

	function getName() {
		return '[object Object]';
	}
	function toString() {
		return Foo.toString();
	}
});

tape( 'the function supports Map objects (ES2015)', function test( t ) {
	var v;
	if ( typeof Map !== 'undefined' ) {
		v = constructorName( new Map() );
		t.equal( v, 'Map', 'returns Map' );
	}
	t.end();
});

tape( 'the function supports WeakMap objects (ES2015)', function test( t ) {
	var v;
	if ( typeof WeakMap !== 'undefined' ) {
		v = constructorName( new WeakMap() );
		t.equal( v, 'WeakMap', 'returns WeakMap' );
	}
	t.end();
});

tape( 'the function supports Set objects (ES2015)', function test( t ) {
	var v;
	if ( typeof Set !== 'undefined' ) {
		v = constructorName( new Set() );
		t.equal( v, 'Set', 'returns Set' );
	}
	t.end();
});

tape( 'the function supports WeakSet objects (ES2015)', function test( t ) {
	var v;
	if ( typeof WeakSet !== 'undefined' ) {
		v = constructorName( new WeakSet() );
		t.equal( v, 'WeakSet', 'returns WeakSet' );
	}
	t.end();
});

tape( 'the function supports Symbol objects (ES2015)', function test( t ) {
	var v;
	if ( typeof Symbol !== 'undefined' ) {
		v = constructorName( Symbol() );
		t.equal( v, 'Symbol', 'returns Symbol' );
	}
	t.end();
});

tape( 'the function supports custom objects', function test( t ) {
	var v;
	function Person(){}
	v = constructorName( new Person() );
	t.equal( v, 'Person', 'returns Person' );
	t.end();
});

tape( 'if a value\'s constructor is an anonymous function, the function returns an empty string', function test( t ) {
	var Person = function(){};
	var v;

	v = constructorName( new Person() );
	t.equal( v, '', 'returns empty string' );

	t.end();
});

// TODO: add generator function test

@@ -49,24 +49,93 @@
 ( 'tape' );%0A
+var hasSymbols = require( '@stdlib/utils/detect-symbol-support' )();%0A
 var proxyqui
@@ -3477,37 +3477,27 @@
 f ( 
-typeof Symbol !== 'undefined'
+hasSymbols === true
  ) %7B

Fix feature detection bug in Node v0.10