From 782e55d616e30ccc920471eea4112de28d1db7d8 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 29 Mar 2017 17:55:53 -0400 Subject: [PATCH 1/6] Include nested test directories in test glob --- webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index f34bec3ad3b6a..8372bc39cac00 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -85,7 +85,7 @@ switch ( process.env.NODE_ENV ) { './element/index.js', './blocks/index.js', './editor/index.js', - ...glob.sync( `./{${ Object.keys( config.entry ).join() }}/test/*.js` ) + ...glob.sync( `./{${ Object.keys( config.entry ).join() }}/**/test/*.js` ) ]; config.externals = [ require( 'webpack-node-externals' )() ]; config.output = { From a1938df50b68491d424b77eb9e77ac7ea0589e14 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 29 Mar 2017 17:56:04 -0400 Subject: [PATCH 2/6] Move block registration to standalone file --- blocks/index.js | 82 +---------------------- blocks/parser/index.js | 2 +- blocks/parser/test/index.js | 2 +- blocks/registration.js | 80 ++++++++++++++++++++++ blocks/test/{index.js => registration.js} | 2 +- 5 files changed, 84 insertions(+), 84 deletions(-) create mode 100644 blocks/registration.js rename blocks/test/{index.js => registration.js} (98%) diff --git a/blocks/index.js b/blocks/index.js index aaec78468ef9e..ab1bea06dd3aa 100644 --- a/blocks/index.js +++ b/blocks/index.js @@ -1,5 +1,3 @@ -/* eslint-disable no-console */ - /** * External dependencies */ @@ -9,82 +7,4 @@ export { query }; export { default as Editable } from './components/editable'; export { default as parse } from './parser'; export { getCategories } from './categories'; - -/** - * Block settings keyed by block slug. - * - * @var {Object} blocks - */ -const blocks = {}; - -/** - * Registers a new block provided a unique slug and an object defining its - * behavior. Once registered, the block is made available as an option to any - * editor interface where blocks are implemented. - * - * @param {string} slug Block slug - * @param {Object} settings Block settings - * @return {?WPBlock} The block, if it has been successfully - * registered; otherwise `undefined`. - */ -export function registerBlock( slug, settings ) { - if ( typeof slug !== 'string' ) { - console.error( - 'Block slugs must be strings.' - ); - return; - } - if ( ! /^[a-z0-9-]+\/[a-z0-9-]+$/.test( slug ) ) { - console.error( - 'Block slugs must contain a namespace prefix. Example: my-plugin/my-custom-block' - ); - return; - } - if ( blocks[ slug ] ) { - console.error( - 'Block "' + slug + '" is already registered.' - ); - return; - } - const block = Object.assign( { slug }, settings ); - blocks[ slug ] = block; - return block; -} - -/** - * Unregisters a block. - * - * @param {string} slug Block slug - * @return {?WPBlock} The previous block value, if it has been - * successfully unregistered; otherwise `undefined`. - */ -export function unregisterBlock( slug ) { - if ( ! blocks[ slug ] ) { - console.error( - 'Block "' + slug + '" is not registered.' - ); - return; - } - const oldBlock = blocks[ slug ]; - delete blocks[ slug ]; - return oldBlock; -} - -/** - * Returns settings associated with a registered block. - * - * @param {string} slug Block slug - * @return {?Object} Block settings - */ -export function getBlockSettings( slug ) { - return blocks[ slug ]; -} - -/** - * Returns all registered blocks. - * - * @return {Array} Block settings - */ -export function getBlocks() { - return Object.values( blocks ); -} +export * from './registration'; diff --git a/blocks/parser/index.js b/blocks/parser/index.js index 4576de19ce58e..0ec2b11ffc059 100644 --- a/blocks/parser/index.js +++ b/blocks/parser/index.js @@ -7,7 +7,7 @@ import * as query from 'hpq'; * Internal dependencies */ import { parse as grammarParse } from './post.pegjs'; -import { getBlockSettings } from '../'; +import { getBlockSettings } from '../registration'; /** * Returns the block attributes of a registered block node given its settings. diff --git a/blocks/parser/test/index.js b/blocks/parser/test/index.js index 3e99a02f5d8c6..04a78efad2d63 100644 --- a/blocks/parser/test/index.js +++ b/blocks/parser/test/index.js @@ -8,7 +8,7 @@ import { text } from 'hpq'; * Internal dependencies */ import { default as parse, getBlockAttributes } from '../'; -import * as blocks from '../../'; +import * as blocks from '../../registration'; describe( 'block parser', () => { describe( 'getBlockAttributes()', () => { diff --git a/blocks/registration.js b/blocks/registration.js new file mode 100644 index 0000000000000..f3593ce9b09f8 --- /dev/null +++ b/blocks/registration.js @@ -0,0 +1,80 @@ +/* eslint-disable no-console */ + +/** + * Block settings keyed by block slug. + * + * @var {Object} blocks + */ +const blocks = {}; + +/** + * Registers a new block provided a unique slug and an object defining its + * behavior. Once registered, the block is made available as an option to any + * editor interface where blocks are implemented. + * + * @param {string} slug Block slug + * @param {Object} settings Block settings + * @return {?WPBlock} The block, if it has been successfully + * registered; otherwise `undefined`. + */ +export function registerBlock( slug, settings ) { + if ( typeof slug !== 'string' ) { + console.error( + 'Block slugs must be strings.' + ); + return; + } + if ( ! /^[a-z0-9-]+\/[a-z0-9-]+$/.test( slug ) ) { + console.error( + 'Block slugs must contain a namespace prefix. Example: my-plugin/my-custom-block' + ); + return; + } + if ( blocks[ slug ] ) { + console.error( + 'Block "' + slug + '" is already registered.' + ); + return; + } + const block = Object.assign( { slug }, settings ); + blocks[ slug ] = block; + return block; +} + +/** + * Unregisters a block. + * + * @param {string} slug Block slug + * @return {?WPBlock} The previous block value, if it has been + * successfully unregistered; otherwise `undefined`. + */ +export function unregisterBlock( slug ) { + if ( ! blocks[ slug ] ) { + console.error( + 'Block "' + slug + '" is not registered.' + ); + return; + } + const oldBlock = blocks[ slug ]; + delete blocks[ slug ]; + return oldBlock; +} + +/** + * Returns settings associated with a registered block. + * + * @param {string} slug Block slug + * @return {?Object} Block settings + */ +export function getBlockSettings( slug ) { + return blocks[ slug ]; +} + +/** + * Returns all registered blocks. + * + * @return {Array} Block settings + */ +export function getBlocks() { + return Object.values( blocks ); +} diff --git a/blocks/test/index.js b/blocks/test/registration.js similarity index 98% rename from blocks/test/index.js rename to blocks/test/registration.js index eb649bdf38909..2c29795448b1d 100644 --- a/blocks/test/index.js +++ b/blocks/test/registration.js @@ -9,7 +9,7 @@ import sinon from 'sinon'; /** * Internal dependencies */ -import * as blocks from '../'; +import * as blocks from '../registration'; describe( 'blocks', () => { // Reset block state before each test. From 00c858f2c0f43df568b52a49f191e04031a6ef58 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 30 Mar 2017 09:42:10 -0400 Subject: [PATCH 3/6] Set explicit named exports from entry Potentially a bug with Webpack being unable to find keys to export from wildcard? --- blocks/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/index.js b/blocks/index.js index ab1bea06dd3aa..83d496a96f7aa 100644 --- a/blocks/index.js +++ b/blocks/index.js @@ -7,4 +7,4 @@ export { query }; export { default as Editable } from './components/editable'; export { default as parse } from './parser'; export { getCategories } from './categories'; -export * from './registration'; +export { registerBlock, unregisterBlock, getBlockSettings, getBlocks } from './registration'; From 3bf9d856315de70983fce8435a64361ad67ddcee Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 30 Mar 2017 09:45:00 -0400 Subject: [PATCH 4/6] Flatten parser into blocks directory --- blocks/{parser/index.js => parser.js} | 2 +- blocks/{parser => }/post.pegjs | 0 blocks/{parser/test/index.js => test/parser.js} | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename blocks/{parser/index.js => parser.js} (96%) rename blocks/{parser => }/post.pegjs (100%) rename blocks/{parser/test/index.js => test/parser.js} (94%) diff --git a/blocks/parser/index.js b/blocks/parser.js similarity index 96% rename from blocks/parser/index.js rename to blocks/parser.js index 0ec2b11ffc059..d89ea1fddd555 100644 --- a/blocks/parser/index.js +++ b/blocks/parser.js @@ -7,7 +7,7 @@ import * as query from 'hpq'; * Internal dependencies */ import { parse as grammarParse } from './post.pegjs'; -import { getBlockSettings } from '../registration'; +import { getBlockSettings } from './registration'; /** * Returns the block attributes of a registered block node given its settings. diff --git a/blocks/parser/post.pegjs b/blocks/post.pegjs similarity index 100% rename from blocks/parser/post.pegjs rename to blocks/post.pegjs diff --git a/blocks/parser/test/index.js b/blocks/test/parser.js similarity index 94% rename from blocks/parser/test/index.js rename to blocks/test/parser.js index 04a78efad2d63..ec08a568ae3fe 100644 --- a/blocks/parser/test/index.js +++ b/blocks/test/parser.js @@ -7,8 +7,8 @@ import { text } from 'hpq'; /** * Internal dependencies */ -import { default as parse, getBlockAttributes } from '../'; -import * as blocks from '../../registration'; +import { default as parse, getBlockAttributes } from '../parser'; +import * as blocks from '../registration'; describe( 'block parser', () => { describe( 'getBlockAttributes()', () => { From a84ccb60cec56e2c92789f1224d65b592f4329a3 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 30 Mar 2017 09:47:32 -0400 Subject: [PATCH 5/6] Use named imports in test Avoid referring to registration as canonical "blocks" --- blocks/test/parser.js | 4 ++-- blocks/test/registration.js | 48 ++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/blocks/test/parser.js b/blocks/test/parser.js index ec08a568ae3fe..8255453582904 100644 --- a/blocks/test/parser.js +++ b/blocks/test/parser.js @@ -8,7 +8,7 @@ import { text } from 'hpq'; * Internal dependencies */ import { default as parse, getBlockAttributes } from '../parser'; -import * as blocks from '../registration'; +import { getBlocks, unregisterBlock, registerBlock } from '../registration'; describe( 'block parser', () => { describe( 'getBlockAttributes()', () => { @@ -63,7 +63,7 @@ describe( 'block parser', () => { }; } }; - blocks.registerBlock( 'core/test-block', blockSettings ); + registerBlock( 'core/test-block', blockSettings ); const postContent = 'Ribs' + 'Ribs'; diff --git a/blocks/test/registration.js b/blocks/test/registration.js index 2c29795448b1d..ee6e15137c17d 100644 --- a/blocks/test/registration.js +++ b/blocks/test/registration.js @@ -9,13 +9,13 @@ import sinon from 'sinon'; /** * Internal dependencies */ -import * as blocks from '../registration'; +import { getBlocks, unregisterBlock, registerBlock, getBlockSettings } from '../registration'; describe( 'blocks', () => { // Reset block state before each test. beforeEach( () => { - blocks.getBlocks().forEach( block => { - blocks.unregisterBlock( block.slug ); + getBlocks().forEach( block => { + unregisterBlock( block.slug ); } ); sinon.stub( console, 'error' ); } ); @@ -26,41 +26,41 @@ describe( 'blocks', () => { describe( 'registerBlock()', () => { it( 'should reject numbers', () => { - const block = blocks.registerBlock( 999 ); + const block = registerBlock( 999 ); expect( console.error ).to.have.been.calledWith( 'Block slugs must be strings.' ); expect( block ).to.be.undefined(); } ); it( 'should reject blocks without a namespace', () => { - const block = blocks.registerBlock( 'doing-it-wrong' ); + const block = registerBlock( 'doing-it-wrong' ); expect( console.error ).to.have.been.calledWith( 'Block slugs must contain a namespace prefix. Example: my-plugin/my-custom-block' ); expect( block ).to.be.undefined(); } ); it( 'should reject blocks with invalid characters', () => { - const block = blocks.registerBlock( 'still/_doing_it_wrong' ); + const block = registerBlock( 'still/_doing_it_wrong' ); expect( console.error ).to.have.been.calledWith( 'Block slugs must contain a namespace prefix. Example: my-plugin/my-custom-block' ); expect( block ).to.be.undefined(); } ); it( 'should accept valid block names', () => { - const block = blocks.registerBlock( 'my-plugin/fancy-block-4' ); + const block = registerBlock( 'my-plugin/fancy-block-4' ); expect( console.error ).to.not.have.been.called(); expect( block ).to.eql( { slug: 'my-plugin/fancy-block-4' } ); } ); it( 'should prohibit registering the same block twice', () => { - blocks.registerBlock( 'core/test-block' ); - const block = blocks.registerBlock( 'core/test-block' ); + registerBlock( 'core/test-block' ); + const block = registerBlock( 'core/test-block' ); expect( console.error ).to.have.been.calledWith( 'Block "core/test-block" is already registered.' ); expect( block ).to.be.undefined(); } ); it( 'should store a copy of block settings', () => { const blockSettings = { settingName: 'settingValue' }; - blocks.registerBlock( 'core/test-block-with-settings', blockSettings ); + registerBlock( 'core/test-block-with-settings', blockSettings ); blockSettings.mutated = true; - expect( blocks.getBlockSettings( 'core/test-block-with-settings' ) ).to.eql( { + expect( getBlockSettings( 'core/test-block-with-settings' ) ).to.eql( { slug: 'core/test-block-with-settings', settingName: 'settingValue', } ); @@ -69,35 +69,35 @@ describe( 'blocks', () => { describe( 'unregisterBlock()', () => { it( 'should fail if a block is not registered', () => { - const oldBlock = blocks.unregisterBlock( 'core/test-block' ); + const oldBlock = unregisterBlock( 'core/test-block' ); expect( console.error ).to.have.been.calledWith( 'Block "core/test-block" is not registered.' ); expect( oldBlock ).to.be.undefined(); } ); it( 'should unregister existing blocks', () => { - blocks.registerBlock( 'core/test-block' ); - expect( blocks.getBlocks() ).to.eql( [ + registerBlock( 'core/test-block' ); + expect( getBlocks() ).to.eql( [ { slug: 'core/test-block' }, ] ); - const oldBlock = blocks.unregisterBlock( 'core/test-block' ); + const oldBlock = unregisterBlock( 'core/test-block' ); expect( console.error ).to.not.have.been.called(); expect( oldBlock ).to.eql( { slug: 'core/test-block' } ); - expect( blocks.getBlocks() ).to.eql( [] ); + expect( getBlocks() ).to.eql( [] ); } ); } ); describe( 'getBlockSettings()', () => { it( 'should return { slug } for blocks with no settings', () => { - blocks.registerBlock( 'core/test-block' ); - expect( blocks.getBlockSettings( 'core/test-block' ) ).to.eql( { + registerBlock( 'core/test-block' ); + expect( getBlockSettings( 'core/test-block' ) ).to.eql( { slug: 'core/test-block', } ); } ); it( 'should return all block settings', () => { const blockSettings = { settingName: 'settingValue' }; - blocks.registerBlock( 'core/test-block-with-settings', blockSettings ); - expect( blocks.getBlockSettings( 'core/test-block-with-settings' ) ).to.eql( { + registerBlock( 'core/test-block-with-settings', blockSettings ); + expect( getBlockSettings( 'core/test-block-with-settings' ) ).to.eql( { slug: 'core/test-block-with-settings', settingName: 'settingValue', } ); @@ -106,14 +106,14 @@ describe( 'blocks', () => { describe( 'getBlocks()', () => { it( 'should return an empty array at first', () => { - expect( blocks.getBlocks() ).to.eql( [] ); + expect( getBlocks() ).to.eql( [] ); } ); it( 'should return all registered blocks', () => { - blocks.registerBlock( 'core/test-block' ); + registerBlock( 'core/test-block' ); const blockSettings = { settingName: 'settingValue' }; - blocks.registerBlock( 'core/test-block-with-settings', blockSettings ); - expect( blocks.getBlocks() ).to.eql( [ + registerBlock( 'core/test-block-with-settings', blockSettings ); + expect( getBlocks() ).to.eql( [ { slug: 'core/test-block' }, { slug: 'core/test-block-with-settings', settingName: 'settingValue' }, ] ); From 4d3ebaafa91fff226740f15c79de7b9041220b48 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Thu, 30 Mar 2017 09:48:17 -0400 Subject: [PATCH 6/6] Reset blocks before each parser test --- blocks/test/parser.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/blocks/test/parser.js b/blocks/test/parser.js index 8255453582904..907489f7552e5 100644 --- a/blocks/test/parser.js +++ b/blocks/test/parser.js @@ -11,6 +11,12 @@ import { default as parse, getBlockAttributes } from '../parser'; import { getBlocks, unregisterBlock, registerBlock } from '../registration'; describe( 'block parser', () => { + beforeEach( () => { + getBlocks().forEach( ( block ) => { + unregisterBlock( block.slug ); + } ); + } ); + describe( 'getBlockAttributes()', () => { it( 'should merge attributes from function implementation', () => { const blockSettings = {