From dac640161fbce38836ebc2848ea6a847382db2dd Mon Sep 17 00:00:00 2001 From: qejk Date: Thu, 12 Jan 2017 20:21:59 +0100 Subject: [PATCH 01/33] We need more lemon pledge --- package.js | 51 ------------------- .../contain-array-of-structs.coffee | 33 ------------ source/assertions/depend_on.coffee | 25 --------- source/assertions/extend.coffee | 13 ----- .../assertions/match-array-of-structs.coffee | 31 ----------- source/assertions/to_match.coffee | 16 ------ source/helpers/is-subclass.coffee | 4 -- test.sh | 9 ---- tests/assertions/depend_on.integration.coffee | 21 -------- tests/assertions/extend.spec.coffee | 16 ------ tests/assertions/to_match.integration.coffee | 31 ----------- 11 files changed, 250 deletions(-) delete mode 100644 package.js delete mode 100644 source/assertions/contain-array-of-structs.coffee delete mode 100644 source/assertions/depend_on.coffee delete mode 100644 source/assertions/extend.coffee delete mode 100644 source/assertions/match-array-of-structs.coffee delete mode 100644 source/assertions/to_match.coffee delete mode 100644 source/helpers/is-subclass.coffee delete mode 100755 test.sh delete mode 100644 tests/assertions/depend_on.integration.coffee delete mode 100644 tests/assertions/extend.spec.coffee delete mode 100644 tests/assertions/to_match.integration.coffee diff --git a/package.js b/package.js deleted file mode 100644 index 6610169..0000000 --- a/package.js +++ /dev/null @@ -1,51 +0,0 @@ -Package.describe({ - summary: 'Helpers for Testing Space Applications and Modules.', - name: 'space:testing', - version: '3.0.2', - git: 'https://github.com/meteor-space/testing.git', - debugOnly: true -}); - -Package.onUse(function(api) { - - api.versionsFrom('1.0'); - - api.use([ - 'coffeescript', - 'underscore', - 'reactive-var', - 'reactive-dict', - 'tracker', - 'check', - 'practicalmeteor:munit@2.1.5' - ]); - - api.addFiles([ - 'source/helpers/is-subclass.coffee', - 'source/assertions/depend_on.coffee', - 'source/assertions/extend.coffee', - 'source/assertions/to_match.coffee', - 'source/assertions/match-array-of-structs.coffee', - 'source/assertions/contain-array-of-structs.coffee' - ]); - -}); - -Package.onTest(function(api) { - - api.use([ - 'coffeescript', - 'check', - 'mongo', - 'underscore', - 'space:testing', - 'practicalmeteor:munit@2.1.5' - ]); - - api.addFiles([ - 'tests/assertions/depend_on.integration.coffee', - 'tests/assertions/extend.spec.coffee', - 'tests/assertions/to_match.integration.coffee' - ]); - -}); diff --git a/source/assertions/contain-array-of-structs.coffee b/source/assertions/contain-array-of-structs.coffee deleted file mode 100644 index 7093624..0000000 --- a/source/assertions/contain-array-of-structs.coffee +++ /dev/null @@ -1,33 +0,0 @@ -chai.use (chai, utils) -> - - chai.Assertion.addMethod 'containArrayOfStructs', (expected) -> - - # Filter out structs we don't need to test for - actual = _.filter(this._obj, (actualStruct) -> - _.any(expected, (expectedStruct) -> - _.isEqual(expectedStruct.toString(), actualStruct.toString()) - ) - ) - - untestedProperties = ['timestamp', 'version', 'meta', 'schemaVersion'] - - for actualStruct, index in actual - for key, type of actualStruct.fields() - if _.isFunction(expected[index][key]) - # Check that the actual value is of the expected type - check actualStruct[key], expected[index][key] - # Copy over the actual value, so that they are equal - expected[index][key] = actualStruct[key] - else if _.contains(untestedProperties, key) - delete expected[index][key] - delete actualStruct[key] - - # Format for error messages - actualString = JSON.stringify(actual, null, 2) - - for struct, index in expected - structString = JSON.stringify(struct, null, 2) - this.assert( - _.any(actual, (item) -> _.isEqual(item, struct) ), - "Expected Struct #{struct.toString()} #{structString} not contained in #{actualString}" - ) diff --git a/source/assertions/depend_on.coffee b/source/assertions/depend_on.coffee deleted file mode 100644 index 7350cb5..0000000 --- a/source/assertions/depend_on.coffee +++ /dev/null @@ -1,25 +0,0 @@ - -chai.use (chai, utils) -> - - chai.Assertion.addMethod 'dependOn', (dependencies) -> - - input = this._obj - - this.assert( - utils.type(input.prototype.Dependencies) == 'object', - "expected #{input} to declare dependencies", - "", - dependencies, - input.prototype.Dependencies - ) - - expected = JSON.stringify dependencies, null, 2 - actual = JSON.stringify input.prototype.Dependencies, null, 2 - - this.assert( - utils.eql(input.prototype.Dependencies, dependencies), - "expected #{input} to depend on:\n#{expected}\nbut was:\n#{actual}", - "", - dependencies, - input.prototype.Dependencies - ) diff --git a/source/assertions/extend.coffee b/source/assertions/extend.coffee deleted file mode 100644 index b3dd6a0..0000000 --- a/source/assertions/extend.coffee +++ /dev/null @@ -1,13 +0,0 @@ -chai.use (chai, utils) -> - - chai.Assertion.addMethod 'extend', (baseClass) -> - - input = this._obj - - this.assert( - input.__super__.constructor == baseClass, - "expected #{input} to extend baseClass", - "", - baseClass, - input.__super__.constructor - ) diff --git a/source/assertions/match-array-of-structs.coffee b/source/assertions/match-array-of-structs.coffee deleted file mode 100644 index f2acb49..0000000 --- a/source/assertions/match-array-of-structs.coffee +++ /dev/null @@ -1,31 +0,0 @@ -chai.use (chai, utils) -> - - chai.Assertion.addMethod 'matchArrayOfStructs', (expected) -> - - actual = this._obj - - untestedProperties = ['timestamp', 'version', 'meta', 'schemaVersion'] - - for struct, index in actual - for key, type of struct.fields() - if _.isFunction(expected[index][key]) - # Check that the actual value is of the expected type - check struct[key], expected[index][key] - # Copy over the actual value, so that they are equal - expected[index][key] = struct[key] - else if _.contains(untestedProperties, key) - delete expected[index][key] - delete struct[key] - - # Turn the structs into JSON so that we can output them - # in readable structure in the tests. - actualString = JSON.stringify(actual, null, 2) - expectedString = JSON.stringify(expected, null, 2) - - this.assert( - _.isEqual(actual, expected), - "expected #{actualString} to match #{expectedString}", - "", - actualString, - expectedString - ) diff --git a/source/assertions/to_match.coffee b/source/assertions/to_match.coffee deleted file mode 100644 index ace7b6d..0000000 --- a/source/assertions/to_match.coffee +++ /dev/null @@ -1,16 +0,0 @@ -chai.use (chai, utils) -> - - chai.Assertion.addMethod 'toMatch', (expectation) -> - - input = this._obj - - actual = JSON.stringify input, null, 2 - expected = JSON.stringify expectation, null, 2 - - this.assert( - sinon.match(expectation).test(input), - "expected #{actual} to match #{expected}", - "", - expectation, - input - ) diff --git a/source/helpers/is-subclass.coffee b/source/helpers/is-subclass.coffee deleted file mode 100644 index 795d38e..0000000 --- a/source/helpers/is-subclass.coffee +++ /dev/null @@ -1,4 +0,0 @@ -@isSubclassOf = (sub, sup) -> - isSubclass = sub.prototype instanceof sup - isSameClass = sub is sup - return isSubclass || isSameClass diff --git a/test.sh b/test.sh deleted file mode 100755 index 7b9cd76..0000000 --- a/test.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -export PACKAGE_DIRS='packages' - -if [ "$PORT" ]; then - meteor test-packages ./ --port $PORT -else - meteor test-packages ./ -fi diff --git a/tests/assertions/depend_on.integration.coffee b/tests/assertions/depend_on.integration.coffee deleted file mode 100644 index 33d7e5f..0000000 --- a/tests/assertions/depend_on.integration.coffee +++ /dev/null @@ -1,21 +0,0 @@ - -describe 'Space.testing', -> - - describe 'Classes', -> - - class TestClass - Dependencies: - first: 'first' - second: 'second' - - describe '#dependOn', -> - - it 'checks if a given class depends on other stuff', -> - expect(TestClass).to.dependOn { - first: 'first' - second: 'second' - } - - it 'throws nice error if expectations fail', -> - fail = -> expect(TestClass).to.dependOn first: 'first' - expect(fail).to.throw Error diff --git a/tests/assertions/extend.spec.coffee b/tests/assertions/extend.spec.coffee deleted file mode 100644 index 360e73f..0000000 --- a/tests/assertions/extend.spec.coffee +++ /dev/null @@ -1,16 +0,0 @@ - -describe 'Space.testing', -> - - describe 'Classes', -> - - class BaseClass - class TestClass extends BaseClass - - describe '#extend', -> - - it 'checks if a given coffeescript class extends another', -> - expect(TestClass).to.extend BaseClass - - it 'throws error if expectations fail', -> - fail = -> expect(TestClass).to.extend {} - expect(fail).to.throw Error diff --git a/tests/assertions/to_match.integration.coffee b/tests/assertions/to_match.integration.coffee deleted file mode 100644 index fae2369..0000000 --- a/tests/assertions/to_match.integration.coffee +++ /dev/null @@ -1,31 +0,0 @@ - -describe 'Space.testing', -> - - describe '#toMatch', -> - - class Test - class Other - - it 'checks if a given object matches the expectation', -> - - input = - number: 1 - string: 'test' - instance: new Test - - expect(input).toMatch - number: sinon.match.number - string: sinon.match.string - instance: sinon.match.instanceOf(Test) - - it 'throws when it does not match', -> - - expect(-> expect(null).toMatch {}).to.throw Error - expect(-> expect(number: 1).toMatch number: sinon.match.string).to.throw Error - - it 'can be negated', -> - - expect(number: 1, string: 'test', instance: new Test).not.toMatch - number: sinon.match.string - string: sinon.match.number - instance: sinon.match.instanceOf(Other) From 3cb396a2e8b9dce0c777c5eab8508824c6cf84a2 Mon Sep 17 00:00:00 2001 From: qejk Date: Thu, 12 Jan 2017 20:23:13 +0100 Subject: [PATCH 02/33] Updates package to npm --- .babelrc | 6 + .eslintrc | 176 ++++++++++++++++++ circle.yml | 14 +- package.json | 41 +++++ src/assertions/contain-array-of-structs.js | 72 ++++++++ src/assertions/depend-on.js | 52 ++++++ src/assertions/extend.js | 54 ++++++ src/assertions/match-array-of-structs.js | 68 +++++++ src/assertions/same.js | 45 +++++ src/helpers/is-subclass.js | 7 + src/space-testing.js | 204 +++++++++++++++++++++ test/assertions/depend-on.integration.js | 29 +++ test/assertions/extend.spec.js | 30 +++ test/assertions/same.integration.js | 43 +++++ test/common.js | 4 + test/mocha.opts | 7 + 16 files changed, 843 insertions(+), 9 deletions(-) create mode 100644 .babelrc create mode 100644 .eslintrc create mode 100644 package.json create mode 100644 src/assertions/contain-array-of-structs.js create mode 100644 src/assertions/depend-on.js create mode 100644 src/assertions/extend.js create mode 100644 src/assertions/match-array-of-structs.js create mode 100644 src/assertions/same.js create mode 100644 src/helpers/is-subclass.js create mode 100644 src/space-testing.js create mode 100644 test/assertions/depend-on.integration.js create mode 100644 test/assertions/extend.spec.js create mode 100644 test/assertions/same.integration.js create mode 100644 test/common.js create mode 100644 test/mocha.opts diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..e518608 --- /dev/null +++ b/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["es2015"], + "plugins": [ + "add-module-exports" + ] +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..78c0eb9 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,176 @@ +/** + * 0 - turn the rule off + * 1 - turn the rule on as a warning (doesn't affect exit code) + * 2 - turn the rule on as an error (exit code will be 1) + * + * Meteor Style Guide: https://github.com/meteor/meteor/wiki/Meteor-Style-Guide + * + */ + +{ + "parser": "babel-eslint", + "env": { + "browser": true, + "node": true + }, + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "jsx": true + }, + "rules": { + /** + * Strict mode + */ + // babel inserts "use strict"; for us + // http://eslint.org/docs/rules/strict + "strict": 0, + + /** + * ES6 + */ + "no-var": 1, // http://eslint.org/docs/rules/no-var + + /** + * Variables + */ + "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow + "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names + "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars + "vars": "local", + "args": "after-used" + }], + "no-use-before-define": [2, "nofunc"], // http://eslint.org/docs/rules/no-use-before-define + + /** + * Possible errors + */ + "comma-dangle": [1, "never"], // http://eslint.org/docs/rules/comma-dangle + "no-cond-assign": [2, "always"], // http://eslint.org/docs/rules/no-cond-assign + "no-console": 1, // http://eslint.org/docs/rules/no-console + "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger + "no-alert": 1, // http://eslint.org/docs/rules/no-alert + "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition + "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys + "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case + "no-empty": 2, // http://eslint.org/docs/rules/no-empty + "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign + "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast + "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi + "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign + "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations + "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp + "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace + "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls + "quote-props": [2, "as-needed", { "keywords": true, "unnecessary": false }], // http://eslint.org/docs/rules/quote-props (previously known as no-reserved-keys) + "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays + "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable + "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan + "block-scoped-var": 0, // http://eslint.org/docs/rules/block-scoped-var + + /** + * Best practices + */ + "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return + "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly + "default-case": 2, // http://eslint.org/docs/rules/default-case + "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation + "allowKeywords": true + }], + "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq + "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in + "no-caller": 2, // http://eslint.org/docs/rules/no-caller + //"no-else-return": 2, // http://eslint.org/docs/rules/no-else-return + "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null + "no-eval": 2, // http://eslint.org/docs/rules/no-eval + "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native + "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind + "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough + "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal + "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval + "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks + "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func + "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str + "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign + "no-new": 2, // http://eslint.org/docs/rules/no-new + "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func + "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers + "no-octal": 2, // http://eslint.org/docs/rules/no-octal + "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape + "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign + "no-proto": 2, // http://eslint.org/docs/rules/no-proto + "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare + "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign + "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url + "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare + "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences + "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal + "no-with": 2, // http://eslint.org/docs/rules/no-with + "radix": 2, // http://eslint.org/docs/rules/radix + "vars-on-top": 1, // http://eslint.org/docs/rules/vars-on-top + "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife + "yoda": 2, // http://eslint.org/docs/rules/yoda + "max-len": [1, 200, 2], // http://eslint.org/docs/rules/max-len + + /** + * Style + */ + "indent": [2, 2, {"VariableDeclarator": 2}], // http://eslint.org/docs/rules/indent + "brace-style": [2, // http://eslint.org/docs/rules/brace-style + "1tbs", { + "allowSingleLine": true + }], + "camelcase": [2, { // http://eslint.org/docs/rules/camelcase + "properties": "never" + }], + "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing + "before": false, + "after": true + }], + "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style + "eol-last": 2, // http://eslint.org/docs/rules/eol-last + "func-names": 0, // http://eslint.org/docs/rules/func-names + "func-style": [2, "expression"], // http://eslint.org/docs/rules/func-style + "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing + "beforeColon": false, + "afterColon": true + }], + "new-cap": [2, { // http://eslint.org/docs/rules/new-cap + "newIsCap": true, + "capIsNew": false + }], + "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines + "max": 2 + }], + "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary + "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object + "no-array-constructor": 2, // http://eslint.org/docs/rules/no-array-constructor + "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func + "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces + "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle + "one-var": [1, "never"], // http://eslint.org/docs/rules/one-var + "semi": [2, "always"], // http://eslint.org/docs/rules/semi + "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing + "before": false, + "after": true + }], + "keyword-spacing": 2, // http://eslint.org/docs/rules/space-after-keywords + "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks + "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren + "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops + "spaced-comment": 2, // http://eslint.org/docs/rules/spaced-comment (previously known as spaced-line-comment) + } +} \ No newline at end of file diff --git a/circle.yml b/circle.yml index 65ddaf5..47c0606 100644 --- a/circle.yml +++ b/circle.yml @@ -1,16 +1,12 @@ machine: node: - version: 0.10.33 - environment: - PACKAGE_DIRS: packages + version: 4.0.0 pre: - curl https://install.meteor.com | /bin/sh dependencies: - pre: - - npm install -g mgp - - npm install -g spacejam - override: - - mgp + cache_directories: + - node_modules + test: override: - - spacejam test-packages ./ + - mocha --compilers js:babel-register --recursive tests/**/*.js diff --git a/package.json b/package.json new file mode 100644 index 0000000..3dd3b11 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "space-testing", + "version": "4.0.0", + "description": "Helpers for Testing Space Applications and Modules", + "main": "src/space-testing.js", + "keywords": [ + "space", + "modular", + "architecture", + "testing" + ], + "author": "Dominik Guzei, Rhys Bartels-Waller, Darko Mijic, Adam Desivi", + "contributors": [ + "Dominik Guzei (https://github.com/DominikGuzei)", + "Rhys Bartels-Waller (https://github.com/rhyslbw)", + "Darko Mijić (https://github.com/darko-mijic)", + "Adam Desivi (https://github.com/qejk)" + ], + "license": "MIT", + "engines": { + "node": ">= 4.0.x", + "npm": ">= 1.4.x" + }, + "dependencies": { + "underscore": "^1.8.0", + "lodash": "^4.17.0" + }, + "devDependencies": { + "babel-core": "^6.21.0", + "babel-cli": "^6.18.0", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-preset-es2015": "^6.14.0", + "chai": "^3.5.0", + "sinon": "^1.17.7", + "mocha": "^3.2.0" + }, + "scripts": { + "test": "mocha --require babel-core/register --recursive test/**/*.js", + "test-watch": "npm test -- --watch" + } +} \ No newline at end of file diff --git a/src/assertions/contain-array-of-structs.js b/src/assertions/contain-array-of-structs.js new file mode 100644 index 0000000..1a2fd6e --- /dev/null +++ b/src/assertions/contain-array-of-structs.js @@ -0,0 +1,72 @@ +const _ = require('underscore'); +const ObjectEntries = require('lodash/entries'); +const ObjectKeys = require('lodash/keys'); + +(function(plugin) { + if ( + typeof require === "function" && + typeof exports === "object" && + typeof module === "object" + ) { + // NodeJS + module.exports = plugin; + } else if ( + typeof define === "function" && + define.amd + ) { + // AMD + define(function() { + return plugin; + }); + } else { + // Other environment (usually