/*
 * Copyright 2019, TeamDev. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package io.spine.validate;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@DisplayName("Range constraint should")
class RangeConstraintTest {



    @ParameterizedTest
    @MethodSource("validRanges")
    @DisplayName("be able to obtain adequate ranges")
    void acceptProperRanges(String range, RangeType expected) {
        RangeType result = RangeType.parse(range);
        assertEquals(expected, result);
    }

    private static Stream<Arguments> validRanges() {
        return Stream.of(
                Arguments.of("[1..2]", RangeType.CLOSED),
                Arguments.of("(1..2)", RangeType.OPEN),
                Arguments.of("[1..2)", RangeType.CLOSED_OPEN),
                Arguments.of("(1..2]", RangeType.OPEN_CLOSED)
        );
    }

    @ParameterizedTest
    @MethodSource("badRanges")
    @DisplayName("throw on incorrectly defined ranges")
    void throwOnMalformedRanges(String badRange) {
        assertThrows(Exception.class, () -> RangeConstraint.rangeFromOption(badRange));
    }

    private static Stream<Arguments> badRanges() {
        return Stream.of(
                Arguments.of("{3..5]"),
                Arguments.of("[3..5}"),
                Arguments.of("{3..5}"),
                Arguments.of("(3..5"),
                Arguments.of("3..5)"),
                Arguments.of("((3..5]"),
                Arguments.of("(3..5]]"),
                Arguments.of("(3,5..5)"),
                Arguments.of("(3 5..5"),
                Arguments.of("[3..5 5]"),
                Arguments.of("[3..5,5]"),
                Arguments.of("[3;5]"),
                Arguments.of("[3.5..5)"),
                Arguments.of("[3..5.5)"),
                Arguments.of("[3...5]")
        );
    }
}

@@ -1030,24 +1030,108 @@
 .validate;%0A%0A
+import com.google.common.collect.BoundType;%0Aimport com.google.common.collect.Range;%0A
 import org.j
@@ -1698,21 +1698,21 @@
  range, 
-Range
+Bound
 Type exp
@@ -1737,37 +1737,67 @@
 ange
-Type result = RangeType.parse
+%3CComparableNumber%3E result = RangeConstraint.rangeFromOption
 (ran
@@ -1838,16 +1838,33 @@
 , result
+.upperBoundType()
 );%0A    %7D
@@ -1979,29 +1979,29 @@
 f(%22%5B1..2%5D%22, 
-Range
+Bound
 Type.CLOSED)
@@ -2037,29 +2037,29 @@
 f(%22(1..2)%22, 
-Range
+Bound
 Type.OPEN),%0A
@@ -2101,25 +2101,18 @@
 )%22, 
-RangeType.CLOSED_
+BoundType.
 OPEN
@@ -2157,23 +2157,18 @@
 %5D%22, 
-RangeType.OPEN_
+BoundType.
 CLOS

Add another positive test case.