/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package groovy.bugs

import groovy.test.GroovyTestCase

class Groovy2350Bug extends GroovyTestCase{

     void testNoArg () {
         shouldFail (org.codehaus.groovy.runtime.metaclass.MethodSelectionException) {
             def a = new DefaultNoArgCtor()
         }

         assertEquals "NULL", new DefaultNoArgCtor2().value
     }

     void testNoDefCtor () {
         def a = new NoDefaultCtor("first")
         assertEquals "toS: first", a.toString()

         def b = new NoDefaultCtor()
         assertEquals "toS: null", b.toString()
     }
}

class NoDefaultCtor {
    def field

    NoDefaultCtor(param) { field= param }

    String toString() {
      return "toS: ${field}"
    }
}


class DefaultNoArgCtor {
  DefaultNoArgCtor(String s) {}

  DefaultNoArgCtor(int s) {}
}

class DefaultNoArgCtor2 {
  String value

  DefaultNoArgCtor2(String s) {
      value = s ? s : "NULL"
  }
}
