Skip to content

Commit

Permalink
Added new migration with test (also added jest-extended)
Browse files Browse the repository at this point in the history
  • Loading branch information
Morten Barklund committed Apr 27, 2020
1 parent 47df628 commit 5dcaf4e
Show file tree
Hide file tree
Showing 6 changed files with 639 additions and 0 deletions.
2 changes: 2 additions & 0 deletions assets/src/edit-story/migration/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import pageAdvancement from './migrations/v0011_pageAdvancement';
import setBackgroundTextMode from './migrations/v0012_setBackgroundTextMode';
import videoIdToId from './migrations/v0013_videoIdToId';
import oneTapLinkDeprecate from './migrations/v0014_oneTapLinkDeprecate';
import inlineTextProperties from './migrations/v0015_inlineTextProperties';

const MIGRATIONS = {
1: [storyDataArrayToObject],
Expand All @@ -48,6 +49,7 @@ const MIGRATIONS = {
12: [setBackgroundTextMode],
13: [videoIdToId],
14: [oneTapLinkDeprecate],
15: [inlineTextProperties],
};

export const DATA_VERSION = Math.max.apply(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,352 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Internal dependencies
*/
import inlineTextProperties from '../v0015_inlineTextProperties';

describe('inlineTextProperties', () => {
describe('should parse all text elements', () => {
it('should ignore non-text elements', () => {
expect(
inlineTextProperties({
pages: [
{
elements: [
{
type: 'square',
bold: true,
},
{
type: 'image',
content: 'Horse',
color: 'red',
},
],
},
],
})
).toStrictEqual({
pages: [
{
elements: [
{
type: 'square',
bold: true,
},
{
type: 'image',
content: 'Horse',
color: 'red',
},
],
},
],
});
});

it('should parse multiple text elements on multiple pages', () => {
expect(
inlineTextProperties({
pages: [
{
elements: [
{
type: 'text',
bold: true,
content: 'Hello',
},
{
type: 'text',
textDecoration: 'underline',
content: 'Hello',
},
],
},
{
elements: [
{
type: 'text',
fontStyle: 'italic',
content: 'Hello',
},
{
type: 'text',
fontWeight: 300,
content: 'Hello',
},
],
},
],
})
).toStrictEqual({
pages: [
{
elements: [
{
type: 'text',
content:
'<span class="weight" style="font-weight: 700">Hello</span>',
},
{
type: 'text',
content:
'<span class="underline" style="text-decoration: underline">Hello</span>',
},
],
},
{
elements: [
{
type: 'text',
content:
'<span class="italic" style="font-style: italic">Hello</span>',
},
{
type: 'text',
content:
'<span class="weight" style="font-weight: 300">Hello</span>',
},
],
},
],
});
});

it('should remove all deprecated properties', () => {
const res = inlineTextProperties({
pages: [
{
elements: [
{
type: 'text',
bold: true,
fontWeight: 300,
fontStyle: 'italic',
textDecoration: 'underline',
letterSpacing: 5,
color: { color: { r: 255, g: 0, b: 0 } },
content: 'Hello',
},
],
},
],
});

const convertedElementKeys = res.pages[0].elements[0];
expect(convertedElementKeys).toContainKey('content');
expect(convertedElementKeys).not.toContainKeys([
'bold',
'fontWeight',
'fontStyle',
'textDecoration',
'letterSpacing',
'color',
]);
});
});

function convert(content, properties) {
const converted = inlineTextProperties({
pages: [{ elements: [{ type: 'text', content, ...properties }] }],
});
return converted.pages[0].elements[0].content;
}

it('should convert inline elements', () => {

This comment has been minimized.

Copy link
@miina

miina Apr 28, 2020

Contributor

Would be good to add a test for redundant nested tags as well, e.g. <strong>Lorem <strong>Ipsum</strong> dolor</strong> which doesn't really have a difference visually but is possible to create.

This comment has been minimized.

Copy link
@barklund

barklund Apr 29, 2020

Contributor

Fixed in c4f4c18.

const original = `
Lorem
<strong>ipsum</strong>
<em>dolor</em>
<strong>sit</strong>
amet,
<em>
consectetur
<u>adipiscing</u>
elit
</em>.
`;
const converted = convert(original);
const expected = `
Lorem
<span class="weight" style="font-weight: 700">ipsum</span>
<span class="italic" style="font-style: italic">dolor</span>
<span class="weight" style="font-weight: 700">sit</span>
amet,
<span class="italic" style="font-style: italic">
consectetur
<span class="underline" style="text-decoration: underline">adipiscing</span>
elit
</span>.
`;
expect(converted).toStrictEqual(expected);
});

describe('should correctly interpret bold properties', () => {
it('should correctly interpret bold property and ignore inline elements', () => {
const original = 'Lorem <strong>ipsum</strong>';
const properties = { bold: true };
const converted = convert(original, properties);
const expected =
'<span class="weight" style="font-weight: 700">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should correctly interpret font weight property and ignore inline elements', () => {
const original = 'Lorem <strong>ipsum</strong>';
const properties = { fontWeight: 300 };
const converted = convert(original, properties);
const expected =
'<span class="weight" style="font-weight: 300">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should ignore font weight set to 400', () => {
const original = 'Lorem <strong>ipsum</strong>';
const properties = { fontWeight: 400 };
const converted = convert(original, properties);
const expected =
'Lorem <span class="weight" style="font-weight: 700">ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should use font weight over bold when both set if not 400', () => {
const original = 'Lorem <strong>ipsum</strong>';
const properties = { fontWeight: 300, bold: true };
const converted = convert(original, properties);
const expected =
'<span class="weight" style="font-weight: 300">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should do nothing globally if font weight is 400 and bold is false', () => {
const original = 'Lorem <strong>ipsum</strong>';
const properties = { fontWeight: 400, bold: false };
const converted = convert(original, properties);
const expected =
'Lorem <span class="weight" style="font-weight: 700">ipsum</span>';
expect(converted).toStrictEqual(expected);
});
});

describe('should correctly interpret italic property', () => {
it('should correctly interpret font style property and ignore inline elements', () => {
const original = 'Lorem <em>ipsum</em>';
const properties = { fontStyle: 'italic' };
const converted = convert(original, properties);
const expected =
'<span class="italic" style="font-style: italic">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should ignore font style set to anything but "italic"', () => {
const original = 'Lorem <em>ipsum</em>';
const properties = { fontStyle: 'oblique' };
const converted = convert(original, properties);
const expected =
'Lorem <span class="italic" style="font-style: italic">ipsum</span>';
expect(converted).toStrictEqual(expected);
});
});

describe('should correctly interpret underline property', () => {
it('should correctly interpret text decoration property and ignore inline elements', () => {
const original = 'Lorem <u>ipsum</u>';
const properties = { textDecoration: 'underline' };
const converted = convert(original, properties);
const expected =
'<span class="underline" style="text-decoration: underline">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should ignore text decoration set to anything but "underline"', () => {
const original = 'Lorem <u>ipsum</u>';
const properties = { textDecoration: 'line-through' };
const converted = convert(original, properties);
const expected =
'Lorem <span class="underline" style="text-decoration: underline">ipsum</span>';
expect(converted).toStrictEqual(expected);
});
});

it('should correctly inline color property', () => {
const original = 'Lorem ipsum';
const properties = { color: { color: { r: 255, g: 0, b: 0, a: 0.5 } } };
const converted = convert(original, properties);
const expected =
'<span class="color" style="color: rgba(255, 0, 0, 0.5)">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should correctly inline letter spacing property', () => {
const original = 'Lorem ipsum';
const properties = { letterSpacing: 20 };
const converted = convert(original, properties);
const expected =
'<span class="letterspacing" style="letter-spacing: 0.2em">Lorem ipsum</span>';
expect(converted).toStrictEqual(expected);
});

it('should all work correctly together', () => {
const original = `
Lorem
<strong>ipsum</strong>
<em>dolor</em>
<strong>sit</strong>
amet,
<em>consectetur
<u>adipiscing</u>
elit</em>.
`;
// Here we have global italic, color and letter spacing, but no global font weight or underline.
const properties = {
letterSpacing: 20,
bold: false,
fontWeight: 400,
fontStyle: 'italic',
color: { color: { r: 255, g: 0, b: 0 } },
textDecoration: 'line-through',
};
const converted = convert(original, properties);
const expected = `
<span class="letterspacing" style="letter-spacing: 0.2em">
<span class="color" style="color: rgba(255, 0, 0, 1)">
<span class="italic" style="font-style: italic">
Lorem
<span class="weight" style="font-weight: 700">ipsum</span>
dolor
<span class="weight" style="font-weight: 700">sit</span>
amet,
consectetur
<span class="underline" style="text-decoration: underline">adipiscing</span>
elit.
</span>
</span>
</span>
`;
expect(uniformWhitespace(converted)).toStrictEqual(
uniformWhitespace(expected)
);

function uniformWhitespace(str) {
return str
.replace(/^|$/g, ' ') // insert single space front and back
.replace(/></g, '> <') // and insert space between tags
.replace(/\s+/g, ' '); // and then collapse all multi-whitespace to single space
}
});
});

0 comments on commit 5dcaf4e

Please sign in to comment.