def METHOD_NAME(self):
    code = """
        <opset_import: [ "" : 18 ], domain: "local">
        DoReduce (x, axes) => (y) {
            y = ReduceMax (x, axes)
        }
    """
    # We can omit the type for a missing trailing optional parameter
    self._check(code, [float_type_], [], [float_type_])
    # Or, we can pass in a default-value of TypeProto() for a missing optional parameter
    self._check(code, [float_type_, no_type_], [], [float_type_])
    code = """
        <opset_import: [ "" : 18 ], domain: "local">
        Quantize (x, scale, zero_point) => (y) {
            y = QuantizeLinear (x, scale, zero_point)
        }
    """
    # If the optional third parameter is specified, it determines the output type.
    self._check(code, [float_type_, float_type_, int8_type_], [], [int8_type_])
    self._check(code, [float_type_, float_type_, uint8_type_], [], [uint8_type_])
    # If the optional third parameter is omitted, the output type is uint8 (default).
    self._check(code, [float_type_, float_type_, no_type_], [], [uint8_type_])
    code = """
        <opset_import: [ "" : 18 ], domain: "local">
        DoClip (x, min, max) => (y) {
            y = Clip (x, min, max)
        }
    """
    # A test-case with a non-trailing missing optional parameter
    self._check(code, [float_type_, no_type_, float_type_], [], [float_type_])
    # A failing test-case with a non-trailing missing optional parameter
    self._check_fails(code, [float_type_, no_type_, int8_type_], [])