Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 39537
1
###############################################################################
2
#
3
# CoCalc: Collaborative web-based calculation
4
# Copyright (C) 2017, Sagemath Inc.
5
# AGPLv3
6
#
7
###############################################################################
8
9
###
10
Handling of input opts to functions and type checking.
11
###
12
13
PropTypes = require('prop-types')
14
15
immutable_types = require('./immutable-types')
16
17
###
18
Testing related env/DEVEL/DEBUG stuff
19
###
20
21
if process?.env?.DEVEL and not process?.env?.SMC_TEST
22
# Running on node and DEVEL is set and not running under test suite
23
DEBUG = true
24
else
25
DEBUG = false
26
27
# console.debug only logs if DEBUG is true
28
if DEBUG
29
console.debug = console.log
30
else
31
console.debug = ->
32
33
if process?.env?.SMC_TEST
34
# in test mode we *do* want exception to get thrown below when type checks fails
35
TEST_MODE = true
36
37
# Checks property types on a target object with checkers in a declaration.
38
# Declarations should throw an Error for mismatches and undefined if OK.
39
types = exports.types = (target, declaration, identifier="check.types") ->
40
if typeof(target) != 'object'
41
throw new Error("Types was given a non-object to check")
42
43
if typeof(declaration) != 'object'
44
throw new Error("Types was given a #{typeof declaration} as a declaration instead of an object")
45
46
PropTypes.checkPropTypes(declaration, target, 'checking a', identifier)
47
48
for key, val of PropTypes
49
if key != 'checkPropTypes' and key != 'PropTypes'
50
types[key] = val
51
52
types.immutable = immutable_types.immutable
53
54
# Returns a new object with properties determined by those of obj1 and
55
# obj2. The properties in obj1 *must* all also appear in obj2. If an
56
# obj2 property has value "defaults.required", then it must appear in
57
# obj1. For each property P of obj2 not specified in obj1, the
58
# corresponding value obj1[P] is set (all in a new copy of obj1) to
59
# be obj2[P].
60
exports.defaults = (obj1, obj2, allow_extra, strict=false) ->
61
if not obj1?
62
obj1 = {}
63
error = () ->
64
try
65
return "(obj1=#{exports.trunc(exports.to_json(obj1),1024)}, obj2=#{exports.trunc(exports.to_json(obj2),1024)})"
66
catch err
67
return ""
68
if not obj1?
69
# useful special case
70
obj1 = {}
71
if typeof(obj1) != 'object'
72
# We put explicit traces before the errors in this function,
73
# since otherwise they can be very hard to debug.
74
err = "BUG -- Traceback -- misc.defaults -- TypeError: function takes inputs as an object #{error()}"
75
if strict or DEBUG or TEST_MODE
76
throw new Error(err)
77
else
78
console.log(err)
79
console.trace()
80
return obj2
81
r = {}
82
for prop, val of obj2
83
if obj1.hasOwnProperty(prop) and obj1[prop]?
84
if obj2[prop] == exports.defaults.required and not obj1[prop]?
85
err = "misc.defaults -- TypeError: property '#{prop}' must be specified: #{error()}"
86
if strict or DEBUG or TEST_MODE
87
throw new Error(err)
88
else
89
console.warn(err)
90
console.trace()
91
r[prop] = obj1[prop]
92
else if obj2[prop]? # only record not undefined properties
93
if obj2[prop] == exports.defaults.required
94
err = "misc.defaults -- TypeError: property '#{prop}' must be specified: #{error()}"
95
if strict or DEBUG or TEST_MODE
96
throw new Error(err)
97
else
98
console.warn(err)
99
console.trace()
100
else
101
r[prop] = obj2[prop]
102
if not allow_extra
103
for prop, val of obj1
104
if not obj2.hasOwnProperty(prop)
105
err = "misc.defaults -- TypeError: got an unexpected argument '#{prop}' #{error()}"
106
if strict or DEBUG or TEST_MODE
107
throw new Error(err)
108
else
109
console.warn(err)
110
console.trace()
111
return r
112
113
# WARNING -- don't accidentally use this as a default:
114
required = exports.required = exports.defaults.required = "__!!!!!!this is a required property!!!!!!__"
115
116