Skip to content

Commit

Permalink
Support web browser loading
Browse files Browse the repository at this point in the history
closes #18
  • Loading branch information
dougwilson committed Sep 7, 2015
1 parent 45d9883 commit 12833d3
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ node_js:
- "2.0"
- "2.5"
sudo: false
before_install:
# Setup Node.js version-specific dependencies
- "test $TRAVIS_NODE_VERSION = '0.6' -o test $TRAVIS_NODE_VERSION = '0.8' || npm install browserify"
script: "npm run-script test-ci"
after_script: "npm install [email protected] && cat ./coverage/lcov.info | coveralls"
2 changes: 2 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ unreleased

* Enable strict mode in more places
* Support io.js 2.x
* Support web browser loading
- Requires bundler like Browserify or webpack

1.0.1 / 2015-04-07
==================
Expand Down
7 changes: 7 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ Deprecate all the things
## Install

This module is installed directly using `npm`:

```sh
$ npm install depd
```

This module can also be bundled with systems like
[Browserify](http://browserify.org/) or [webpack](https://webpack.github.io/),
though by default this module will alter it's API to no longer display or
track deprecations.

## API

```js
Expand Down
79 changes: 79 additions & 0 deletions lib/browser/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*!
* depd
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/

'use strict'

/**
* Module exports.
* @public
*/

module.exports = depd

/**
* Create deprecate for namespace in caller.
*/

function depd(namespace) {
if (!namespace) {
throw new TypeError('argument namespace is required')
}

function deprecate(message) {
// no-op in browser
}

deprecate._file = undefined
deprecate._ignored = true
deprecate._namespace = namespace
deprecate._traced = false
deprecate._warned = Object.create(null)

deprecate.function = wrapfunction
deprecate.property = wrapproperty

return deprecate
}

/**
* Return a wrapped function in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/

function wrapfunction(fn, message) {
if (typeof fn !== 'function') {
throw new TypeError('argument fn must be a function')
}

return fn
}

/**
* Wrap property in a deprecation message.
*
* This is a no-op version of the wrapper, which does nothing but call
* validation.
*/

function wrapproperty(obj, prop, message) {
if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
throw new TypeError('argument obj must be object')
}

var descriptor = Object.getOwnPropertyDescriptor(obj, prop)

if (!descriptor) {
throw new TypeError('must call property on owner object')
}

if (!descriptor.configurable) {
throw new TypeError('property must be configurable')
}

return
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"deprecated"
],
"repository": "dougwilson/nodejs-depd",
"browser": "lib/browser/index.js",
"devDependencies": {
"benchmark": "1.0.0",
"beautify-benchmark": "0.2.4",
Expand Down
202 changes: 202 additions & 0 deletions test/browserify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@

var assert = require('assert')
var basename = require('path').basename
var browserify = tryRequire('browserify')
var bufferConcat = require('../lib/compat').bufferConcat
var depd = null
var mylib = null
var path = require('path')
var run = browserify ? describe : describe.skip

run('when browserified', function () {
before(function (done) {
var b = browserify()

// require depd
b.require(path.join(__dirname, '..'), {
expose: 'depd'
})

// require libs
b.require(path.join(__dirname, 'fixtures', 'libs'), {
expose: 'libs'
})

b.bundle(function (err, buf) {
var require = eval(buf.toString())
depd = require('depd')
mylib = require('libs').my
done()
})
})

describe('depd(namespace)', function () {
it('creates deprecated function', function () {
assert.equal(typeof depd('test'), 'function')
})

it('requires namespace', function () {
assert.throws(depd.bind(null), /namespace.*required/)
})
})

describe('deprecate(message)', function () {
it('should not log message', function () {
function callold() { mylib.old() }
assert.equal(captureStderr(callold), '')
})

describe('when message omitted', function () {
it('should not log message', function () {
function callold() { mylib.automsgnamed() }
assert.equal(captureStderr(callold), '')
})
})
})

describe('deprecate.function(fn, message)', function () {
it('should throw when not given function', function () {
var deprecate = depd('test')
assert.throws(deprecate.function.bind(deprecate, 2), /fn.*function/)
})

it('should not log on call to function', function () {
function callold() { mylib.oldfn() }
assert.equal(captureStderr(callold), '')
})

it('should have same arity', function () {
assert.equal(mylib.oldfn.length, 2)
})

it('should pass arguments', function () {
var ret
function callold() { ret = mylib.oldfn(1, 2) }
assert.equal(captureStderr(callold), '')
assert.equal(ret, 2)
})

describe('when message omitted', function () {
it('should not log message', function () {
function callold() { mylib.oldfnauto() }
assert.equal(captureStderr(callold), '')
})
})
})

describe('deprecate.property(obj, prop, message)', function () {
it('should throw when given primitive', function () {
var deprecate = depd('test')
assert.throws(deprecate.property.bind(deprecate, 2), /obj.*object/)
})

it('should throw when given missing property', function () {
var deprecate = depd('test')
var obj = {}
assert.throws(deprecate.property.bind(deprecate, obj, 'blargh'), /property.*owner/)
})

it('should throw when given non-configurable property', function () {
var deprecate = depd('test')
var obj = {}
Object.defineProperty(obj, 'thing', {value: 'thingie'})
assert.throws(deprecate.property.bind(deprecate, obj, 'thing'), /property.*configurable/)
})

it('should not log on access to property', function () {
function callprop() { mylib.propa }
assert.equal(captureStderr(callprop), '')
})

it('should not log on setting property', function () {
var val
function callprop() { val = mylib.propa }
function setprop() { mylib.propa = 'newval' }
assert.equal(captureStderr(setprop), '')
assert.equal(captureStderr(callprop), '')
assert.equal(val, 'newval')
})

describe('when obj is a function', function () {
it('should not log on access to property on function', function () {
function callprop() { mylib.fnprop.propa }
assert.equal(captureStderr(callprop), '')
})

it('should not generate message on named function', function () {
function callprop() { mylib.fnprop.propautomsg }
assert.equal(captureStderr(callprop), '')
})
})

describe('when value descriptor', function () {
it('should not log on access and set', function () {
function callold() { mylib.propa }
function setold() { mylib.propa = 'val' }
assert.equal(captureStderr(callold), '')
assert.equal(captureStderr(setold), '')
})

it('should not log on set to non-writable', function () {
function callold() { mylib.propget }
function setold() { mylib.propget = 'val' }
assert.equal(captureStderr(callold), '')
assert.equal(captureStderr(setold), '')
})
})

describe('when accessor descriptor', function () {
it('should log on access and set', function () {
function callold() { mylib.propdyn }
function setold() { mylib.propdyn = 'val' }
assert.equal(captureStderr(callold), '')
assert.equal(captureStderr(setold), '')
})

it('should not log on access when no accessor', function () {
function callold() { mylib.propsetter }
assert.equal(captureStderr(callold), '')
})

it('should not log on set when no setter', function () {
function callold() { mylib.propgetter = 'val' }
assert.equal(captureStderr(callold), '')
})
})

describe('when message omitted', function () {
it('should not generate message for method call on named function', function () {
function callold() { mylib.propauto }
assert.equal(captureStderr(callold), '')
})
})
})
})

function captureStderr(fn, color) {
var chunks = []
var isTTY = process.stderr.isTTY
var write = process.stderr.write

process.stderr.isTTY = Boolean(color)
process.stderr.write = function write(chunk, encoding) {
chunks.push(new Buffer(chunk, encoding))
}

try {
fn()
} finally {
process.stderr.isTTY = isTTY
process.stderr.write = write
}

return bufferConcat(chunks).toString('utf8')
}

function tryRequire(name) {
try {
return require(name)
} catch (e) {
return undefined
}
}
4 changes: 2 additions & 2 deletions test/fixtures/cool-lib.js → test/fixtures/libs/cool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

var deprecate1 = require('../..')('cool-lib')
var deprecate2 = require('../..')('neat-lib')
var deprecate1 = require('../../..')('cool-lib')
var deprecate2 = require('../../..')('neat-lib')

exports.cool = function () {
deprecate1('cool')
Expand Down
30 changes: 30 additions & 0 deletions test/fixtures/libs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

exports.my = require('./my')
exports.strict = require('./strict')

lazyRequireProperty(exports, 'cool', './cool')
lazyRequireProperty(exports, 'multi', './multi')
lazyRequireProperty(exports, 'new', './new')
lazyRequireProperty(exports, 'old', './old')
lazyRequireProperty(exports, 'thing', './thing')
lazyRequireProperty(exports, 'trace', './trace')

function lazyRequireProperty(obj, prop, path) {
function get() {
var val = require(path)

Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
value: val
})

return val
}

Object.defineProperty(obj, prop, {
configurable: true,
enumerable: true,
get: get
})
}
11 changes: 11 additions & 0 deletions test/fixtures/libs/multi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

var deprecate1 = require('../../..')('multi-lib')
var deprecate2 = require('../../..')('multi-lib-other')

exports.old = function () {
deprecate1('old')
}

exports.old2 = function () {
deprecate2('old2')
}
2 changes: 1 addition & 1 deletion test/fixtures/my-lib.js → test/fixtures/libs/my.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

var deprecate = require('../..')('my-lib')
var deprecate = require('../../..')('my-lib')

exports.fn = fn
exports.prop = 'thingie'
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/thing-lib.js → test/fixtures/libs/new.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

var deprecate = require('../..')('thing-lib')
var deprecate = require('../../..')('new-lib')

exports.old = function () {
deprecate('old')
Expand Down
Loading

0 comments on commit 12833d3

Please sign in to comment.