From 742b06f1a41554c5d68ef686baa55afc33d576b8 Mon Sep 17 00:00:00 2001 From: Josh Rowley Date: Mon, 28 Jul 2014 15:13:47 -0400 Subject: [PATCH] repace sinon with mockery, :100: tests --- lib/index.coffee | 135 +++++++++++------------ package.json | 5 +- test/fixtures/missing_token/app.coffee | 16 +++ test/fixtures/missing_token/index.jade | 1 + test/fixtures/missing_token/package.json | 6 + test/support/helpers.js | 4 +- test/test.coffee | 72 +++++++----- 7 files changed, 132 insertions(+), 107 deletions(-) create mode 100644 test/fixtures/missing_token/app.coffee create mode 100644 test/fixtures/missing_token/index.jade create mode 100644 test/fixtures/missing_token/package.json diff --git a/lib/index.coffee b/lib/index.coffee index 3b51231..0237fb9 100644 --- a/lib/index.coffee +++ b/lib/index.coffee @@ -22,82 +22,71 @@ module.exports = (opts) -> accessToken: opts.access_token space: opts.space_id - ###* - * Configures content types set in app.coffee. Sets default values if - * optional config options are missing. - * @param {Array} types - content_types set in app.coffee extension config - * @return {Promise} - returns an array of configured content types - ### - - configure_content = (types) -> - W.map types, (t) -> - if not t.id then return W.reject(errors.no_type_id) - if t.name then return W.resolve(t) - t.filters ?= {} - W client.contentType(t.id).then (res) -> - t.name = pluralize(S(res.name).toLowerCase().underscore().s) - return t - - ###* - * Fetches data from Contentful API, formats the raw data, and constructs - * the locals object - * @param {Array} types - configured content_type objects - * @return {Promise} - returns formatted locals object with all content - ### - - get_all_content = (types) -> - W.reduce types, (m, t) -> - fetch_content(t) - .then(format_content) - .then((c) -> m[t.name] = c) - .yield(m) - , {} - - ###* - * Fetch entries for a single content type object - * @param {Object} type - content type object - * @return {Promise} - returns response from Contentful API - ### - - fetch_content = (type) -> - W client.entries(_.merge(type.filters, content_type: type.id)) - - ###* - * Formats raw response from Contentful - * @param {Object} content - entries API response for a content type - * @return {Promise} - returns formatted content type entries object - ### - - format_content = (content) -> - W.map(content, format_entry) - - ###* - * Formats a single entry object from Contentful API response - * @param {Object} e - single entry object from API response - * @return {Promise} - returns formatted entry object - ### - - format_entry = (e) -> - if _.has(e.fields, 'sys') then return W.reject(errors.sys_conflict) - _.assign(_.omit(e, 'fields'), e.fields) - - content = [] - class RootsContentful constructor: (@roots) -> @roots.config.locals ||= {} setup: -> - if content.length - configure_content(opts.content_types) + configure_content(opts.content_types) .then(get_all_content) - .then (res) -> content = res - else - W.resolve() - - compile_hooks: -> - before_pass: (ctx) => - # once content is loaded, pass contentful data into locals - promise.then (locals) => - if @roots.config.locals.contentful then return - @roots.config.locals.contentful = locals + .then (res) => + @roots.config.locals.contentful = res + + ###* + * Configures content types set in app.coffee. Sets default values if + * optional config options are missing. + * @param {Array} types - content_types set in app.coffee extension config + * @return {Promise} - returns an array of configured content types + ### + + configure_content = (types) -> + W.map types, (t) -> + if not t.id then return W.reject(errors.no_type_id) + if t.name then return W.resolve(t) + t.filters ?= {} + W client.contentType(t.id).then (res) -> + t.name = pluralize(S(res.name).toLowerCase().underscore().s) + return t + + ###* + * Fetches data from Contentful API, formats the raw data, and constructs + * the locals object + * @param {Array} types - configured content_type objects + * @return {Promise} - returns formatted locals object with all content + ### + + get_all_content = (types) -> + W.reduce types, (m, t) -> + fetch_content(t) + .then(format_content) + .then((c) -> m[t.name] = c) + .yield(m) + , {} + + ###* + * Fetch entries for a single content type object + * @param {Object} type - content type object + * @return {Promise} - returns response from Contentful API + ### + + fetch_content = (type) -> + W client.entries(_.merge(type.filters, content_type: type.id)) + + ###* + * Formats raw response from Contentful + * @param {Object} content - entries API response for a content type + * @return {Promise} - returns formatted content type entries object + ### + + format_content = (content) -> + W.map(content, format_entry) + + ###* + * Formats a single entry object from Contentful API response + * @param {Object} e - single entry object from API response + * @return {Promise} - returns formatted entry object + ### + + format_entry = (e) -> + if _.has(e.fields, 'sys') then return W.reject(errors.sys_conflict) + _.assign(_.omit(e, 'fields'), e.fields) diff --git a/package.json b/package.json index 152c55c..0761c3f 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,7 @@ }, "dependencies": { "lodash": "~2.4.1", - "minimatch": "0.2.x", - "roots-util": "0.0.4", + "roots-util": "~0.0.5", "contentful": "~0.1.2", "when": "~3.4.2", "string": "~1.9.0", @@ -23,7 +22,7 @@ "istanbul": "0.3.x", "mocha": "1.x", "roots": "3.x", - "sinon": "1.x" + "mockery": "~1.4.0" }, "peerDependencies": { "roots": "3.x" diff --git a/test/fixtures/missing_token/app.coffee b/test/fixtures/missing_token/app.coffee new file mode 100644 index 0000000..96412f9 --- /dev/null +++ b/test/fixtures/missing_token/app.coffee @@ -0,0 +1,16 @@ +contentful = require '../../..' + +module.exports = + ignores: ["**/_*", "**/.DS_Store"] + extensions: [ + contentful( + content_types: [ + { + name: 'test' + } + { + id: '7CDlVsacqQc88cmIEGYWMa' + } + ] + ) + ] diff --git a/test/fixtures/missing_token/index.jade b/test/fixtures/missing_token/index.jade new file mode 100644 index 0000000..8240f0e --- /dev/null +++ b/test/fixtures/missing_token/index.jade @@ -0,0 +1 @@ +h1 wow diff --git a/test/fixtures/missing_token/package.json b/test/fixtures/missing_token/package.json new file mode 100644 index 0000000..2d0ae2c --- /dev/null +++ b/test/fixtures/missing_token/package.json @@ -0,0 +1,6 @@ +{ + "name": "test", + "dependencies": { + "jade": "*" + } +} diff --git a/test/support/helpers.js b/test/support/helpers.js index fee43b1..6ca23af 100644 --- a/test/support/helpers.js +++ b/test/support/helpers.js @@ -1,6 +1,6 @@ var chai = require('chai'), chai_promise = require('chai-as-promised'), - sinon = require('sinon'), + mockery = require('mockery'), path = require('path'), _path = path.join(__dirname, '../fixtures'), RootsUtil = require('roots-util'), @@ -11,7 +11,7 @@ var should = chai.should(); chai.use(chai_promise); global.should = should; -global.sinon = sinon; +global.mockery = mockery; global._path = _path; global.h = h; global.roots_contentful = roots_contentful; diff --git a/test/test.coffee b/test/test.coffee index 47c2284..e83576a 100644 --- a/test/test.coffee +++ b/test/test.coffee @@ -1,3 +1,4 @@ +_ = require 'lodash' path = require 'path' fs = require 'fs' W = require 'when' @@ -8,21 +9,31 @@ Roots = require 'roots' compile_fixture = (fixture_name, done) -> @public = path.join(fixture_name, 'public') - node.call(h.project.compile.bind(h), Roots, fixture_name) - -stub_contentful = (opts = {}) -> - contentful = require 'contentful' - sinon.stub(contentful, 'createClient').returns - contentType: -> W.resolve(opts.content_type || { name: 'Blog Post' }) - entries: -> W.resolve [ - opts.entry || { - sys: {'sys': 'data'}, - fields: { - title: 'Default Title' - body: 'Default Body' - } - } - ] + h.project.compile(Roots, fixture_name) + +mock_contentful = (opts = {}) -> + mockery.enable + warnOnUnregistered: false + useCleanCache: true + + opts = _.defaults opts, + entry: + sys: + sys: 'data' + fields: + title: 'Default Title' + body: 'Default Body' + content_type: + name: 'Blog Post' + + mockery.registerMock 'contentful', + createClient: -> + contentType: -> W.resolve(opts.content_type) + entries: -> W.resolve [ opts.entry ] + +unmock_contentful = -> + mockery.deregisterAll() + mockery.disable() before (done) -> h.project.install_dependencies('*', done) @@ -33,26 +44,30 @@ after -> # tests describe 'config', -> + before -> mock_contentful() + it 'should throw an error when missing an access token', -> - (-> roots_contentful()).should.throw() + (-> compile_fixture.call(@, 'missing_token')).should.throw() it 'should throw an error without content type id', -> compile_fixture.call(@, 'missing_config').should.be.rejected - describe 'contentful content type fields', -> - before -> @stub = stub_contentful(entry: {fields: {sys: 'test'}}) + after -> unmock_contentful() + +describe 'contentful content type fields', -> + before -> mock_contentful(entry: {fields: {sys: 'test'}}) - it 'should throw an error if `sys` is a field name', -> - compile_fixture.call(@, 'basic').should.be.rejected + it 'should throw an error if `sys` is a field name', -> + compile_fixture.call(@, 'basic').should.be.rejected - after -> @stub.restore() + after -> unmock_contentful() describe 'basic compile', -> before (done) -> @title = 'Throw Some Ds' @body = 'Rich Boy selling crick' - @stub = stub_contentful(entry: {fields: {title: @title, body: @body}}) - compile_fixture.call(@, 'basic').then(-> done()) + mock_contentful(entry: {fields: {title: @title, body: @body}}) + compile_fixture.call(@, 'basic').then(-> done()).catch(done) it 'compiles basic project', -> p = path.join(@public, 'index.html') @@ -63,20 +78,19 @@ describe 'basic compile', -> h.file.contains(p, @title).should.be.true h.file.contains(p, @body).should.be.true - after -> - @stub.restore() + after -> unmock_contentful() describe 'custom name for view helper local', -> before (done) -> @title = 'Throw Some Ds' @body = 'Rich Boy selling crack' - @stub = stub_contentful(entry: {fields: {title: @title, body: @body}}) - compile_fixture.call(@, 'custom_name', -> done()) + mock_contentful(entry: {fields: {title: @title, body: @body}}) + compile_fixture.call(@, 'custom_name').then(-> done()) + .catch(done) it 'has contentful data available in views under a custom name', -> p = path.join(@public, 'index.html') h.file.contains(p, @title).should.be.true h.file.contains(p, @body).should.be.true - after -> - @stub.restore() + after -> unmock_contentful()