@wordpress/shortcode
Version:
Shortcode module for WordPress.
310 lines (264 loc) • 8.55 kB
JavaScript
/**
* Internal dependencies
*/
import { next, replace, attrs } from '../';
describe( 'shortcode', () => {
describe( 'next', () => {
it( 'should find the shortcode', () => {
const result = next( 'foo', 'this has the [foo] shortcode' );
expect( result.index ).toBe( 13 );
} );
it( 'should find the shortcode with attributes', () => {
const result = next(
'foo',
'this has the [foo param="foo"] shortcode'
);
expect( result.index ).toBe( 13 );
} );
it( 'should not find shortcodes that are not there', () => {
const result = next( 'bar', 'this has the [foo] shortcode' );
expect( result ).toBe( undefined );
} );
it( 'should not find shortcodes with attributes that are not there', () => {
const result = next(
'bar',
'this has the [foo param="bar"] shortcode'
);
expect( result ).toBe( undefined );
} );
it( 'should find the shortcode when told to start looking beyond the start of the string', () => {
const result1 = next( 'foo', 'this has the [foo] shortcode', 12 );
expect( result1.index ).toBe( 13 );
const result2 = next( 'foo', 'this has the [foo] shortcode', 13 );
expect( result2.index ).toBe( 13 );
const result3 = next( 'foo', 'this has the [foo] shortcode', 14 );
expect( result3 ).toBe( undefined );
} );
it( 'should find the second instances of the shortcode when the starting indice is after the start of the first one', () => {
const result = next(
'foo',
'this has the [foo] shortcode [foo] twice',
14
);
expect( result.index ).toBe( 29 );
} );
it( 'should not find escaped shortcodes', () => {
const result = next( 'foo', 'this has the [[foo]] shortcode' );
expect( result ).toBe( undefined );
} );
it( 'should not find escaped shortcodes with attributes', () => {
const result = next(
'foo',
'this has the [[foo param="foo"]] shortcode'
);
expect( result ).toBe( undefined );
} );
it( 'should find shortcodes that are incorrectly escaped by newlines', () => {
const result1 = next( 'foo', 'this has the [\n[foo]] shortcode' );
expect( result1.index ).toBe( 15 );
const result2 = next( 'foo', 'this has the [[foo]\n] shortcode' );
expect( result2.index ).toBe( 14 );
} );
it( 'should still work when there are not equal amounts of square brackets', () => {
const result1 = next( 'foo', 'this has the [[foo] shortcode' );
expect( result1.index ).toBe( 14 );
const result2 = next( 'foo', 'this has the [foo]] shortcode' );
expect( result2.index ).toBe( 13 );
} );
it( 'should find the second instances of the shortcode when the first one is escaped', () => {
const result = next(
'foo',
'this has the [[foo]] shortcode [foo] twice'
);
expect( result.index ).toBe( 31 );
} );
it( 'should not find shortcodes that are not full matches', () => {
const result1 = next( 'foo', 'this has the [foobar] shortcode' );
expect( result1 ).toBe( undefined );
const result2 = next( 'foobar', 'this has the [foo] shortcode' );
expect( result2 ).toBe( undefined );
} );
} );
describe( 'replace', () => {
it( 'should replace the shortcode', () => {
const result1 = replace(
'foo',
'this has the [foo] shortcode',
() => 'bar'
);
expect( result1 ).toBe( 'this has the bar shortcode' );
const result2 = replace(
'foo',
'this has the [foo param="foo"] shortcode',
() => 'bar'
);
expect( result2 ).toBe( 'this has the bar shortcode' );
} );
it( 'should replace the shortcode with data from an attribute', () => {
const result1 = replace(
'foo',
'this [foo param="replacement text"] came from a shortcode attribute',
( match ) => {
return match.attrs.named.param || '';
}
);
expect( result1 ).toBe(
'this replacement text came from a shortcode attribute'
);
} );
it( 'should not replace the shortcode when it does not match', () => {
const result1 = replace(
'bar',
'this has the [foo] shortcode',
() => 'bar'
);
expect( result1 ).toBe( 'this has the [foo] shortcode' );
const result2 = replace(
'bar',
'this has the [foo param="bar"] shortcode',
() => 'bar'
);
expect( result2 ).toBe(
'this has the [foo param="bar"] shortcode'
);
} );
it( 'should replace the shortcode in all instances of its use', () => {
const result1 = replace(
'foo',
'this has the [foo] shortcode [foo] twice',
() => 'bar'
);
expect( result1 ).toBe( 'this has the bar shortcode bar twice' );
const result2 = replace(
'foo',
'this has the [foo param="foo"] shortcode [foo] twice',
() => 'bar'
);
expect( result2 ).toBe( 'this has the bar shortcode bar twice' );
} );
it( 'should not replace the escaped shortcodes', () => {
const result1 = replace(
'foo',
'this has the [[foo]] shortcode',
() => 'bar'
);
expect( result1 ).toBe( 'this has the [[foo]] shortcode' );
const result2 = replace(
'foo',
'this has the [[foo param="bar"]] shortcode',
() => 'bar'
);
expect( result2 ).toBe(
'this has the [[foo param="bar"]] shortcode'
);
const result3 = replace(
'foo',
'this [foo] has the [[foo param="bar"]] shortcode escaped',
() => 'bar'
);
expect( result3 ).toBe(
'this bar has the [[foo param="bar"]] shortcode escaped'
);
} );
it( 'should replace improperly escaped shortcodes that include newlines', () => {
const result1 = replace(
'foo',
'this [foo] has the [[foo param="bar"]\n] shortcode ',
() => 'bar'
);
expect( result1 ).toBe( 'this bar has the [bar\n] shortcode ' );
const result2 = replace(
'foo',
'this [foo] has the [\n[foo param="bar"]] shortcode ',
() => 'bar'
);
expect( result2 ).toBe( 'this bar has the [\nbar] shortcode ' );
} );
it( 'should not replace the shortcode when it is an incomplete match', () => {
const result1 = replace(
'foo',
'this has the [foobar] shortcode',
() => 'bar'
);
expect( result1 ).toBe( 'this has the [foobar] shortcode' );
const result2 = replace(
'foobar',
'this has the [foo] shortcode',
() => 'bar'
);
expect( result2 ).toBe( 'this has the [foo] shortcode' );
} );
it( 'should replace shortcode with a number', () => {
const result1 = replace( 'foo', 'hello [foo] world', () => 3 );
expect( result1 ).toBe( 'hello 3 world' );
const result2 = replace(
'foo',
'hello [foo bar=bar baz="baz" qux]delete me[/foo] world',
() => 4
);
expect( result2 ).toBe( 'hello 4 world' );
} );
it( 'should replace shortcode with an empty string', () => {
const result1 = replace( 'foo', 'hello [foo] world', () => '' );
expect( result1 ).toBe( 'hello world' );
const result2 = replace(
'foo',
'hello [foo bar=bar baz="baz" qux]delete me[/foo] world',
() => ''
);
expect( result2 ).toBe( 'hello world' );
} );
} );
describe( 'attrs', () => {
it( 'should return named attributes created with single, double, and no quotes', () => {
const result = attrs( `param="foo" another='bar' andagain=baz` );
const expected = {
named: {
param: 'foo',
another: 'bar',
andagain: 'baz',
},
numeric: [],
};
expect( result ).toEqual( expected );
} );
it( 'should return numeric attributes in the order they are used', () => {
const result = attrs( 'foo bar baz' );
const expected = {
named: {},
numeric: [ 'foo', 'bar', 'baz' ],
};
expect( result ).toEqual( expected );
} );
it( 'should return numeric attributes in the order they are used when they have named attributes in between', () => {
const result = attrs( 'foo not="a blocker" bar baz' );
const expected = {
named: {
not: 'a blocker',
},
numeric: [ 'foo', 'bar', 'baz' ],
};
expect( result ).toEqual( expected );
} );
it( 'should return numeric attributes created with single, double, and no quotes', () => {
const result = attrs( `foo "bar" 'baz'` );
const expected = {
named: {},
numeric: [ 'foo', 'bar', 'baz' ],
};
expect( result ).toEqual( expected );
} );
it( 'should return mixed attributes created with single, double, and no quotes', () => {
const result = attrs( `a="foo" b='bar' c=baz foo "bar" 'baz'` );
const expected = {
named: {
a: 'foo',
b: 'bar',
c: 'baz',
},
numeric: [ 'foo', 'bar', 'baz' ],
};
expect( result ).toEqual( expected );
} );
} );
} );