-
Notifications
You must be signed in to change notification settings - Fork 470
Expand file tree
/
Copy patherror.js
More file actions
133 lines (110 loc) · 3.52 KB
/
Copy patherror.js
File metadata and controls
133 lines (110 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'use strict'
const constants = require('../constants')
const formatUtils = require('../formatUtils')
const isEnumerable = require('../isEnumerable')
const lineBuilder = require('../lineBuilder')
const NOOP_RECURSOR = require('../recursorUtils').NOOP_RECURSOR
const object = require('./object')
const UNEQUAL = constants.UNEQUAL
function describe (props) {
const error = props.value
return new DescribedErrorValue(Object.assign({
nameIsEnumerable: isEnumerable(error, 'name'),
name: error.name,
messageIsEnumerable: isEnumerable(error, 'message'),
message: error.message,
}, props))
}
exports.describe = describe
function deserialize (state, recursor) {
return new DeserializedErrorValue(state, recursor)
}
exports.deserialize = deserialize
const tag = Symbol('ErrorValue')
exports.tag = tag
class ErrorValue extends object.ObjectValue {
constructor (props) {
super(props)
this.name = props.name
}
compare (expected) {
return this.tag === expected.tag && this.name === expected.name
? super.compare(expected)
: UNEQUAL
}
formatShallow (theme, indent) {
const name = this.name || this.ctor
let string = name
? formatUtils.wrap(theme.error.name, name)
: formatUtils.wrap(theme.object.stringTag, this.stringTag)
if (this.ctor && this.ctor !== name) {
string += ' ' + formatUtils.wrap(theme.error.ctor, this.ctor)
}
if (this.stringTag && this.stringTag !== this.ctor && this.name && !this.name.includes(this.stringTag)) {
string += ' ' + formatUtils.wrap(theme.object.secondaryStringTag, this.stringTag)
}
string += ' ' + theme.object.openBracket
return super.formatShallow(theme, indent).customize({
finalize (innerLines) {
return innerLines.isEmpty
? lineBuilder.single(string + theme.object.closeBracket)
: lineBuilder.first(string)
.concat(innerLines.withFirstPrefixed(indent.increase()).stripFlags())
.append(lineBuilder.last(indent + theme.object.closeBracket))
},
maxDepth () {
return lineBuilder.single(string + ' ' + theme.maxDepth + ' ' + theme.object.closeBracket)
},
})
}
serialize () {
return [this.name, super.serialize()]
}
}
Object.defineProperty(ErrorValue.prototype, 'tag', { value: tag })
class DescribedErrorValue extends object.DescribedMixin(ErrorValue) {
constructor (props) {
super(props)
this.nameIsEnumerable = props.nameIsEnumerable
this.messageIsEnumerable = props.messageIsEnumerable
this.message = props.message
}
createPropertyRecursor () {
const recursor = super.createPropertyRecursor()
let skipName = this.nameIsEnumerable
let emitMessage = !this.messageIsEnumerable
let size = recursor.size
if (skipName && size > 0) {
size -= 1
}
if (emitMessage) {
size += 1
}
if (size === 0) return NOOP_RECURSOR
let done = false
const next = () => {
if (done) return null
const property = recursor.next()
if (property) {
if (skipName && property.key.value === 'name') {
skipName = false
return next()
}
return property
}
if (emitMessage) {
emitMessage = false
return this.describeProperty('message', this.describeAny(this.message))
}
done = true
return null
}
return { size, next }
}
}
class DeserializedErrorValue extends object.DeserializedMixin(ErrorValue) {
constructor (state, recursor) {
super(state[1], recursor)
this.name = state[0]
}
}