Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

uber / deck.gl / 13720

17 Sep 2019 - 4:53 coverage increased (+2.8%) to 82.714%
13720

Pull #3588

travis-ci-com

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Try to fix examples
Pull Request #3588: Add JSON Tile3D examples to Playground

3390 of 4602 branches covered (73.66%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

479 existing lines in 86 files now uncovered.

7161 of 8154 relevant lines covered (87.82%)

4294.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.06
/modules/core/src/lifecycle/props.js
1
import assert from '../utils/assert';
2

3
export function validateProps(props) {
4
  const propTypes = getPropTypes(props);
1×
5

6
  for (const propName in propTypes) {
4×
7
    const propType = propTypes[propName];
4×
8
    const {validate} = propType;
5×
9
    if (validate && !validate(props[propName], propType)) {
1×
10
      throw new Error(`Invalid prop ${propName}: ${props[propName]}`);
1×
11
    }
12
  }
13
}
14

15
// Returns an object with "change flags", either false or strings indicating reason for change
16
export function diffProps(props, oldProps) {
17
  // First check if any props have changed (ignore props that will be examined separately)
18
  const propsChangedReason = compareProps({
9×
19
    newProps: props,
20
    oldProps,
21
    propTypes: getPropTypes(props),
22
    ignoreProps: {data: null, updateTriggers: null, extensions: null, transitions: null}
23
  });
24

25
  // Now check if any data related props have changed
26
  const dataChangedReason = diffDataProps(props, oldProps);
9×
27

28
  // Check update triggers to determine if any attributes need regeneration
29
  // Note - if data has changed, all attributes will need regeneration, so skip this step
30
  let updateTriggersChangedReason = false;
259×
31
  if (!dataChangedReason) {
259×
32
    updateTriggersChangedReason = diffUpdateTriggers(props, oldProps);
259×
33
  }
34

35
  return {
5×
36
    dataChanged: dataChangedReason,
37
    propsChanged: propsChangedReason,
38
    updateTriggersChanged: updateTriggersChangedReason,
39
    extensionsChanged: diffExtensions(props, oldProps),
40
    transitionsChanged: diffTransitions(props, oldProps)
41
  };
42
}
43

44
function diffTransitions(props, oldProps) {
45
  if (!props.transitions) {
1,121×
46
    return null;
1,121×
47
  }
48
  const result = {};
1,121×
49
  const propTypes = getPropTypes(props);
1,121×
50

51
  for (const key in props.transitions) {
893×
52
    const propType = propTypes[key];
1,121×
53
    const type = propType && propType.type;
1,121×
54
    const isTransitionable = type === 'number' || type === 'color' || type === 'array';
Branches [[5, 1], [5, 2]] missed. 1,118×
55
    if (isTransitionable && comparePropValues(props[key], oldProps[key], propType)) {
3×
56
      result[key] = true;
3×
57
    }
58
  }
59
  return result;
3×
60
}
61

62
/**
63
 * Performs equality by iterating through keys on an object and returning false
64
 * when any key has values which are not strictly equal between the arguments.
65
 * @param {Object} opt.oldProps - object with old key/value pairs
66
 * @param {Object} opt.newProps - object with new key/value pairs
67
 * @param {Object} opt.ignoreProps={} - object, keys that should not be compared
68
 * @returns {null|String} - null when values of all keys are strictly equal.
69
 *   if unequal, returns a string explaining what changed.
70
 */
71
/* eslint-disable max-statements, max-depth, complexity */
72
/*
73
 * Note: for better performance, this function assumes that both oldProps and newProps
74
   inherit the same prototype (defaultProps). That is, if neither object contains own
75
   property <key>, assume `oldProps.<key>` and `newProps.<key>` are equal.
76
 */
77
export function compareProps({
Branches [[8, 0]] missed.
78
  newProps,
79
  oldProps,
80
  ignoreProps = {},
81
  propTypes = {},
82
  triggerName = 'props'
83
} = {}) {
84
  assert(oldProps !== undefined && newProps !== undefined, 'compareProps args');
3×
85

86
  // shallow equality => deep equality
87
  if (oldProps === newProps) {
3×
88
    return null;
3×
89
  }
90

91
  // TODO - do we need these checks? Should never happen...
92
  if (typeof newProps !== 'object' || newProps === null) {
3×
93
    return `${triggerName} changed shallowly`;
1×
94
  }
95

96
  if (typeof oldProps !== 'object' || oldProps === null) {
3×
97
    return `${triggerName} changed shallowly`;
3,050×
98
  }
99

100
  // Compare explicitly defined new props against old/default values
101
  for (const key of Object.keys(newProps)) {
3,050×
102
    if (!(key in ignoreProps)) {
83×
103
      if (!(key in oldProps)) {
2,967×
104
        return `${triggerName}.${key} added`;
269×
105
      }
106
      const changed = comparePropValues(newProps[key], oldProps[key], propTypes[key]);
2,698×
107
      if (changed) {
44×
108
        return `${triggerName}.${key} ${changed}`;
2,654×
109
      }
110
    }
111
  }
112

113
  // Test if any old props have been dropped
114
  for (const key of Object.keys(oldProps)) {
12,794×
115
    if (!(key in ignoreProps)) {
11,738×
116
      if (!(key in newProps)) {
39×
117
        return `${triggerName}.${key} dropped`;
11,699×
118
      }
119
      if (!Object.hasOwnProperty.call(newProps, key)) {
11,699×
120
        // Compare dropped old prop against default value
121
        const changed = comparePropValues(newProps[key], oldProps[key], propTypes[key]);
543×
122
        if (changed) {
2,072×
123
          return `${triggerName}.${key} ${changed}`;
10,021×
124
        }
125
      }
126
    }
127
  }
128

129
  return null;
9,029×
130
}
131
/* eslint-enable max-statements, max-depth, complexity */
132

133
// HELPERS
134
function comparePropValues(newProp, oldProp, propType) {
135
  // If prop type has an equal function, invoke it
136
  let equal = propType && propType.equal;
4×
137
  if (equal && !equal(newProp, oldProp, propType)) {
9,025×
138
    return 'changed deeply';
30×
139
  }
140

141
  if (!equal) {
30×
142
    // If object has an equals function, invoke it
143
    equal = newProp && oldProp && newProp.equals;
24×
144
    if (equal && !equal.call(newProp, oldProp)) {
2,044×
145
      return 'changed deeply';
11,732×
146
    }
147
  }
148

149
  if (!equal && oldProp !== newProp) {
11,732×
150
    return 'changed shallowly';
273×
151
  }
152

153
  return null;
11,459×
154
}
155

156
// The comparison of the data prop requires special handling
157
// the dataComparator should be used if supplied
158
function diffDataProps(props, oldProps) {
159
  if (oldProps === null) {
Branches [[34, 0]] missed. 5,368×
160
    return 'oldProps is null, initial diff';
5,368×
161
  }
162

163
  let dataChanged = null;
1×
164
  // Support optional app defined comparison of data
165
  const {dataComparator, _dataDiff} = props;
11,458×
166
  if (dataComparator) {
Branches [[35, 0]] missed. 294×
167
    if (!dataComparator(props.data, oldProps.data)) {
Branches [[36, 0], [36, 1]] missed. 11,164×
168
      dataChanged = 'Data comparator detected a change';
1,121×
169
    }
170
    // Otherwise, do a shallow equal on props
UNCOV
171
  } else if (props.data !== oldProps.data) {
!
172
    dataChanged = 'A new data container was supplied';
1,121×
173
  }
174
  if (dataChanged && _dataDiff) {
1,121×
175
    dataChanged = _dataDiff(props.data, oldProps.data) || dataChanged;
1,121×
176
  }
177

UNCOV
178
  return dataChanged;
!
179
}
180

181
// Checks if any update triggers have changed
182
// also calls callback to invalidate attributes accordingly.
183
function diffUpdateTriggers(props, oldProps) {
UNCOV
184
  if (oldProps === null) {
Branches [[41, 0]] missed. !
185
    return 'oldProps is null, initial diff';
1,121×
186
  }
187

188
  // If the 'all' updateTrigger fires, ignore testing others
189
  if ('all' in props.updateTriggers) {
228×
190
    const diffReason = diffUpdateTrigger(props, oldProps, 'all');
1,121×
191
    if (diffReason) {
Branches [[43, 0]] missed. 162×
192
      return {all: true};
1,121×
193
    }
194
  }
195

196
  const triggerChanged = {};
893×
UNCOV
197
  let reason = false;
!
198
  // If the 'all' updateTrigger didn't fire, need to check all others
199
  for (const triggerName in props.updateTriggers) {
893×
200
    if (triggerName !== 'all') {
407×
201
      const diffReason = diffUpdateTrigger(props, oldProps, triggerName);
407×
UNCOV
202
      if (diffReason) {
!
203
        triggerChanged[triggerName] = true;
893×
204
        reason = triggerChanged;
893×
205
      }
206
    }
207
  }
208

209
  return reason;
893×
210
}
211

212
// Returns true if any extensions have changed
213
function diffExtensions(props, oldProps) {
214
  if (oldProps === null) {
Branches [[46, 0]] missed. 1,907×
215
    return 'oldProps is null, initial diff';
1,500×
216
  }
217

218
  const oldExtensions = oldProps.extensions;
1,500×
219
  const {extensions} = props;
402×
220

221
  if (extensions === oldExtensions) {
402×
222
    return false;
893×
223
  }
224
  if (extensions.length !== oldExtensions.length) {
1,121×
UNCOV
225
    return true;
!
226
  }
227
  for (let i = 0; i < extensions.length; i++) {
1,121×
228
    if (!extensions[i].equals(oldExtensions[i])) {
1,121×
229
      return true;
1,117×
230
    }
231
  }
232
  return false;
4×
233
}
234

235
function diffUpdateTrigger(props, oldProps, triggerName) {
236
  let newTriggers = props.updateTriggers[triggerName];
1×
237
  newTriggers = newTriggers === undefined || newTriggers === null ? {} : newTriggers;
3×
238
  let oldTriggers = oldProps.updateTriggers[triggerName];
3×
239
  oldTriggers = oldTriggers === undefined || oldTriggers === null ? {} : oldTriggers;
3×
240
  const diffReason = compareProps({
2×
241
    oldProps: oldTriggers,
242
    newProps: newTriggers,
243
    triggerName
244
  });
245
  return diffReason;
1×
246
}
247

248
function getPropTypes(props) {
249
  const layer = props._component;
1,907×
250
  const LayerType = layer && layer.constructor;
1,907×
251
  return LayerType ? LayerType._propTypes : {};
Branches [[55, 1]] missed. 1,907×
252
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2019 Coveralls, LLC