function assertDefBlockStructure(
  defBlock,
  hasReturn = false,
  args = [],
  hasStatements = true,
) {
  if (hasStatements) {
    assert.isNotNull(
      defBlock.getInput('STACK'),
      'Def block should have STACK input',
    );
  } else {
    assert.isNull(
      defBlock.getInput('STACK'),
      'Def block should not have STACK input',
    );
  }
  if (hasReturn) {
    assert.isNotNull(
      defBlock.getInput('RETURN'),
      'Def block should have RETURN input',
    );
  } else {
    assert.isNull(
      defBlock.getInput('RETURN'),
      'Def block should not have RETURN input',
    );
  }
  if (args.length) {
    assert.include(
      defBlock.toString(),
      'with',
      'Def block string should include "with"',
    );
  } else {
    assert.notInclude(
      defBlock.toString(),
      'with',
      'Def block string should not include "with"',
    );
  }

  assertDefBlockArgsStructure_(defBlock, hasReturn, args, hasStatements);
}
Asserts that the procedure definition block has the expected inputs and
   fields.
@param {!Blockly.Block} defBlock The procedure definition block.
@param {boolean=} hasReturn If we expect the procedure def to have a return
    input or not.
@param {Array<string>=} args An array of argument names.
@param {boolean=} hasStatements If we expect the procedure def to have a
    statement input or not.