/*
 * 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 org.apache.drill.common.util.function;

import org.apache.drill.test.BaseTest;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;

import java.util.HashMap;
import java.util.Map;

import static org.hamcrest.CoreMatchers.containsString;

public class TestCheckedFunction extends BaseTest {

  @Test
  public void testComputeIfAbsentWithCheckedFunction() {
    ExceptionProducer producer = new ExceptionProducer();
    Map<String, String> map = new HashMap<>();
    String message = "Exception message";
    CheckedFunction<String, String, Exception> function = producer::failWithMessage;

    Exception exception = Assert.assertThrows(Exception.class, () -> map.computeIfAbsent(message, function));
    MatcherAssert.assertThat(exception.getMessage(), containsString(message));
  }

  private class ExceptionProducer {

    String failWithMessage(String message) throws Exception {
      throw new Exception(message);
    }

  }

}
