All files / helpers validate.js

50% Statements 15/30
33.33% Branches 6/18
57.14% Functions 4/7
57.69% Lines 15/26

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 802x 2x 2x 2x                                                                           1x 1x       1x       1x         1x 1x   1x   1x   1x 1x                             2x  
const assert = require('assert');
const testASTShape = require('../utils/test-ast-shape');
const { evaluateNodePath } = require('../utils/ast');
const { isAtRuleObject } = require('../utils/styles');
 
function isHMR(identifier) {
  return testASTShape(identifier.parentPath, {
    type: 'CallExpression',
    callee: {
      type: 'MemberExpression',
      object: {
        name: 'reactHotLoader'
      },
      property: {
        name: 'register'
      }
    }
  });
}
 
function validateReferences(references) {
  references.forEach(ref => {
    const { parentPath, parent, node } = ref;
    if (parentPath.isCallExpression() && parent.callee === node) return;
    if (parentPath.isSpreadElement()) return;
    if (parentPath.isMemberExpression()) return;
 
    // The return value from `style9.create` should be a function, but the
    // compiler turns it into an object. Therefore only access to properties
    // is allowed. React Hot Loader accesses all bindings, so a temporary
    // workaround is required. React Fast Refresh does not have this problem.
    assert(
      isHMR(ref),
      ref.buildCodeFrameError(
        'Return value from style9.create has to be called as a function or accessed as an object'
      )
    );
  });
}
 
function evalKey(objProp) {
  const keyPath = objProp.get('key');
  Iif (objProp.node.computed) {
    return evaluateNodePath(keyPath);
  }
 
  Iif (keyPath.isStringLiteral()) {
    return keyPath.node.value;
  }
 
  return keyPath.node.name;
}
 
// Does not validate spread elements
function validateStyleObject(objExpr) {
  objExpr.get('properties').forEach(prop => {
    Iif (!prop.isObjectProperty()) return;
 
    prop.get('value').traverse({
      ObjectProperty(path) {
        const key = evalKey(path);
 
        Eif (path.get('value').isObjectExpression() && !isAtRuleObject(key)) {
          throw path
            .get('key')
            .buildCodeFrameError(
              `Invalid key ${key}. Object keys must be at-rules or pseudo selectors`
            );
        }
 
        // Skip direct props
        validateStyleObject(path.get('value'));
        path.skip();
      }
    });
  });
}
 
module.exports = { validateReferences, validateStyleObject };