/*
 * 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 SF 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.sling.hc.impl.healthchecks;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class PathSpecTest {
    private final String pathSpec;
    private final String expectedPath;
    private final int expectedStatus;
    
    @Parameters(name="{1}")
    public static List<Object[]> data() {
        final List<Object[]> result = new ArrayList<Object[]>();

        result.add(new Object[] { "/one.html", "/one.html", 200 } ); 
        result.add(new Object[] { "/two.html:404", "/two.html", 404 } ); 
        result.add(new Object[] { "three.html : 404 ", "three.html", 404 } ); 
        result.add(new Object[] { "four.html:not an integer", "four.html:not an integer", 200 } ); 
        result.add(new Object[] { "", "", 200 } ); 

        return result;
    }

    public PathSpecTest(String pathSpec, String expectedPath, int expectedStatus) {
        this.pathSpec = pathSpec;
        this.expectedPath = expectedPath;
        this.expectedStatus = expectedStatus;
    }
    
    @Test
    public void testParsing() {
        final SlingRequestStatusHealthCheck.PathSpec ps = new SlingRequestStatusHealthCheck.PathSpec(pathSpec);
        assertEquals(expectedPath, ps.path);
        assertEquals(expectedStatus, ps.status);
    }
}
