mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 10:51:44 +02:00
working on moving components into the schema
This commit is contained in:
@@ -93,8 +93,8 @@ class Editor extends React.Component {
|
||||
super(props)
|
||||
this.tmp = {}
|
||||
this.state = {}
|
||||
this.state.schema = Schema.create(props.schema)
|
||||
this.state.plugins = this.resolvePlugins(props)
|
||||
this.state.schema = this.resolveSchema(this.state.plugins)
|
||||
this.state.state = this.onBeforeChange(props.state)
|
||||
|
||||
// Mix in the event handlers.
|
||||
@@ -112,16 +112,10 @@ class Editor extends React.Component {
|
||||
*/
|
||||
|
||||
componentWillReceiveProps = (props) => {
|
||||
if (props.schema != this.props.schema) {
|
||||
this.setState({
|
||||
schema: Schema.create(props.schema)
|
||||
})
|
||||
}
|
||||
|
||||
if (props.plugins != this.props.plugins) {
|
||||
this.setState({
|
||||
plugins: this.resolvePlugins(props)
|
||||
})
|
||||
const plugins = this.resolvePlugins(props)
|
||||
const schema = this.resolveSchema(plugins)
|
||||
this.setState({ plugins, schema })
|
||||
}
|
||||
|
||||
this.setState({
|
||||
@@ -269,6 +263,7 @@ class Editor extends React.Component {
|
||||
renderDecorations={this.renderDecorations}
|
||||
renderMark={this.renderMark}
|
||||
renderNode={this.renderNode}
|
||||
schema={this.state.schema}
|
||||
spellCheck={this.props.spellCheck}
|
||||
state={this.state.state}
|
||||
style={this.props.style}
|
||||
@@ -361,6 +356,27 @@ class Editor extends React.Component {
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the editor's schema from a set of `plugins`.
|
||||
*
|
||||
* @param {Array} plugins
|
||||
* @return {Schema}
|
||||
*/
|
||||
|
||||
resolveSchema = (plugins) => {
|
||||
let rules = []
|
||||
|
||||
for (const plugin of plugins) {
|
||||
if (!plugin.schema) continue
|
||||
debugger
|
||||
const schema = Schema.create(plugin.schema)
|
||||
rules = rules.concat(schema.rules)
|
||||
}
|
||||
|
||||
const schema = Schema.create({ rules })
|
||||
return schema
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -53,6 +53,17 @@ class Mark extends new Record(DEFAULTS) {
|
||||
return 'mark'
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component for the node from a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {Component || Void}
|
||||
*/
|
||||
|
||||
getComponent(schema) {
|
||||
return schema.__getComponent(this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -338,6 +338,17 @@ const Node = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the component for the node from a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {Component || Void}
|
||||
*/
|
||||
|
||||
getComponent(schema) {
|
||||
return schema.__getComponent(this)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a descendant node by `key`.
|
||||
*
|
||||
@@ -1071,10 +1082,74 @@ const Node = {
|
||||
updateDescendant(node) {
|
||||
this.assertDescendant(node)
|
||||
return this.mapDescendants(d => d.key == node.key ? node : d)
|
||||
},
|
||||
|
||||
/**
|
||||
* Validate the node against a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {Object || Void}
|
||||
*/
|
||||
|
||||
validate(schema) {
|
||||
return schema.__validate(this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Memoize read methods.
|
||||
*/
|
||||
|
||||
memoize(Node, [
|
||||
'assertChild',
|
||||
'assertDescendant',
|
||||
'findDescendant',
|
||||
'filterDescendants',
|
||||
'getBlocks',
|
||||
'getBlocksAtRange',
|
||||
'getCharactersAtRange',
|
||||
'getChild',
|
||||
'getChildrenAfter',
|
||||
'getChildrenAfterIncluding',
|
||||
'getChildrenBefore',
|
||||
'getChildrenBeforeIncluding',
|
||||
'getChildrenBetween',
|
||||
'getChildrenBetweenIncluding',
|
||||
'getClosest',
|
||||
'getClosestBlock',
|
||||
'getClosestInline',
|
||||
'getComponent',
|
||||
'getDescendant',
|
||||
'getDepth',
|
||||
'getFragmentAtRange',
|
||||
'getFurthest',
|
||||
'getFurthestBlock',
|
||||
'getFurthestInline',
|
||||
'getHighestChild',
|
||||
'getHighestOnlyChildParent',
|
||||
'getInlinesAtRange',
|
||||
'getMarksAtRange',
|
||||
'getNextBlock',
|
||||
'getNextSibling',
|
||||
'getNextText',
|
||||
'getOffset',
|
||||
'getOffsetAtRange',
|
||||
'getParent',
|
||||
'getPreviousSibling',
|
||||
'getPreviousText',
|
||||
'getPreviousBlock',
|
||||
'getTextAtOffset',
|
||||
'getTextDirection',
|
||||
'getTexts',
|
||||
'getTextsAtRange',
|
||||
'hasChild',
|
||||
'hasDescendant',
|
||||
'hasVoidParent',
|
||||
'isInlineSplitAtRange',
|
||||
'validate'
|
||||
])
|
||||
|
||||
/**
|
||||
* Normalize a `key`, from a key string or a node.
|
||||
*
|
||||
@@ -1119,57 +1194,6 @@ for (const key in Transforms) {
|
||||
Node[key] = Transforms[key]
|
||||
}
|
||||
|
||||
/**
|
||||
* Memoize read methods.
|
||||
*/
|
||||
|
||||
memoize(Node, [
|
||||
'assertChild',
|
||||
'assertDescendant',
|
||||
'findDescendant',
|
||||
'filterDescendants',
|
||||
'getBlocks',
|
||||
'getBlocksAtRange',
|
||||
'getCharactersAtRange',
|
||||
'getChildrenAfter',
|
||||
'getChildrenAfterIncluding',
|
||||
'getChildrenBefore',
|
||||
'getChildrenBeforeIncluding',
|
||||
'getChildrenBetween',
|
||||
'getChildrenBetweenIncluding',
|
||||
'getClosest',
|
||||
'getClosestBlock',
|
||||
'getClosestInline',
|
||||
'getChild',
|
||||
'getDescendant',
|
||||
'getDepth',
|
||||
'getFragmentAtRange',
|
||||
'getFurthest',
|
||||
'getFurthestBlock',
|
||||
'getFurthestInline',
|
||||
'getHighestChild',
|
||||
'getHighestOnlyChildParent',
|
||||
'getInlinesAtRange',
|
||||
'getMarksAtRange',
|
||||
'getNextBlock',
|
||||
'getNextSibling',
|
||||
'getNextText',
|
||||
'getOffset',
|
||||
'getOffsetAtRange',
|
||||
'getParent',
|
||||
'getPreviousSibling',
|
||||
'getPreviousText',
|
||||
'getPreviousBlock',
|
||||
'getTextAtOffset',
|
||||
'getTextDirection',
|
||||
'getTexts',
|
||||
'getTextsAtRange',
|
||||
'hasChild',
|
||||
'hasDescendant',
|
||||
'hasVoidParent',
|
||||
'isInlineSplitAtRange'
|
||||
])
|
||||
|
||||
/**
|
||||
* Export.
|
||||
*/
|
||||
|
@@ -65,7 +65,7 @@ const CHECKS = {
|
||||
const { nodes } = object
|
||||
if (!nodes) return
|
||||
const invalids = nodes.filterNot((child) => {
|
||||
return value.some(fail => !fail(child))
|
||||
return value.some(match => match(child))
|
||||
})
|
||||
|
||||
if (invalids.size) return invalids
|
||||
@@ -75,7 +75,7 @@ const CHECKS = {
|
||||
const { nodes } = object
|
||||
if (!nodes) return
|
||||
const invalids = nodes.filterNot((child) => {
|
||||
return value.every(fail => fail(child))
|
||||
return value.every(match => !match(child))
|
||||
})
|
||||
|
||||
if (invalids.size) return invalids
|
||||
@@ -86,10 +86,10 @@ const CHECKS = {
|
||||
if (!nodes) return
|
||||
if (nodes.size != value.length) return nodes
|
||||
|
||||
const invalids = nodes.filter((child, i) => {
|
||||
const fail = value[i]
|
||||
if (!fail) return true
|
||||
return fail(child)
|
||||
const invalids = nodes.filterNot((child, i) => {
|
||||
const match = value[i]
|
||||
if (!match) return false
|
||||
return match(child)
|
||||
})
|
||||
|
||||
if (invalids.size) return invalids
|
||||
@@ -138,62 +138,47 @@ class Schema extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a `state` to abide by the schema.
|
||||
* Return the component for an `object`.
|
||||
*
|
||||
* @param {State} state
|
||||
* @return {State}
|
||||
* This method is private, because it should always be called on one of the
|
||||
* often-changing immutable objects instead, since it will be memoized for
|
||||
* much better performance.
|
||||
*
|
||||
* @param {Mixed} object
|
||||
* @return {Component || Void}
|
||||
*/
|
||||
|
||||
transform(state) {
|
||||
const { document } = state
|
||||
let transform = state.transform()
|
||||
let failure
|
||||
|
||||
document.filterDescendantsDeep((node) => {
|
||||
if (failure = this.validateNode(node)) {
|
||||
const { reason, rule } = failure
|
||||
transform = rule.transform(transform, node, reason)
|
||||
}
|
||||
})
|
||||
|
||||
if (failure = this.validateNode(document)) {
|
||||
const { reason, rule } = failure
|
||||
transform = rule.transform(transform, document, reason)
|
||||
}
|
||||
|
||||
const next = transform.apply({ snapshot: false })
|
||||
return next
|
||||
__getComponent(object) {
|
||||
const match = this.rules.find(rule => rule.match(object) && rule.component)
|
||||
if (!match) return
|
||||
return match.component
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a `state` against the schema.
|
||||
* Validate an `object` against the schema, returning the failing rule and
|
||||
* reason if the object is invalid, or void if it's valid.
|
||||
*
|
||||
* @param {State} state
|
||||
* @return {State}
|
||||
*/
|
||||
|
||||
validate(state) {
|
||||
return !!state.document.findDescendant(node => this.validateNode(node))
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a `node` against the schema, returning the rule that was not met
|
||||
* if the node is invalid, or null if the rule was valid.
|
||||
* This method is private, because it should always be called on one of the
|
||||
* often-changing immutable objects instead, since it will be memoized for
|
||||
* much better performance.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @param {Mixed} object
|
||||
* @return {Object || Void}
|
||||
*/
|
||||
|
||||
validateNode(node) {
|
||||
__validate(object) {
|
||||
let reason
|
||||
let match = this.rules
|
||||
.filter(rule => !rule.match(node))
|
||||
.find((rule) => {
|
||||
reason = rule.validate(node)
|
||||
if (reason) return true
|
||||
|
||||
const match = this.rules.find((rule) => {
|
||||
if (!rule.match(object)) return
|
||||
debugger
|
||||
if (!rule.validate) return
|
||||
debugger
|
||||
reason = rule.validate(object)
|
||||
return reason
|
||||
})
|
||||
|
||||
if (!match) return
|
||||
if (!reason) return
|
||||
|
||||
return {
|
||||
rule: match,
|
||||
@@ -203,16 +188,6 @@ class Schema extends new Record(DEFAULTS) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Memoize read methods.
|
||||
*/
|
||||
|
||||
memoize(Schema.prototype, [
|
||||
'transform',
|
||||
'validate',
|
||||
'validateNode',
|
||||
])
|
||||
|
||||
/**
|
||||
* Normalize the `properties` of a schema.
|
||||
*
|
||||
@@ -267,9 +242,7 @@ function normalizeProperties(properties) {
|
||||
}
|
||||
|
||||
return {
|
||||
rules: rules
|
||||
.concat(RULES)
|
||||
.map(normalizeRule)
|
||||
rules: rules.map(normalizeRule)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,10 +290,7 @@ function normalizeValidate(validate) {
|
||||
switch (typeOf(validate)) {
|
||||
case 'function': return validate
|
||||
case 'boolean': return () => validate
|
||||
case 'object': return normalizeSpec(validate)
|
||||
default: {
|
||||
throw new Error(`Invalid \`validate\` spec: "${validate}".`)
|
||||
}
|
||||
case 'object': return normalizeSpec(validate, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,9 +304,6 @@ function normalizeValidate(validate) {
|
||||
function normalizeTransform(transform) {
|
||||
switch (typeOf(transform)) {
|
||||
case 'function': return transform
|
||||
default: {
|
||||
throw new Error(`Invalid \`transform\` spec: "${transform}".`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,10 +311,11 @@ function normalizeTransform(transform) {
|
||||
* Normalize a `spec` object.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {Boolean} giveReason
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function normalizeSpec(obj) {
|
||||
function normalizeSpec(obj, giveReason) {
|
||||
const spec = { ...obj }
|
||||
if (spec.exactlyOf) spec.exactlyOf = spec.exactlyOf.map(normalizeSpec)
|
||||
if (spec.anyOf) spec.anyOf = spec.anyOf.map(normalizeSpec)
|
||||
@@ -356,11 +324,18 @@ function normalizeSpec(obj) {
|
||||
return (node) => {
|
||||
for (const key in CHECKS) {
|
||||
const value = spec[key]
|
||||
debugger
|
||||
|
||||
if (value == null) continue
|
||||
|
||||
debugger
|
||||
const fail = CHECKS[key]
|
||||
const failure = fail(node, value)
|
||||
|
||||
if (!giveReason) {
|
||||
return !failure
|
||||
}
|
||||
|
||||
if (failure != undefined) {
|
||||
return {
|
||||
type: key,
|
||||
|
@@ -59,7 +59,7 @@ class State extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there undoable events?
|
||||
* Are there undoable events?
|
||||
*
|
||||
* @return {Boolean} hasUndos
|
||||
*/
|
||||
@@ -69,7 +69,7 @@ class State extends new Record(DEFAULTS) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Is there redoable events?
|
||||
* Are there redoable events?
|
||||
*
|
||||
* @return {Boolean} hasRedos
|
||||
*/
|
||||
@@ -358,6 +358,38 @@ class State extends new Record(DEFAULTS) {
|
||||
return this.document.getTextsAtRange(this.selection)
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a state against a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {State}
|
||||
*/
|
||||
|
||||
normalize(schema) {
|
||||
const state = this
|
||||
const { document, selection } = this
|
||||
let transform = this.transform()
|
||||
let failure
|
||||
|
||||
document.filterDescendantsDeep((node) => {
|
||||
if (failure = node.validate(schema)) {
|
||||
const { reason, rule } = failure
|
||||
debugger
|
||||
transform = rule.transform(transform, node, reason)
|
||||
}
|
||||
})
|
||||
|
||||
if (failure = document.validate(schema)) {
|
||||
const { reason, rule } = failure
|
||||
debugger
|
||||
transform = rule.transform(transform, document, reason)
|
||||
}
|
||||
|
||||
return transform.steps.size
|
||||
? transform.apply({ snapshot: false })
|
||||
: state
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new `Transform` with the current state as a starting point.
|
||||
*
|
||||
|
@@ -228,6 +228,17 @@ class Text extends new Record(DEFAULTS) {
|
||||
return this.merge({ characters })
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the node against a `schema`.
|
||||
*
|
||||
* @param {Schema} schema
|
||||
* @return {Object || Void}
|
||||
*/
|
||||
|
||||
validate(schema) {
|
||||
return schema.__validate(this)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,7 +249,8 @@ memoize(Text.prototype, [
|
||||
'getDecoratedCharacters',
|
||||
'getDecoratedRanges',
|
||||
'getRanges',
|
||||
'getRangesForCharacters'
|
||||
'getRangesForCharacters',
|
||||
'validate'
|
||||
])
|
||||
|
||||
/**
|
||||
|
@@ -73,66 +73,66 @@ function Plugin(options = {}) {
|
||||
)
|
||||
}
|
||||
|
||||
// /**
|
||||
// * The default schema.
|
||||
// *
|
||||
// * @type {Object}
|
||||
// */
|
||||
/**
|
||||
* The default schema.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
|
||||
// const DEFAULT_SCHEMA = {
|
||||
// rules: [
|
||||
// {
|
||||
// match: {
|
||||
// kind: 'document'
|
||||
// },
|
||||
// validate: {
|
||||
// anyOf: [
|
||||
// { kind: 'block' }
|
||||
// ]
|
||||
// },
|
||||
// transform: (transform, match, reason) => {
|
||||
// return reason.value.reduce((tr, node) => {
|
||||
// return tr.removeNodeByKey(node.key)
|
||||
// }, transform)
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// match: {
|
||||
// kind: 'block'
|
||||
// },
|
||||
// validate: {
|
||||
// anyOf: [
|
||||
// { kind: 'block' },
|
||||
// { kind: 'inline' },
|
||||
// { kind: 'text' },
|
||||
// ]
|
||||
// },
|
||||
// transform: (transform, match, reason) => {
|
||||
// return reason.value.reduce((tr, node) => {
|
||||
// return tr.removeNodeByKey(node.key)
|
||||
// }, transform)
|
||||
// },
|
||||
// component: DEFAULT_BLOCK
|
||||
// },
|
||||
// {
|
||||
// match: {
|
||||
// kind: 'inline'
|
||||
// },
|
||||
// validate: {
|
||||
// anyOf: [
|
||||
// { kind: 'inline' },
|
||||
// { kind: 'text' },
|
||||
// ]
|
||||
// },
|
||||
// transform: (transform, match, reason) => {
|
||||
// return reason.value.reduce((tr, node) => {
|
||||
// return tr.removeNodeByKey(node.key)
|
||||
// }, transform)
|
||||
// },
|
||||
// component: DEFAULT_INLINE
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
const DEFAULT_SCHEMA = {
|
||||
rules: [
|
||||
{
|
||||
match: {
|
||||
kind: 'document'
|
||||
},
|
||||
validate: {
|
||||
anyOf: [
|
||||
{ kind: 'block' }
|
||||
]
|
||||
},
|
||||
transform: (transform, match, reason) => {
|
||||
return reason.value.reduce((tr, node) => {
|
||||
return tr.removeNodeByKey(node.key)
|
||||
}, transform)
|
||||
}
|
||||
},
|
||||
{
|
||||
match: {
|
||||
kind: 'block'
|
||||
},
|
||||
validate: {
|
||||
anyOf: [
|
||||
{ kind: 'block' },
|
||||
{ kind: 'inline' },
|
||||
{ kind: 'text' },
|
||||
]
|
||||
},
|
||||
transform: (transform, match, reason) => {
|
||||
return reason.value.reduce((tr, node) => {
|
||||
return tr.removeNodeByKey(node.key)
|
||||
}, transform)
|
||||
},
|
||||
component: DEFAULT_BLOCK
|
||||
},
|
||||
{
|
||||
match: {
|
||||
kind: 'inline'
|
||||
},
|
||||
validate: {
|
||||
anyOf: [
|
||||
{ kind: 'inline' },
|
||||
{ kind: 'text' },
|
||||
]
|
||||
},
|
||||
transform: (transform, match, reason) => {
|
||||
return reason.value.reduce((tr, node) => {
|
||||
return tr.removeNodeByKey(node.key)
|
||||
}, transform)
|
||||
},
|
||||
component: DEFAULT_INLINE
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* On before change, enforce the editor's schema.
|
||||
@@ -144,9 +144,8 @@ function Plugin(options = {}) {
|
||||
|
||||
function onBeforeChange(state, editor) {
|
||||
if (state.isNative) return state
|
||||
return editor
|
||||
.getSchema()
|
||||
.transform(state)
|
||||
const schema = editor.getSchema()
|
||||
return state.normalize(schema)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -700,7 +699,8 @@ function Plugin(options = {}) {
|
||||
onKeyDown,
|
||||
onPaste,
|
||||
onSelect,
|
||||
renderNode
|
||||
renderNode,
|
||||
schema: DEFAULT_SCHEMA
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -84,8 +84,8 @@
|
||||
"open": "open http://localhost:8080/dev.html",
|
||||
"prepublish": "npm run dist",
|
||||
"start": "http-server ./examples",
|
||||
"test": "npm-run-all lint dist:npm test:server",
|
||||
"test:server": "mocha --compilers js:babel-core/register --reporter spec ./test/server.js",
|
||||
"test": "npm-run-all lint dist:npm tests",
|
||||
"tests": "mocha --compilers js:babel-core/register --reporter spec ./test/server.js",
|
||||
"watch": "npm-run-all --parallel --print-label watch:dist watch:examples start",
|
||||
"watch:dist": "babel --watch --out-dir ./dist ./lib",
|
||||
"watch:examples": "watchify --debug --transform babelify ./examples/index.js -o ./examples/build.dev.js"
|
||||
|
@@ -1,2 +0,0 @@
|
||||
|
||||
export default {}
|
@@ -1,8 +0,0 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: default
|
||||
isVoid: true
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
@@ -1,5 +0,0 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: default
|
||||
isVoid: true
|
@@ -1,2 +0,0 @@
|
||||
|
||||
export default {}
|
@@ -1,11 +0,0 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: default
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: default
|
||||
isVoid: true
|
||||
nodes:
|
||||
- kind: text
|
||||
text: one
|
@@ -1,8 +0,0 @@
|
||||
|
||||
nodes:
|
||||
- kind: block
|
||||
type: default
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: default
|
||||
isVoid: true
|
@@ -1,8 +1,9 @@
|
||||
|
||||
import React from 'react'
|
||||
import fs from 'fs'
|
||||
import strip from '../helpers/strip-dynamic'
|
||||
import readMetadata from 'read-metadata'
|
||||
import { Raw, Schema } from '../..'
|
||||
import { Raw, Editor, Schema } from '../..'
|
||||
import { strictEqual } from '../helpers/assert-json'
|
||||
import { resolve } from 'path'
|
||||
|
||||
@@ -22,8 +23,8 @@ describe('schema', () => {
|
||||
const expected = readMetadata.sync(resolve(dir, 'output.yaml'))
|
||||
const schema = Schema.create(require(dir))
|
||||
|
||||
let state = Raw.deserialize(input, { terse: true })
|
||||
state = schema.transform(state)
|
||||
const state = Raw.deserialize(input, { terse: true })
|
||||
const editor = <Editor state={state} schema={schema} />
|
||||
const output = Raw.serialize(state, { terse: true })
|
||||
strictEqual(strip(output), strip(expected))
|
||||
})
|
||||
|
Reference in New Issue
Block a user