2018-09-03 02:47:52 +03:00
|
|
|
/**********************************************************************
|
|
|
|
|
*
|
|
|
|
|
* This module describes the diff format and provides basic verification.
|
|
|
|
|
*
|
|
|
|
|
* XXX EXPERIMENTAL...
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
|
|
|
|
(function(require){ var module={} // make module AMD/node compatible...
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
|
|
|
|
|
var diff = require('./diff')
|
|
|
|
|
var {
|
|
|
|
|
ANY,
|
2018-09-06 00:21:52 +03:00
|
|
|
NULL, BOOL, B, NUMBER, N, STRING, S, ARRAY, L, FUNCTION, F,
|
2019-12-27 06:11:54 +03:00
|
|
|
OR, XOR, AND, NOT,
|
2018-09-03 02:47:52 +03:00
|
|
|
AT, OF, IN,
|
2018-09-05 00:09:45 +03:00
|
|
|
VAR, LIKE, TEST,
|
2018-09-26 03:35:10 +03:00
|
|
|
// non-pattern values...
|
2018-09-03 02:47:52 +03:00
|
|
|
EMPTY, NONE,
|
|
|
|
|
} = diff
|
|
|
|
|
|
|
|
|
|
|
2018-09-26 02:08:46 +03:00
|
|
|
/*********************************************************************/
|
|
|
|
|
// helpers...
|
|
|
|
|
|
2018-09-26 03:35:10 +03:00
|
|
|
// OPT(key, value)
|
|
|
|
|
// -> true if key matches value or does not exist...
|
2018-09-26 02:08:46 +03:00
|
|
|
var OPT = function(key, value){
|
|
|
|
|
return OR(
|
|
|
|
|
NOT(AT(key)),
|
|
|
|
|
AT(key, value)) }
|
|
|
|
|
|
|
|
|
|
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
//
|
2018-09-26 03:35:10 +03:00
|
|
|
// NOTE: this file is organized bottoms-up, with the most general
|
|
|
|
|
// (top-level) patterns at the bottom.
|
|
|
|
|
//
|
2018-09-03 02:47:52 +03:00
|
|
|
// XXX need better mismatch checking -- ideally stating the exact spot
|
|
|
|
|
// where we did not match and the path of fails it created...
|
2018-09-05 04:39:42 +03:00
|
|
|
//
|
2018-09-03 02:47:52 +03:00
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Flat diff...
|
2018-09-25 20:52:00 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
// Basic value...
|
2018-09-03 02:47:52 +03:00
|
|
|
var VALUE =
|
|
|
|
|
module.VALUE = OR(
|
2018-09-06 00:50:16 +03:00
|
|
|
OR(LIKE('EMPTY'), EMPTY),
|
|
|
|
|
OR(LIKE('NONE'), NONE),
|
2018-09-03 02:47:52 +03:00
|
|
|
ANY)
|
|
|
|
|
|
|
|
|
|
|
2018-09-25 20:52:00 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
// Basic change...
|
2018-09-03 02:47:52 +03:00
|
|
|
var CHANGE =
|
|
|
|
|
module.CHANGE = AND(
|
2018-09-06 00:21:52 +03:00
|
|
|
AT('path', L),
|
2018-09-26 02:08:46 +03:00
|
|
|
OPT('type', S),
|
|
|
|
|
// NOTE: this matches if one or both of A and B exist and if they
|
|
|
|
|
// do the match VALUE...
|
|
|
|
|
AT(OR('A', 'B'), VALUE))
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
|
2018-09-25 20:52:00 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
// flat diff root (Array)...
|
2018-09-03 02:47:52 +03:00
|
|
|
var DIFF_FLAT =
|
|
|
|
|
module.DIFF_FLAT = OR(
|
2018-09-06 00:21:52 +03:00
|
|
|
L(CHANGE),
|
2018-09-03 02:47:52 +03:00
|
|
|
null)
|
|
|
|
|
|
|
|
|
|
|
2018-09-25 20:52:00 +03:00
|
|
|
|
2018-09-03 02:47:52 +03:00
|
|
|
//---------------------------------------------------------------------
|
|
|
|
|
// Tree diff...
|
2018-09-25 20:52:00 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
// Basic change...
|
2018-09-03 02:47:52 +03:00
|
|
|
var BASIC_CHANGE =
|
|
|
|
|
module.BASIC_CHANGE = AND(
|
|
|
|
|
AT('type', 'Basic'),
|
2018-09-26 02:08:46 +03:00
|
|
|
AT(OR('A', 'B'), VALUE))
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2018-09-25 20:52:00 +03:00
|
|
|
// Object change...
|
2018-09-03 02:47:52 +03:00
|
|
|
var OBJECT_ITEM =
|
|
|
|
|
module.OBJECT_ITEM = OR(
|
2018-09-06 00:21:52 +03:00
|
|
|
[S, DIFF_TREE],
|
|
|
|
|
[S, S, DIFF_TREE])
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
var OBJECT_CHANGE =
|
|
|
|
|
module.OBJECT_CHANGE = AND(
|
|
|
|
|
AT('type', 'Object'),
|
2018-09-06 00:21:52 +03:00
|
|
|
AT('items', L(OBJECT_ITEM)),
|
2018-09-03 02:47:52 +03:00
|
|
|
// XXX
|
2018-09-27 01:22:13 +03:00
|
|
|
OPT('item_order'))
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2018-09-25 20:52:00 +03:00
|
|
|
// Array change...
|
2018-09-03 02:47:52 +03:00
|
|
|
var ARRAY_ITEM =
|
|
|
|
|
module.ARRAY_ITEM = OR(
|
|
|
|
|
[ANY, ANY, DIFF_TREE],
|
2018-09-06 00:21:52 +03:00
|
|
|
[[ANY, N], [ANY, N], DIFF_TREE])
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
var ARRAY_ITEMS =
|
|
|
|
|
module.ARRAY_ITEMS = AND(
|
2018-09-06 00:50:16 +03:00
|
|
|
AT('items',
|
|
|
|
|
L(OR(
|
2018-09-03 02:47:52 +03:00
|
|
|
ARRAY_ITEM,
|
|
|
|
|
OBJECT_ITEM))),
|
2018-09-27 01:22:13 +03:00
|
|
|
OPT('length', [N, N]),
|
2018-09-03 02:47:52 +03:00
|
|
|
// XXX
|
2018-09-27 01:22:13 +03:00
|
|
|
OPT('item_order'))
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
var ARRAY_CHANGE =
|
|
|
|
|
module.ARRAY_CHANGE = AND(
|
2018-09-06 00:50:16 +03:00
|
|
|
AT('type', 'Array'),
|
|
|
|
|
ARRAY_ITEMS)
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2018-09-25 20:52:00 +03:00
|
|
|
// Text change...
|
2018-09-03 02:47:52 +03:00
|
|
|
var TEXT_CHANGE =
|
|
|
|
|
module.TEXT_CHANGE = AND(
|
2018-09-06 00:50:16 +03:00
|
|
|
AT('type', 'Text'),
|
|
|
|
|
ARRAY_ITEMS)
|
2018-09-03 02:47:52 +03:00
|
|
|
|
2018-09-06 00:50:16 +03:00
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2018-09-25 20:52:00 +03:00
|
|
|
// Tree - the tree node...
|
2018-09-06 00:50:16 +03:00
|
|
|
// XXX need to check if we stop on a recursive pattern...
|
2018-09-03 02:47:52 +03:00
|
|
|
// XXX TEST!!!
|
|
|
|
|
var DIFF_TREE =
|
|
|
|
|
module.DIFF_TREE = OR(
|
|
|
|
|
BASIC_CHANGE,
|
|
|
|
|
OBJECT_CHANGE,
|
|
|
|
|
ARRAY_CHANGE,
|
|
|
|
|
TEXT_CHANGE,
|
|
|
|
|
null)
|
|
|
|
|
|
|
|
|
|
|
2018-09-25 20:52:00 +03:00
|
|
|
|
2018-09-03 02:47:52 +03:00
|
|
|
//---------------------------------------------------------------------
|
2018-09-25 20:52:00 +03:00
|
|
|
// Diff -- the root data structure...
|
2018-09-26 02:08:46 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
// Options...
|
|
|
|
|
var OPTIONS =
|
|
|
|
|
module.OPTIONS = AND(
|
|
|
|
|
OPT('tree_diff', B),
|
|
|
|
|
OPT('keep_none', B),
|
|
|
|
|
OPT('min_text_length', N),
|
|
|
|
|
OPT('no_attributes', B),
|
|
|
|
|
OPT('NONE', ANY),
|
|
|
|
|
OPT('EMPTY', ANY),
|
|
|
|
|
OPT('no_length', B),
|
|
|
|
|
OPT('cmp', F) )
|
2018-09-03 02:47:52 +03:00
|
|
|
|
2018-09-26 03:35:10 +03:00
|
|
|
|
2018-09-26 02:08:46 +03:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2018-09-03 02:47:52 +03:00
|
|
|
var DIFF_OBJECT =
|
|
|
|
|
module.DIFF_OBJECT = AND(
|
|
|
|
|
// format metadata...
|
|
|
|
|
AT('format', diff.FORMAT_NAME),
|
2018-09-26 03:35:10 +03:00
|
|
|
AT('version', AND(
|
|
|
|
|
// version format...
|
|
|
|
|
S(/\d+\.\d+\.\d+[ab]?/),
|
|
|
|
|
// explicit version value...
|
|
|
|
|
diff.FORMAT_VERSION)),
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
// instance metadata...
|
2018-09-26 02:08:46 +03:00
|
|
|
AT('options', OPTIONS),
|
2018-09-06 00:50:16 +03:00
|
|
|
AT('placeholders',
|
|
|
|
|
AND(
|
|
|
|
|
AT('NONE',
|
|
|
|
|
VAR('NONE', ANY)),
|
|
|
|
|
AT('EMPTY',
|
|
|
|
|
VAR('EMPTY', ANY)))),
|
2018-09-06 00:21:52 +03:00
|
|
|
AT('timestamp', N),
|
2018-09-03 02:47:52 +03:00
|
|
|
|
|
|
|
|
// diff...
|
|
|
|
|
OR(
|
|
|
|
|
AND(
|
|
|
|
|
AT('structure', 'flat'),
|
|
|
|
|
AT('diff', DIFF_FLAT)),
|
|
|
|
|
AND(
|
|
|
|
|
AT('structure', 'tree'),
|
|
|
|
|
AT('diff', DIFF_TREE))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
|
* vim:set ts=4 sw=4 : */ return module })
|