mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-20 22:21:20 +02:00
got first stab at schema working with tests
This commit is contained in:
@@ -11,62 +11,54 @@ const RULES = [
|
|||||||
kind: 'document'
|
kind: 'document'
|
||||||
},
|
},
|
||||||
validate: {
|
validate: {
|
||||||
nodes: {
|
|
||||||
anyOf: [
|
anyOf: [
|
||||||
{ kind: 'block' }
|
{ kind: 'block' }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
transform: (transform, match, reason) => {
|
||||||
|
return reason.value.reduce((tr, node) => {
|
||||||
|
return tr.removeNodeByKey(node.key)
|
||||||
|
}, transform)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transform: (transform, node) => {
|
{
|
||||||
return node.nodes
|
match: {
|
||||||
.filter(child => child.kind != 'block')
|
kind: 'block'
|
||||||
.reduce((tr, child) => tr.removeNodeByKey(child.key), transform)
|
},
|
||||||
|
validate: {
|
||||||
|
anyOf: [
|
||||||
|
{ kind: 'block' },
|
||||||
|
{ kind: 'inline' },
|
||||||
|
{ kind: 'text' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
transform: (transform, match, reason) => {
|
||||||
|
return reason.value.reduce((tr, node) => {
|
||||||
|
return tr.removeNodeByKey(node.key)
|
||||||
|
}, transform)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// match: { kind: 'block' },
|
|
||||||
// nodes: {
|
|
||||||
// anyOf: [
|
|
||||||
// { kind: 'block' },
|
|
||||||
// { kind: 'inline' },
|
|
||||||
// { kind: 'text' },
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// transform: (transform, node) => {
|
|
||||||
// return node
|
|
||||||
// .filterChildren(child => {
|
|
||||||
// return (
|
|
||||||
// child.kind != 'block' ||
|
|
||||||
// child.kind != 'inline' ||
|
|
||||||
// child.kind != 'text'
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
// .reduce((transform, child) => {
|
|
||||||
// return transform.removeNodeByKey(child.key)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// match: { kind: 'inline' },
|
|
||||||
// nodes: {
|
|
||||||
// anyOf: [
|
|
||||||
// { kind: 'inline' },
|
|
||||||
// { kind: 'text' }
|
|
||||||
// ]
|
|
||||||
// },
|
|
||||||
// transform: (transform, node) => {
|
|
||||||
// return node
|
|
||||||
// .filterChildren(child => {
|
|
||||||
// return child.kind != 'inline' || child.kind != 'text'
|
|
||||||
// })
|
|
||||||
// .reduce((transform, child) => {
|
|
||||||
// return transform.removeNodeByKey(child.key)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
// {
|
||||||
// match: { isVoid: true },
|
// match: { isVoid: true },
|
||||||
// text: ' ',
|
// validate: {
|
||||||
|
// text: ' '
|
||||||
|
// },
|
||||||
// transform: (transform, node) => {
|
// transform: (transform, node) => {
|
||||||
// const { state } = transform
|
// const { state } = transform
|
||||||
// const range = state.selection.moveToRangeOf(node)
|
// const range = state.selection.moveToRangeOf(node)
|
||||||
|
@@ -16,6 +16,7 @@ import Data from './models/data'
|
|||||||
import Document from './models/document'
|
import Document from './models/document'
|
||||||
import Inline from './models/inline'
|
import Inline from './models/inline'
|
||||||
import Mark from './models/mark'
|
import Mark from './models/mark'
|
||||||
|
import Schema from './models/schema'
|
||||||
import Selection from './models/selection'
|
import Selection from './models/selection'
|
||||||
import State from './models/state'
|
import State from './models/state'
|
||||||
import Text from './models/text'
|
import Text from './models/text'
|
||||||
@@ -50,6 +51,7 @@ export {
|
|||||||
Placeholder,
|
Placeholder,
|
||||||
Plain,
|
Plain,
|
||||||
Raw,
|
Raw,
|
||||||
|
Schema,
|
||||||
Selection,
|
Selection,
|
||||||
State,
|
State,
|
||||||
Text,
|
Text,
|
||||||
@@ -68,6 +70,7 @@ export default {
|
|||||||
Placeholder,
|
Placeholder,
|
||||||
Plain,
|
Plain,
|
||||||
Raw,
|
Raw,
|
||||||
|
Schema,
|
||||||
Selection,
|
Selection,
|
||||||
State,
|
State,
|
||||||
Text,
|
Text,
|
||||||
|
@@ -6,6 +6,97 @@ import typeOf from 'type-of'
|
|||||||
import memoize from '../utils/memoize'
|
import memoize from '../utils/memoize'
|
||||||
import { Record } from 'immutable'
|
import { Record } from 'immutable'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the schema can perform, ordered by performance.
|
||||||
|
*
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const CHECKS = {
|
||||||
|
|
||||||
|
kind(object, value) {
|
||||||
|
if (object.kind != value) return object.kind
|
||||||
|
},
|
||||||
|
|
||||||
|
type(object, value) {
|
||||||
|
if (object.type != value) return object.type
|
||||||
|
},
|
||||||
|
|
||||||
|
isVoid(object, value) {
|
||||||
|
if (object.isVoid != value) return object.isVoid
|
||||||
|
},
|
||||||
|
|
||||||
|
minChildren(object, value) {
|
||||||
|
if (object.nodes.size < value) return object.nodes.size
|
||||||
|
},
|
||||||
|
|
||||||
|
maxChildren(object, value) {
|
||||||
|
if (object.nodes.size > value) return object.nodes.size
|
||||||
|
},
|
||||||
|
|
||||||
|
kinds(object, value) {
|
||||||
|
if (!includes(value, object.kind)) return object.kind
|
||||||
|
},
|
||||||
|
|
||||||
|
types(object, value) {
|
||||||
|
if (!includes(value, object.type)) return object.type
|
||||||
|
},
|
||||||
|
|
||||||
|
minLength(object, value) {
|
||||||
|
const { length } = object
|
||||||
|
if (length < value) return length
|
||||||
|
},
|
||||||
|
|
||||||
|
maxLength(object, value) {
|
||||||
|
const { length } = object
|
||||||
|
if (length > value) return length
|
||||||
|
},
|
||||||
|
|
||||||
|
text(object, value) {
|
||||||
|
const { text } = object
|
||||||
|
switch (typeOf(value)) {
|
||||||
|
case 'function': if (value(text)) return text
|
||||||
|
case 'regexp': if (!text.match(value)) return text
|
||||||
|
default: if (text != value) return text
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
anyOf(object, value) {
|
||||||
|
const { nodes } = object
|
||||||
|
if (!nodes) return
|
||||||
|
const invalids = nodes.filterNot((child) => {
|
||||||
|
return value.some(fail => !fail(child))
|
||||||
|
})
|
||||||
|
|
||||||
|
if (invalids.size) return invalids
|
||||||
|
},
|
||||||
|
|
||||||
|
noneOf(object, value) {
|
||||||
|
const { nodes } = object
|
||||||
|
if (!nodes) return
|
||||||
|
const invalids = nodes.filterNot((child) => {
|
||||||
|
return value.every(fail => fail(child))
|
||||||
|
})
|
||||||
|
|
||||||
|
if (invalids.size) return invalids
|
||||||
|
},
|
||||||
|
|
||||||
|
exactlyOf(object, value) {
|
||||||
|
const { nodes } = object
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (invalids.size) return invalids
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default properties.
|
* Default properties.
|
||||||
*
|
*
|
||||||
@@ -33,15 +124,7 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
|
|
||||||
static create(properties = {}) {
|
static create(properties = {}) {
|
||||||
if (properties instanceof Schema) return properties
|
if (properties instanceof Schema) return properties
|
||||||
|
return new Schema(normalizeProperties(properties))
|
||||||
let rules = [
|
|
||||||
...(properties.rules || []),
|
|
||||||
...RULES,
|
|
||||||
]
|
|
||||||
|
|
||||||
return new Schema({
|
|
||||||
rules: rules.map(normalizeRule)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,21 +138,29 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize a `state` against the schema.
|
* Transform a `state` to abide by the schema.
|
||||||
*
|
*
|
||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @return {State}
|
* @return {State}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
normalize(state) {
|
transform(state) {
|
||||||
const { document } = state
|
const { document } = state
|
||||||
let transform = state.transform()
|
let transform = state.transform()
|
||||||
|
let failure
|
||||||
|
|
||||||
document.filterDescendants((node) => {
|
document.filterDescendantsDeep((node) => {
|
||||||
const rule = this.validateNode(node)
|
if (failure = this.validateNode(node)) {
|
||||||
if (rule) transform = rule.transform(transform, node, state)
|
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 })
|
const next = transform.apply({ snapshot: false })
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
@@ -94,9 +185,20 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
validateNode(node) {
|
validateNode(node) {
|
||||||
return this.rules
|
let reason
|
||||||
.filter(rule => rule.match(node))
|
let match = this.rules
|
||||||
.find(rule => !rule.validate(node))
|
.filter(rule => !rule.match(node))
|
||||||
|
.find((rule) => {
|
||||||
|
reason = rule.validate(node)
|
||||||
|
if (reason) return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!match) return
|
||||||
|
|
||||||
|
return {
|
||||||
|
rule: match,
|
||||||
|
reason
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -106,7 +208,7 @@ class Schema extends new Record(DEFAULTS) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
memoize(Schema.prototype, [
|
memoize(Schema.prototype, [
|
||||||
'normalize',
|
'transform',
|
||||||
'validate',
|
'validate',
|
||||||
'validateNode',
|
'validateNode',
|
||||||
])
|
])
|
||||||
@@ -119,17 +221,13 @@ memoize(Schema.prototype, [
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function normalizeProperties(properties) {
|
function normalizeProperties(properties) {
|
||||||
let rules = []
|
let { rules, nodes, marks } = properties
|
||||||
|
if (!rules) rules = []
|
||||||
|
|
||||||
// If there's a `rules` property, it is not the shorthand.
|
// If there's a `nodes` property, it's the node rule shorthand dictionary.
|
||||||
if (properties.rules) {
|
if (nodes) {
|
||||||
rules = properties.rules
|
for (const key in nodes) {
|
||||||
}
|
const value = nodes[key]
|
||||||
|
|
||||||
// Otherwise it's the shorthand syntax, so expand each of the properties.
|
|
||||||
else {
|
|
||||||
for (const key in properties) {
|
|
||||||
const value = properties[key]
|
|
||||||
let rule
|
let rule
|
||||||
|
|
||||||
if (isReactComponent(value)) {
|
if (isReactComponent(value)) {
|
||||||
@@ -137,6 +235,7 @@ function normalizeProperties(properties) {
|
|||||||
rule.component = value
|
rule.component = value
|
||||||
} else {
|
} else {
|
||||||
rule = {
|
rule = {
|
||||||
|
kinds: ['block', 'inline'],
|
||||||
type: key,
|
type: key,
|
||||||
...value
|
...value
|
||||||
}
|
}
|
||||||
@@ -146,6 +245,27 @@ function normalizeProperties(properties) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there's a `marks` property, it's the mark rule shorthand dictionary.
|
||||||
|
if (marks) {
|
||||||
|
for (const key in marks) {
|
||||||
|
const value = marks[key]
|
||||||
|
let rule
|
||||||
|
|
||||||
|
if (rule.match) {
|
||||||
|
rule = {
|
||||||
|
kind: 'mark',
|
||||||
|
type: key,
|
||||||
|
...value
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rule.match = { type: key }
|
||||||
|
rule.component = value
|
||||||
|
}
|
||||||
|
|
||||||
|
rules.push(rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rules: rules
|
rules: rules
|
||||||
.concat(RULES)
|
.concat(RULES)
|
||||||
@@ -178,6 +298,7 @@ function normalizeRule(rule) {
|
|||||||
function normalizeMatch(match) {
|
function normalizeMatch(match) {
|
||||||
switch (typeOf(match)) {
|
switch (typeOf(match)) {
|
||||||
case 'function': return match
|
case 'function': return match
|
||||||
|
case 'boolean': return () => match
|
||||||
case 'object': return normalizeSpec(match)
|
case 'object': return normalizeSpec(match)
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`Invalid \`match\` spec: "${match}".`)
|
throw new Error(`Invalid \`match\` spec: "${match}".`)
|
||||||
@@ -195,6 +316,7 @@ function normalizeMatch(match) {
|
|||||||
function normalizeValidate(validate) {
|
function normalizeValidate(validate) {
|
||||||
switch (typeOf(validate)) {
|
switch (typeOf(validate)) {
|
||||||
case 'function': return validate
|
case 'function': return validate
|
||||||
|
case 'boolean': return () => validate
|
||||||
case 'object': return normalizeSpec(validate)
|
case 'object': return normalizeSpec(validate)
|
||||||
default: {
|
default: {
|
||||||
throw new Error(`Invalid \`validate\` spec: "${validate}".`)
|
throw new Error(`Invalid \`validate\` spec: "${validate}".`)
|
||||||
@@ -227,79 +349,25 @@ function normalizeTransform(transform) {
|
|||||||
|
|
||||||
function normalizeSpec(obj) {
|
function normalizeSpec(obj) {
|
||||||
const spec = { ...obj }
|
const spec = { ...obj }
|
||||||
const { nodes } = spec
|
if (spec.exactlyOf) spec.exactlyOf = spec.exactlyOf.map(normalizeSpec)
|
||||||
|
if (spec.anyOf) spec.anyOf = spec.anyOf.map(normalizeSpec)
|
||||||
|
if (spec.noneOf) spec.noneOf = spec.noneOf.map(normalizeSpec)
|
||||||
|
|
||||||
// Normalize recursively for the node specs.
|
|
||||||
if (nodes) {
|
|
||||||
if (nodes.exactlyOf) spec.nodes.exactlyOf = nodes.exactlyOf.map(normalizeSpec)
|
|
||||||
if (nodes.anyOf) spec.nodes.anyOf = nodes.anyOf.map(normalizeSpec)
|
|
||||||
if (nodes.noneOf) spec.nodes.noneOf = nodes.noneOf.map(normalizeSpec)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a checking function.
|
|
||||||
return (node) => {
|
return (node) => {
|
||||||
// If marked as invalid explicitly, return early.
|
for (const key in CHECKS) {
|
||||||
if (spec.invalid === true) return false
|
const value = spec[key]
|
||||||
|
if (value == null) continue
|
||||||
|
|
||||||
// Run the simple equality checks first.
|
const fail = CHECKS[key]
|
||||||
if (
|
const failure = fail(node, value)
|
||||||
(spec.kind != null && spec.kind != node.kind) ||
|
|
||||||
(spec.type != null && spec.type != node.type) ||
|
if (failure != undefined) {
|
||||||
(spec.isVoid != null && spec.isVoid != node.type) ||
|
return {
|
||||||
(spec.kinds != null && !includes(spec.kinds, node.kind)) ||
|
type: key,
|
||||||
(spec.types != null && !includes(spec.types, node.type))
|
value: failure
|
||||||
) {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the node has nodes.
|
|
||||||
if (spec.nodes && !node.nodes) {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the node recursive checks next, start with `exactlyOf`, which likely
|
|
||||||
// has the greatest chance of not matching.
|
|
||||||
if (spec.nodes && spec.nodes.exactlyOf) {
|
|
||||||
const specs = spec.nodes.exactlyOf
|
|
||||||
const matches = node.nodes.reduce((valid, child, i) => {
|
|
||||||
if (!valid) return false
|
|
||||||
const checker = specs[i]
|
|
||||||
if (!checker) return false
|
|
||||||
return checker(child)
|
|
||||||
}, true)
|
|
||||||
|
|
||||||
if (!matches) return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the `anyOf` next check.
|
|
||||||
if (spec.nodes && spec.nodes.anyOf) {
|
|
||||||
const specs = spec.nodes.anyOf
|
|
||||||
const matches = node.nodes.reduce((valid, child) => {
|
|
||||||
if (!valid) return false
|
|
||||||
return specs.reduce((pass, checker) => {
|
|
||||||
if (!pass) return false
|
|
||||||
return checker(child)
|
|
||||||
}, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!matches) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the `noneOf` next check.
|
|
||||||
if (spec.nodes && spec.nodes.noneOf) {
|
|
||||||
const specs = spec.nodes.noneOf
|
|
||||||
const matches = node.nodes.reduce((valid, child) => {
|
|
||||||
if (!valid) return false
|
|
||||||
return specs.reduce((pass, checker) => {
|
|
||||||
if (!pass) return false
|
|
||||||
return !!checker(child)
|
|
||||||
}, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!matches) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -73,6 +73,67 @@ function Plugin(options = {}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * 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
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On before change, enforce the editor's schema.
|
* On before change, enforce the editor's schema.
|
||||||
*
|
*
|
||||||
@@ -85,7 +146,7 @@ function Plugin(options = {}) {
|
|||||||
if (state.isNative) return state
|
if (state.isNative) return state
|
||||||
return editor
|
return editor
|
||||||
.getSchema()
|
.getSchema()
|
||||||
.normalize(state)
|
.transform(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
2
test/schema/fixtures/default-no-block-void-text/index.js
Normal file
2
test/schema/fixtures/default-no-block-void-text/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default {}
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
isVoid: true
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
isVoid: true
|
2
test/schema/fixtures/default-no-document-inline/index.js
Normal file
2
test/schema/fixtures/default-no-document-inline/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default {}
|
@@ -4,11 +4,9 @@ nodes:
|
|||||||
type: default
|
type: default
|
||||||
nodes:
|
nodes:
|
||||||
- kind: text
|
- kind: text
|
||||||
ranges:
|
text: one
|
||||||
- text: one
|
|
||||||
- kind: block
|
- kind: block
|
||||||
type: default
|
type: default
|
||||||
nodes:
|
nodes:
|
||||||
- kind: text
|
- kind: text
|
||||||
ranges:
|
text: two
|
||||||
- text: two
|
|
@@ -4,5 +4,4 @@ nodes:
|
|||||||
type: default
|
type: default
|
||||||
nodes:
|
nodes:
|
||||||
- kind: text
|
- kind: text
|
||||||
ranges:
|
text: two
|
||||||
- text: two
|
|
2
test/schema/fixtures/default-no-document-text/index.js
Normal file
2
test/schema/fixtures/default-no-document-text/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default {}
|
9
test/schema/fixtures/default-no-document-text/input.yaml
Normal file
9
test/schema/fixtures/default-no-document-text/input.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: two
|
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: two
|
2
test/schema/fixtures/default-no-inline-block/index.js
Normal file
2
test/schema/fixtures/default-no-inline-block/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default {}
|
15
test/schema/fixtures/default-no-inline-block/input.yaml
Normal file
15
test/schema/fixtures/default-no-inline-block/input.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: two
|
10
test/schema/fixtures/default-no-inline-block/output.yaml
Normal file
10
test/schema/fixtures/default-no-inline-block/output.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export default {}
|
11
test/schema/fixtures/default-no-inline-void-text/input.yaml
Normal file
11
test/schema/fixtures/default-no-inline-void-text/input.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: default
|
||||||
|
isVoid: true
|
||||||
|
nodes:
|
||||||
|
- kind: text
|
||||||
|
text: one
|
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
nodes:
|
||||||
|
- kind: block
|
||||||
|
type: default
|
||||||
|
nodes:
|
||||||
|
- kind: inline
|
||||||
|
type: default
|
||||||
|
isVoid: true
|
@@ -2,7 +2,7 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import strip from '../helpers/strip-dynamic'
|
import strip from '../helpers/strip-dynamic'
|
||||||
import readMetadata from 'read-metadata'
|
import readMetadata from 'read-metadata'
|
||||||
import { Raw } from '../..'
|
import { Raw, Schema } from '../..'
|
||||||
import { strictEqual } from '../helpers/assert-json'
|
import { strictEqual } from '../helpers/assert-json'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
@@ -20,10 +20,10 @@ describe('schema', () => {
|
|||||||
const dir = resolve(__dirname, './fixtures', test)
|
const dir = resolve(__dirname, './fixtures', test)
|
||||||
const input = readMetadata.sync(resolve(dir, 'input.yaml'))
|
const input = readMetadata.sync(resolve(dir, 'input.yaml'))
|
||||||
const expected = readMetadata.sync(resolve(dir, 'output.yaml'))
|
const expected = readMetadata.sync(resolve(dir, 'output.yaml'))
|
||||||
const schema = require(dir)
|
const schema = Schema.create(require(dir))
|
||||||
|
|
||||||
let state = Raw.deserialize(input, { terse: true })
|
let state = Raw.deserialize(input, { terse: true })
|
||||||
state = schema.normalize(state)
|
state = schema.transform(state)
|
||||||
const output = Raw.serialize(state, { terse: true })
|
const output = Raw.serialize(state, { terse: true })
|
||||||
strictEqual(strip(output), strip(expected))
|
strictEqual(strip(output), strip(expected))
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user