diff --git a/.eslintrc b/.eslintrc
index c60ca9711..8ca14f48b 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -155,5 +155,13 @@
{ "blankLine": "always", "prev": "*", "next": "multiline-block-like" },
{ "blankLine": "any", "prev": "case", "next": "case" }
]
- }
+ },
+ "overrides": [
+ {
+ "files": "**/test/**/*.js",
+ "rules": {
+ "import/no-extraneous-dependencies": false
+ }
+ }
+ ]
}
diff --git a/package.json b/package.json
index d24d41bfe..99fd36eb4 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
"rollup-plugin-uglify": "^3.0.0",
"slate-collapse-on-escape": "^0.6.0",
"slate-dev-benchmark": "*",
+ "slate-dev-test-utils": "*",
"slate-soft-break": "^0.6.0",
"source-map-loader": "^0.2.3",
"source-map-support": "^0.4.0",
diff --git a/packages/slate-dev-benchmark/package.json b/packages/slate-dev-benchmark/package.json
index 1a734a71e..82c4e5dd7 100644
--- a/packages/slate-dev-benchmark/package.json
+++ b/packages/slate-dev-benchmark/package.json
@@ -1,6 +1,6 @@
{
"name": "slate-dev-benchmark",
- "description": "A simple, development-only benchmark for Slate",
+ "description": "INTERNAL: A development-only benchmark tool for Slate's core.",
"version": "0.0.3",
"license": "MIT",
"repository": "git://github.com/ianstormtaylor/slate.git",
@@ -10,8 +10,5 @@
},
"scripts": {
"clean": "rm -rf ./dist ./lib ./node_modules"
- },
- "keywords": [
- "slate"
- ]
+ }
}
diff --git a/packages/slate-dev-environment/package.json b/packages/slate-dev-environment/package.json
index f24de0775..653419b88 100644
--- a/packages/slate-dev-environment/package.json
+++ b/packages/slate-dev-environment/package.json
@@ -1,6 +1,6 @@
{
"name": "slate-dev-environment",
- "description": "Detect browser and OS environments in core Slate packages",
+ "description": "INTERNAL: A set of environment-related constants for Slate's core.",
"version": "0.1.3",
"license": "MIT",
"repository": "git://github.com/ianstormtaylor/slate.git",
@@ -12,13 +12,10 @@
"dist/",
"lib/"
],
- "scripts": {
- "clean": "rm -rf ./dist ./lib ./node_modules"
- },
- "keywords": [
- "slate"
- ],
"dependencies": {
"is-in-browser": "^1.1.3"
+ },
+ "scripts": {
+ "clean": "rm -rf ./dist ./lib ./node_modules"
}
}
diff --git a/packages/slate-dev-logger/package.json b/packages/slate-dev-logger/package.json
index 0d468dc59..26e07c713 100644
--- a/packages/slate-dev-logger/package.json
+++ b/packages/slate-dev-logger/package.json
@@ -1,6 +1,6 @@
{
"name": "slate-dev-logger",
- "description": "A simple, development-only logger for Slate.",
+ "description": "INTERNAL: A simple, development-only logger for Slate.",
"version": "0.1.41",
"license": "MIT",
"repository": "git://github.com/ianstormtaylor/slate.git",
@@ -17,8 +17,5 @@
},
"scripts": {
"clean": "rm -rf ./dist ./lib ./node_modules"
- },
- "keywords": [
- "slate"
- ]
+ }
}
diff --git a/packages/slate-dev-test-utils/Readme.md b/packages/slate-dev-test-utils/Readme.md
new file mode 100644
index 000000000..feda8fe15
--- /dev/null
+++ b/packages/slate-dev-test-utils/Readme.md
@@ -0,0 +1 @@
+This package contains a set of testing utilities used by Slate's other core packages for writing their tests.
diff --git a/packages/slate-dev-test-utils/package.json b/packages/slate-dev-test-utils/package.json
new file mode 100644
index 000000000..26bfbd909
--- /dev/null
+++ b/packages/slate-dev-test-utils/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "slate-dev-test-utils",
+ "description": "INTERNAL: A set of utils for Slate's core tests.",
+ "version": "0.0.0",
+ "license": "MIT",
+ "repository": "git://github.com/ianstormtaylor/slate.git",
+ "main": "src/index.js",
+ "files": [
+ "dist/",
+ "lib/"
+ ],
+ "peerDependencies": {
+ "slate": ">=0.35.0"
+ },
+ "scripts": {
+ "clean": "rm -rf ./dist ./lib ./node_modules"
+ }
+}
diff --git a/packages/slate-dev-test-utils/src/index.js b/packages/slate-dev-test-utils/src/index.js
new file mode 100644
index 000000000..05b033e50
--- /dev/null
+++ b/packages/slate-dev-test-utils/src/index.js
@@ -0,0 +1,59 @@
+import fs from 'fs'
+import { basename, extname, resolve } from 'path'
+import { KeyUtils } from 'slate'
+
+export const fixtures = (...args) => {
+ let fn = args.pop()
+ let options = { skip: false }
+
+ if (typeof fn !== 'function') {
+ options = fn
+ fn = args.pop()
+ }
+
+ const path = resolve(...args)
+ const files = fs.readdirSync(path)
+ const dir = basename(path)
+ const d = options.skip ? describe.skip : describe
+
+ d(dir, () => {
+ for (const file of files) {
+ const p = resolve(path, file)
+ const stat = fs.statSync(p)
+
+ if (stat.isDirectory()) {
+ fixtures(path, file, fn)
+ }
+
+ if (
+ stat.isFile() &&
+ file.endsWith('.js') &&
+ !file.startsWith('.') &&
+ // Ignoring `index.js` files allows us to use the fixtures directly
+ // from the top-level directory itself, instead of only children.
+ file !== 'index.js'
+ ) {
+ const name = basename(file, extname(file))
+
+ // This needs to be a non-arrow function to use `this.skip()`.
+ it(name, function() {
+ // Ensure that the key generator is reset. We have to do this here
+ // because the `require` call will create the Slate objects.
+ KeyUtils.resetGenerator()
+ const module = require(p)
+
+ if (module.skip) {
+ this.skip()
+ return
+ }
+
+ fn({ name, path, module })
+ })
+ }
+ }
+ })
+}
+
+fixtures.skip = (...args) => {
+ fixtures(...args, { skip: true })
+}
diff --git a/packages/slate-dev-test-utils/test/index.js b/packages/slate-dev-test-utils/test/index.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/slate-html-serializer/test/index.js b/packages/slate-html-serializer/test/index.js
index e7eef3c3f..a4addebfb 100644
--- a/packages/slate-html-serializer/test/index.js
+++ b/packages/slate-html-serializer/test/index.js
@@ -1,64 +1,25 @@
-/**
- * Dependencies.
- */
-
import Html from '..'
import assert from 'assert'
-import fs from 'fs'
-import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
-import { Value, KeyUtils } from 'slate'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Reset Slate's internal key generator state before each text.
- */
-
-beforeEach(() => {
- KeyUtils.resetGenerator()
-})
-
-/**
- * Tests.
- */
+import { JSDOM } from 'jsdom'
+import { Value } from 'slate'
+import { fixtures } from 'slate-dev-test-utils'
describe('slate-html-serializer', () => {
- describe('deserialize()', () => {
- const dir = resolve(__dirname, './deserialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, config, options } = module
- const html = new Html({ parseHtml: JSDOM.fragment, ...config })
- const value = html.deserialize(input, options)
- const actual = Value.isValue(value) ? value.toJSON() : value
- const expected = Value.isValue(output) ? output.toJSON() : output
- assert.deepEqual(actual, expected)
- })
- }
+ fixtures(__dirname, 'deserialize', ({ module }) => {
+ const { input, output, config, options } = module
+ const html = new Html({ parseHtml: JSDOM.fragment, ...config })
+ const value = html.deserialize(input, options)
+ const actual = Value.isValue(value) ? value.toJSON() : value
+ const expected = Value.isValue(output) ? output.toJSON() : output
+ assert.deepEqual(actual, expected)
})
- describe('serialize()', () => {
- const dir = resolve(__dirname, './serialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, rules, options } = module
- const html = new Html({ rules, parseHtml: JSDOM.fragment })
- const string = html.serialize(input, options)
- const actual = string
- const expected = output
- assert.deepEqual(actual, expected)
- })
- }
+ fixtures(__dirname, 'serialize', ({ module }) => {
+ const { input, output, rules, options } = module
+ const html = new Html({ rules, parseHtml: JSDOM.fragment })
+ const string = html.serialize(input, options)
+ const actual = string
+ const expected = output
+ assert.deepEqual(actual, expected)
})
})
diff --git a/packages/slate-hyperscript/test/index.js b/packages/slate-hyperscript/test/index.js
index e9335ce24..2629772a3 100644
--- a/packages/slate-hyperscript/test/index.js
+++ b/packages/slate-hyperscript/test/index.js
@@ -1,56 +1,29 @@
import assert from 'assert'
-import fs from 'fs'
-import { Value, KeyUtils } from 'slate'
-import { basename, extname, resolve } from 'path'
-
-beforeEach(KeyUtils.resetGenerator)
+import { Value } from 'slate'
+import { fixtures } from 'slate-dev-test-utils'
describe('slate-hyperscript', () => {
- const dir = resolve(__dirname, './fixtures')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
+ fixtures(__dirname, 'fixtures', ({ module }) => {
+ const { input, output, options } = module
+ const actual = input.toJSON(options)
+ const expected = Value.isValue(output) ? output.toJSON() : output
+ assert.deepEqual(actual, expected)
+ })
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, options } = module
- const actual = input.toJSON(options)
- const expected = Value.isValue(output) ? output.toJSON() : output
- assert.deepEqual(actual, expected)
- })
- }
+ fixtures.skip(__dirname, 'decorations', ({ module }) => {
+ const { input, output, expectDecorations } = module
+ const actual = input.toJSON()
+ const expected = Value.isValue(output) ? output.toJSON() : output
+ assert.deepEqual(actual, expected)
- describe.skip('decorations', () => {
- const decDir = resolve(__dirname, './decorations')
- const decTests = fs
- .readdirSync(decDir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of decTests) {
- it(test, async () => {
- const module = require(resolve(decDir, test))
- const { input, output, expectDecorations } = module
-
- // ensure deserialization was okay
- const actual = input.toJSON()
- const expected = Value.isValue(output) ? output.toJSON() : output
- assert.deepEqual(actual, expected)
-
- // ensure expected properties of decorations match
- // note: they are expected to match order in test result
- expectDecorations.forEach((decoration, i) => {
- Object.keys(decoration).forEach(prop => {
- assert.deepEqual(
- decoration[prop],
- input.decorations.toJS()[i][prop],
- `decoration ${i} had incorrect prop: ${prop}`
- )
- })
- })
+ expectDecorations.forEach((decoration, i) => {
+ Object.keys(decoration).forEach(prop => {
+ assert.deepEqual(
+ decoration[prop],
+ input.decorations.toJS()[i][prop],
+ `decoration ${i} had incorrect prop: ${prop}`
+ )
})
- }
+ })
})
})
diff --git a/packages/slate-plain-serializer/test/index.js b/packages/slate-plain-serializer/test/index.js
index ace3249eb..a9fff740a 100644
--- a/packages/slate-plain-serializer/test/index.js
+++ b/packages/slate-plain-serializer/test/index.js
@@ -1,47 +1,22 @@
import Plain from '..'
import assert from 'assert'
-import fs from 'fs'
-import { Value, KeyUtils } from 'slate'
-import { basename, extname, resolve } from 'path'
-
-beforeEach(KeyUtils.resetGenerator)
+import { Value } from 'slate'
+import { fixtures } from 'slate-dev-test-utils'
describe('slate-plain-serializer', () => {
- describe('deserialize()', () => {
- const dir = resolve(__dirname, './deserialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, options } = module
- const value = Plain.deserialize(input, options)
- const actual = Value.isValue(value) ? value.toJSON() : value
- const expected = Value.isValue(output) ? output.toJSON() : output
- assert.deepEqual(actual, expected)
- })
- }
+ fixtures(__dirname, 'deserialize', ({ module }) => {
+ const { input, output, options } = module
+ const value = Plain.deserialize(input, options)
+ const actual = Value.isValue(value) ? value.toJSON() : value
+ const expected = Value.isValue(output) ? output.toJSON() : output
+ assert.deepEqual(actual, expected)
})
- describe('serialize()', () => {
- const dir = resolve(__dirname, './serialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, options } = module
- const string = Plain.serialize(input, options)
- const actual = string
- const expected = output
- assert.deepEqual(actual, expected)
- })
- }
+ fixtures(__dirname, 'serialize', ({ module }) => {
+ const { input, output, options } = module
+ const string = Plain.serialize(input, options)
+ const actual = string
+ const expected = output
+ assert.deepEqual(actual, expected)
})
})
diff --git a/packages/slate-react/test/index.js b/packages/slate-react/test/index.js
index 1c79e0e04..4e20c8151 100644
--- a/packages/slate-react/test/index.js
+++ b/packages/slate-react/test/index.js
@@ -1,9 +1,42 @@
-import { KeyUtils } from 'slate'
-
-beforeEach(KeyUtils.resetGenerator)
+import AfterPlugin from '../src/plugins/after'
+import assert from 'assert'
+import BeforePlugin from '../src/plugins/before'
+import clean from './helpers/clean'
+import React from 'react'
+import ReactDOM from 'react-dom/server'
+import Simulator from 'slate-simulator'
+import { Editor } from '..'
+import { fixtures } from 'slate-dev-test-utils'
+import { JSDOM } from 'jsdom'
describe('slate-react', () => {
- require('./plugins')
- require('./rendering')
- require('./utils')
+ fixtures.skip(__dirname, 'plugins', ({ module }) => {
+ const { input, output, props = {} } = module
+ const fn = module.default
+ const plugins = [BeforePlugin(props), AfterPlugin(props)]
+ const simulator = new Simulator({ plugins, value: input })
+ fn(simulator)
+
+ const actual = simulator.value.toJSON({ preserveSelection: true })
+ const expected = output.toJSON({ preserveSelection: true })
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'rendering/fixtures', ({ module }) => {
+ const { value, output, props } = module
+ const p = {
+ value,
+ onChange() {},
+ ...(props || {}),
+ }
+
+ const string = ReactDOM.renderToStaticMarkup()
+ const dom = JSDOM.fragment(output)
+ const expected = dom.firstChild.outerHTML
+ .trim()
+ .replace(/\n/gm, '')
+ .replace(/>\s*<')
+
+ assert.equal(clean(string), expected)
+ })
})
diff --git a/packages/slate-react/test/plugins/index.js b/packages/slate-react/test/plugins/index.js
deleted file mode 100644
index 847ef5c4d..000000000
--- a/packages/slate-react/test/plugins/index.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import AfterPlugin from '../../src/plugins/after'
-import BeforePlugin from '../../src/plugins/before'
-import Simulator from 'slate-simulator'
-import assert from 'assert'
-import fs from 'fs'
-import toCamel from 'to-camel-case' // eslint-disable-line import/no-extraneous-dependencies
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('plugins', () => {
- describe.skip('core', () => {
- const dir = resolve(__dirname, 'core')
- const events = fs
- .readdirSync(dir)
- .filter(e => e[0] != '.' && e != 'index.js')
-
- for (const event of events) {
- describe(`${toCamel(event)}`, () => {
- const testDir = resolve(dir, event)
- const tests = fs
- .readdirSync(testDir)
- .filter(t => t[0] != '.' && !!~t.indexOf('.js'))
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(testDir, test))
- const { input, output, props = {} } = module
- const fn = module.default
- const plugins = [BeforePlugin(props), AfterPlugin(props)]
- const simulator = new Simulator({ plugins, value: input })
- fn(simulator)
-
- const actual = simulator.value.toJSON({ preserveSelection: true })
- const expected = output.toJSON({ preserveSelection: true })
- assert.deepEqual(actual, expected)
- })
- }
- })
- }
- })
-})
diff --git a/packages/slate-react/test/rendering/index.js b/packages/slate-react/test/rendering/index.js
deleted file mode 100644
index 3d7d8cb68..000000000
--- a/packages/slate-react/test/rendering/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom/server'
-import assert from 'assert'
-import clean from '../helpers/clean'
-import fs from 'fs-promise' // eslint-disable-line import/no-extraneous-dependencies
-import { JSDOM } from 'jsdom' // eslint-disable-line import/no-extraneous-dependencies
-import { Editor } from '../..'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('rendering', () => {
- const dir = resolve(__dirname, './fixtures')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.' && !!~t.indexOf('.js'))
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { value, output, props } = module
- const p = {
- value,
- onChange() {},
- ...(props || {}),
- }
-
- const string = ReactDOM.renderToStaticMarkup()
- const dom = JSDOM.fragment(output)
- const expected = dom.firstChild.outerHTML
- .trim()
- .replace(/\n/gm, '')
- .replace(/>\s*<')
-
- assert.equal(clean(string), expected)
- })
- }
-})
diff --git a/packages/slate-react/test/utils/get-children-decorations.js b/packages/slate-react/test/utils/get-children-decorations.js
deleted file mode 100644
index 114802e78..000000000
--- a/packages/slate-react/test/utils/get-children-decorations.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/** @jsx h */
-
-import { List } from 'immutable'
-import assert from 'assert'
-
-import h from '../helpers/h'
-
-import getChildrenDecorations from '../../src/utils/get-children-decorations'
-
-const value = (
-
-
-
- First line
-
-
- Second line
-
-
-
-)
-
-const { document } = value
-const [paragraphB] = document.nodes.toArray()
-
-describe('getChildrenDecorations', () => {
- it('should return the child list when no decorations are given', () => {
- const actual = getChildrenDecorations(document, List())
-
- const expected = [[], []]
-
- assert.deepEqual(actual.map(l => l.toArray()), expected)
- })
-
- it('should wrap a block with the range it contains', () => {
- const decoration1 = {
- startKey: 'c',
- startOffset: 1,
- endKey: 'c',
- endOffset: 2,
- decoration: 'd1',
- }
-
- const actual = getChildrenDecorations(document, List([decoration1]))
-
- const expected = [[decoration1], []]
-
- assert.deepEqual(actual.map(l => l.toArray()), expected)
- })
-
- it('should sort two decorations inside a node', () => {
- const decoration1 = {
- startKey: 'c',
- startOffset: 1,
- endKey: 'c',
- endOffset: 2,
- decoration: 'd1',
- }
-
- const decoration2 = {
- startKey: 'c',
- startOffset: 1,
- endKey: 'e',
- endOffset: 2,
- decoration: 'd2',
- }
-
- const actual = getChildrenDecorations(
- document,
- List([decoration1, decoration2])
- )
-
- const expected = [[decoration1, decoration2], [decoration2]]
-
- assert.deepEqual(actual.map(l => l.toArray()), expected)
- })
-
- it('should sort decorations outside the node', () => {
- const decoration1 = {
- startKey: 'c',
- startOffset: 1,
- endKey: 'e',
- endOffset: 2,
- decoration: 'd1',
- }
-
- const actual = getChildrenDecorations(paragraphB, List([decoration1]))
-
- const expected = [[decoration1]]
-
- assert.deepEqual(actual.map(l => l.toArray()), expected)
- })
-})
diff --git a/packages/slate-react/test/utils/index.js b/packages/slate-react/test/utils/index.js
deleted file mode 100644
index 0c164ab99..000000000
--- a/packages/slate-react/test/utils/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { KeyUtils } from 'slate'
-
-beforeEach(KeyUtils.resetGenerator)
-
-describe('utils', () => {
- // require('./get-children-decorations')
-})
diff --git a/packages/slate/package.json b/packages/slate/package.json
index 5556801b2..0089aa9c8 100644
--- a/packages/slate/package.json
+++ b/packages/slate/package.json
@@ -28,7 +28,8 @@
"react": ">=0.14.0"
},
"devDependencies": {
- "slate-hyperscript": "^0.6.2"
+ "slate-hyperscript": "^0.6.2",
+ "slate-dev-test-utils": "*"
},
"scripts": {
"clean": "rm -rf ./dist ./lib ./node_modules"
diff --git a/packages/slate/test/changes/index.js b/packages/slate/test/changes/index.js
deleted file mode 100644
index 5adaa876e..000000000
--- a/packages/slate/test/changes/index.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import assert from 'assert'
-import fs from 'fs-promise' // eslint-disable-line import/no-extraneous-dependencies
-import toCamel from 'to-camel-case' // eslint-disable-line import/no-extraneous-dependencies
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('changes', async () => {
- const dir = resolve(__dirname)
- const categories = fs
- .readdirSync(dir)
- .filter(c => c[0] != '.' && c != 'index.js')
-
- for (const category of categories) {
- describe(category, () => {
- const categoryDir = resolve(dir, category)
- const methods = fs.readdirSync(categoryDir).filter(c => c[0] != '.')
-
- for (const method of methods) {
- describe(toCamel(method), () => {
- const testDir = resolve(categoryDir, method)
- const tests = fs
- .readdirSync(testDir)
- .filter(t => t[0] != '.' && !!~t.indexOf('.js'))
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- const module = require(resolve(testDir, test))
- const { input, output, skip } = module
- const fn = module.default
- const t = skip ? it.skip : it
-
- t(test, async () => {
- const change = input.change()
- fn(change)
- const opts = { preserveSelection: true, preserveData: true }
- const actual = change.value.toJSON(opts)
- const expected = output.toJSON(opts)
- assert.deepEqual(actual, expected)
- })
- }
- })
- }
- })
- }
-})
diff --git a/packages/slate/test/helpers/h.js b/packages/slate/test/helpers/h.js
index f4ab0d7fb..0c38fec09 100644
--- a/packages/slate/test/helpers/h.js
+++ b/packages/slate/test/helpers/h.js
@@ -1,11 +1,5 @@
import { createHyperscript } from 'slate-hyperscript'
-/**
- * Define a hyperscript.
- *
- * @type {Function}
- */
-
const h = createHyperscript({
blocks: {
line: 'line',
@@ -39,10 +33,4 @@ const h = createHyperscript({
},
})
-/**
- * Export.
- *
- * @type {Function}
- */
-
export default h
diff --git a/packages/slate/test/history/index.js b/packages/slate/test/history/index.js
deleted file mode 100644
index 5b143dcbe..000000000
--- a/packages/slate/test/history/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('history', async () => {
- const dir = resolve(__dirname)
- const methods = fs
- .readdirSync(dir)
- .filter(d => d[0] != '.' && d != 'index.js')
-
- for (const method of methods) {
- describe(method, () => {
- const testDir = resolve(dir, method)
- const tests = fs
- .readdirSync(testDir)
- .filter(f => f[0] != '.' && !!~f.indexOf('.js'))
- .map(f => basename(f, extname(f)))
-
- for (const test of tests) {
- const module = require(resolve(testDir, test))
- const { input, output, skip } = module
- const fn = module.default
- const t = skip ? it.skip : it
-
- t(test, async () => {
- const next = fn(input)
- const opts = { preserveSelection: true, preserveData: true }
- const actual = next.toJSON(opts)
- const expected = output.toJSON(opts)
- assert.deepEqual(actual, expected)
- })
- }
- })
- }
-})
diff --git a/packages/slate/test/index.js b/packages/slate/test/index.js
index 56003530a..38b7f4d9d 100644
--- a/packages/slate/test/index.js
+++ b/packages/slate/test/index.js
@@ -1,26 +1,116 @@
-/**
- * Dependencies.
- */
-
-import { KeyUtils } from '..'
-
-/**
- * Tests.
- */
+import assert from 'assert'
+import { fixtures } from 'slate-dev-test-utils'
+import { Node, Schema, Value } from '..'
describe('slate', () => {
- require('./serializers')
- require('./schema')
- require('./changes')
- require('./history')
- require('./operations')
- require('./models')
-})
+ fixtures(__dirname, 'models/leaf', ({ module }) => {
+ const { input, output } = module
+ const fn = module.default
+ const actual = fn(input).toJSON()
+ const expected = output.toJSON()
+ assert.deepEqual(actual, expected)
+ })
-/**
- * Reset Slate's internal key generator state before each text.
- */
+ fixtures(__dirname, 'models/text', ({ module }) => {
+ const { input, output } = module
+ const fn = module.default
+ const actual = fn(input).toJSON()
+ const expected = output.toJSON()
+ assert.deepEqual(actual, expected)
+ })
-beforeEach(() => {
- KeyUtils.resetGenerator()
+ fixtures(__dirname, 'models/node', ({ module }) => {
+ const { input, output } = module
+ const fn = module.default
+ let actual = fn(input)
+ let expected = output
+
+ if (Node.isNode(actual)) {
+ actual = actual.toJSON()
+ }
+
+ if (Node.isNode(expected)) {
+ expected = expected.toJSON()
+ }
+
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'models/change', ({ module }) => {
+ const { input, output, schema, flags, customChange } = module
+ const s = Schema.create(schema)
+ const expected = output.toJSON()
+ const actual = input
+ .change(flags)
+ .setValue({ schema: s })
+ .withoutNormalization(customChange)
+ .value.toJSON()
+
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'serializers/raw/deserialize', ({ module }) => {
+ const { input, output, options } = module
+ const actual = Value.fromJSON(input, options).toJSON()
+ const expected = output.toJSON()
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'serializers/raw/serialize', ({ module }) => {
+ const { input, output, options } = module
+ const actual = input.toJSON(options)
+ const expected = output
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'operations', ({ module }) => {
+ const { input, output } = module
+ const operations = module.default
+ const change = input.change()
+ change.applyOperations(operations)
+ const opts = {
+ preserveSelection: true,
+ preserveDecorations: true,
+ preserveData: true,
+ }
+ const actual = change.value.toJSON(opts)
+ const expected = output.toJSON(opts)
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'changes', ({ module }) => {
+ const { input, output } = module
+ const fn = module.default
+ const change = input.change()
+ fn(change)
+ const opts = { preserveSelection: true, preserveData: true }
+ const actual = change.value.toJSON(opts)
+ const expected = output.toJSON(opts)
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'schema', ({ module }) => {
+ const { input, output, schema } = module
+ const s = Schema.create(schema)
+ let expected = output
+ let actual = input
+ .change()
+ .setValue({ schema: s })
+ .normalize().value
+
+ if (Value.isValue(actual)) actual = actual.toJSON()
+ if (Value.isValue(expected)) expected = expected.toJSON()
+
+ assert.deepEqual(actual, expected)
+ })
+
+ fixtures(__dirname, 'history', ({ module }) => {
+ const { input, output } = module
+ const fn = module.default
+ const next = fn(input)
+ const opts = { preserveSelection: true, preserveData: true }
+ const actual = next.toJSON(opts)
+ const expected = output.toJSON(opts)
+ assert.deepEqual(actual, expected)
+ })
})
diff --git a/packages/slate/test/models/index.js b/packages/slate/test/models/index.js
deleted file mode 100644
index ab28936bc..000000000
--- a/packages/slate/test/models/index.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { Schema } from '../..'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('models', () => {
- describe('change', () => {
- describe('withoutNormalization', () => {
- const testsDir = resolve(__dirname, 'change')
- const tests = fs
- .readdirSync(testsDir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(testsDir, test))
- const { input, output, schema, flags, customChange } = module
- const s = Schema.create(schema)
- const expected = output.toJSON()
- const actual = input
- .change(flags)
- .setValue({ schema: s })
- .withoutNormalization(customChange)
- .value.toJSON()
-
- assert.deepEqual(actual, expected)
- })
- }
- })
- })
-
- describe('node', () => {
- describe('node', () => {
- const testsDir = resolve(__dirname, 'node')
- const tests = fs
- .readdirSync(testsDir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const run = require(resolve(testsDir, test)).default
- run()
- })
- }
- })
- })
-
- require('./text/')
- require('./leaf/')
-})
diff --git a/packages/slate/test/models/leaf/index.js b/packages/slate/test/models/leaf/index.js
deleted file mode 100644
index ba2e46886..000000000
--- a/packages/slate/test/models/leaf/index.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { resolve } from 'path'
-
-describe('leaf', () => {
- const dir = resolve(__dirname)
-
- const methods = fs
- .readdirSync(dir)
- .filter(c => c[0] != '.' && c != 'index.js')
-
- for (const method of methods) {
- describe(method, () => {
- const testDir = resolve(dir, method)
- const tests = fs
- .readdirSync(testDir)
- .filter(t => t[0] != '.' && t.includes('.js'))
-
- for (const test of tests) {
- const module = require(resolve(testDir, test))
- const { input, output, skip } = module
- const fn = module.default
- const t = skip ? it.skip : it
-
- t(test.replace('.js', ''), () => {
- const actual = fn(input)
- const opts = { preserveData: true }
- const expected = output.toJSON(opts)
- assert.deepEqual(actual.toJSON(opts), expected)
- })
- }
- })
- }
-})
diff --git a/packages/slate/test/models/node/get-fragment-at-range.js b/packages/slate/test/models/node/get-fragment-at-range.js
deleted file mode 100644
index e2acafe0b..000000000
--- a/packages/slate/test/models/node/get-fragment-at-range.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-import assert from 'assert'
-
-export default function() {
- const value = (
-
-
-
- one two three
-
-
-
- )
-
- const { document, selection } = value
- const actual = document.getFragmentAtRange(selection)
- const expected = (
-
- two
-
- )
-
- const a = actual.toJSON()
- const e = expected.toJSON()
- assert.deepEqual(a, e)
-}
diff --git a/packages/slate/test/models/node/get-fragment-at-range/block-across.js b/packages/slate/test/models/node/get-fragment-at-range/block-across.js
new file mode 100644
index 000000000..494785f65
--- /dev/null
+++ b/packages/slate/test/models/node/get-fragment-at-range/block-across.js
@@ -0,0 +1,29 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+ one
+
+ two
+
+ th ree
+
+
+
+)
+
+export default function({ document, selection }) {
+ return document.getFragmentAtRange(selection)
+}
+
+export const output = (
+
+ e
+ two
+ th
+
+)
diff --git a/packages/slate/test/models/node/get-fragment-at-range/block.js b/packages/slate/test/models/node/get-fragment-at-range/block.js
new file mode 100644
index 000000000..bdfbc4633
--- /dev/null
+++ b/packages/slate/test/models/node/get-fragment-at-range/block.js
@@ -0,0 +1,23 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+ one two three
+
+
+
+)
+
+export default function({ document, selection }) {
+ return document.getFragmentAtRange(selection)
+}
+
+export const output = (
+
+ two
+
+)
diff --git a/packages/slate/test/models/node/get-furthest-only-child.js b/packages/slate/test/models/node/get-furthest-only-child.js
deleted file mode 100644
index 462a20b62..000000000
--- a/packages/slate/test/models/node/get-furthest-only-child.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/** @jsx h */
-
-import h from '../../helpers/h'
-import assert from 'assert'
-
-export default function() {
- const { document } = (
-
-
- Some Text
-
-
- )
-
- const paragraph = document.nodes.first()
- const text = paragraph.getFirstText()
-
- assert.equal(document.getFurthestOnlyChildAncestor(paragraph.key), null)
- assert.equal(paragraph.getFurthestOnlyChildAncestor(text.key), null)
- assert.equal(document.getFurthestOnlyChildAncestor(text.key), paragraph)
-}
diff --git a/packages/slate/test/models/node/get-furthest-only-child/block-nested.js b/packages/slate/test/models/node/get-furthest-only-child/block-nested.js
new file mode 100644
index 000000000..95801c146
--- /dev/null
+++ b/packages/slate/test/models/node/get-furthest-only-child/block-nested.js
@@ -0,0 +1,24 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+ word
+
+
+
+)
+
+export default function(value) {
+ const { document } = value
+ return document.getFurthestOnlyChildAncestor('a')
+}
+
+export const output = (
+
+ word
+
+)
diff --git a/packages/slate/test/models/node/get-furthest-only-child/block.js b/packages/slate/test/models/node/get-furthest-only-child/block.js
new file mode 100644
index 000000000..548ea6fa0
--- /dev/null
+++ b/packages/slate/test/models/node/get-furthest-only-child/block.js
@@ -0,0 +1,17 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+ word
+
+
+)
+
+export default function({ document }) {
+ return document.getFurthestOnlyChildAncestor('a')
+}
+
+export const output = null
diff --git a/packages/slate/test/models/node/get-furthest-only-child/inline.js b/packages/slate/test/models/node/get-furthest-only-child/inline.js
new file mode 100644
index 000000000..3f9042976
--- /dev/null
+++ b/packages/slate/test/models/node/get-furthest-only-child/inline.js
@@ -0,0 +1,22 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+ one
+ two
+ three
+
+
+
+)
+
+export default function(value) {
+ const { document } = value
+ return document.getFurthestOnlyChildAncestor('a')
+}
+
+export const output = two
diff --git a/packages/slate/test/models/node/get-furthest-only-child/text-nested.js b/packages/slate/test/models/node/get-furthest-only-child/text-nested.js
new file mode 100644
index 000000000..f9d139d8c
--- /dev/null
+++ b/packages/slate/test/models/node/get-furthest-only-child/text-nested.js
@@ -0,0 +1,26 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+
+ word
+
+
+
+
+)
+
+export default function(value) {
+ const { document } = value
+ return document.getFurthestOnlyChildAncestor('a')
+}
+
+export const output = (
+
+ word
+
+)
diff --git a/packages/slate/test/models/node/get-furthest-only-child/text.js b/packages/slate/test/models/node/get-furthest-only-child/text.js
new file mode 100644
index 000000000..5255f9b9f
--- /dev/null
+++ b/packages/slate/test/models/node/get-furthest-only-child/text.js
@@ -0,0 +1,20 @@
+/** @jsx h */
+
+import h from '../../../helpers/h'
+
+export const input = (
+
+
+
+ word
+
+
+
+)
+
+export default function(value) {
+ const { document } = value
+ return document.getFurthestOnlyChildAncestor('a')
+}
+
+export const output = word
diff --git a/packages/slate/test/models/text/index.js b/packages/slate/test/models/text/index.js
deleted file mode 100644
index ab00927c5..000000000
--- a/packages/slate/test/models/text/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { resolve } from 'path'
-
-describe('texts', () => {
- const dir = resolve(__dirname)
-
- const categories = fs
- .readdirSync(dir)
- .filter(c => c[0] != '.' && c != 'index.js')
-
- for (const category of categories) {
- describe(category, () => {
- const categoryDir = resolve(dir, category)
- const methods = fs
- .readdirSync(categoryDir)
- .filter(c => c[0] != '.' && !c.includes('.js'))
-
- for (const method of methods) {
- describe(method, () => {
- const testDir = resolve(categoryDir, method)
- const tests = fs
- .readdirSync(testDir)
- .filter(t => t[0] != '.' && t.includes('.js'))
-
- for (const test of tests) {
- const module = require(resolve(testDir, test))
- const { input, output, skip } = module
- const fn = module.default
- const t = skip ? it.skip : it
-
- t(test.replace('.js', ''), () => {
- const actual = fn(input)
- const opts = { preserveData: true }
- const expected = output.toJSON(opts)
- assert.deepEqual(actual.toJSON(opts), expected)
- })
- }
- })
- }
- })
- }
-})
diff --git a/packages/slate/test/operations/index.js b/packages/slate/test/operations/index.js
deleted file mode 100644
index 1fc5a006b..000000000
--- a/packages/slate/test/operations/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import assert from 'assert'
-import fs from 'fs-promise' // eslint-disable-line import/no-extraneous-dependencies
-import toSnake from 'to-snake-case' // eslint-disable-line import/no-extraneous-dependencies
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('operations', async () => {
- const dir = resolve(__dirname)
- const categories = fs
- .readdirSync(dir)
- .filter(c => c[0] != '.' && c != 'index.js')
-
- for (const category of categories) {
- describe(category, () => {
- const categoryDir = resolve(dir, category)
- const methods = fs.readdirSync(categoryDir).filter(c => c[0] != '.')
-
- for (const method of methods) {
- describe(toSnake(method), () => {
- const testDir = resolve(categoryDir, method)
- const tests = fs
- .readdirSync(testDir)
- .filter(t => t[0] != '.' && !!~t.indexOf('.js'))
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(testDir, test))
- const { input, output } = module
- const operations = module.default
- const change = input.change()
- change.applyOperations(operations)
- const opts = {
- preserveSelection: true,
- preserveDecorations: true,
- preserveData: true,
- }
- const actual = change.value.toJSON(opts)
- const expected = output.toJSON(opts)
- assert.deepEqual(actual, expected)
- })
- }
- })
- }
- })
- }
-})
diff --git a/packages/slate/test/schema/index.js b/packages/slate/test/schema/index.js
deleted file mode 100644
index d54823525..000000000
--- a/packages/slate/test/schema/index.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { Schema } from '../..'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('schema', () => {
- describe('core', () => {
- const testsDir = resolve(__dirname, 'core')
- const tests = fs
- .readdirSync(testsDir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(testsDir, test))
- const { input, output, schema } = module
- const s = Schema.create(schema)
- const expected = output
- const actual = input
- .change()
- .setValue({ schema: s })
- .normalize()
- .value.toJSON()
-
- assert.deepEqual(actual, expected)
- })
- }
- })
-
- describe('custom', () => {
- const testsDir = resolve(__dirname, 'custom')
- const tests = fs
- .readdirSync(testsDir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(testsDir, test))
- const { input, output, schema } = module
- const s = Schema.create(schema)
- const expected = output.toJSON()
- const actual = input
- .change()
- .setValue({ schema: s })
- .normalize()
- .value.toJSON()
-
- assert.deepEqual(actual, expected)
- })
- }
- })
-})
diff --git a/packages/slate/test/serializers/index.js b/packages/slate/test/serializers/index.js
deleted file mode 100644
index 461b2a74a..000000000
--- a/packages/slate/test/serializers/index.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import assert from 'assert'
-import fs from 'fs'
-import { Value } from '../..'
-import { basename, extname, resolve } from 'path'
-
-/**
- * Tests.
- */
-
-describe('serializers', () => {
- describe('raw', () => {
- describe('deserialize()', () => {
- const dir = resolve(__dirname, './raw/deserialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, options } = module
- const actual = Value.fromJSON(input, options).toJSON()
- const expected = output.toJSON()
- assert.deepEqual(actual, expected)
- })
- }
- })
-
- describe('serialize()', () => {
- const dir = resolve(__dirname, './raw/serialize')
- const tests = fs
- .readdirSync(dir)
- .filter(t => t[0] != '.')
- .map(t => basename(t, extname(t)))
-
- for (const test of tests) {
- it(test, async () => {
- const module = require(resolve(dir, test))
- const { input, output, options } = module
- const actual = input.toJSON(options)
- const expected = output
- assert.deepEqual(actual, expected)
- })
- }
- })
- })
-})
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-keys.js b/packages/slate/test/serializers/raw/serialize/preserve-keys.js
index ccb399e47..be4e4b854 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-keys.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-keys.js
@@ -2,6 +2,8 @@
import h from '../../../helpers/h'
+export const skip = true
+
export const input = (
diff --git a/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js b/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
index 320ab29b6..ade359f3b 100644
--- a/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
+++ b/packages/slate/test/serializers/raw/serialize/preserve-selection-and-keys.js
@@ -2,6 +2,8 @@
import h from '../../../helpers/h'
+export const skip = true
+
export const input = (