/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed 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 android.hardware.cts.helpers.sensorverification;

import junit.framework.TestCase;

import android.hardware.cts.helpers.SensorStats;
import android.hardware.cts.helpers.TestSensorEnvironment;
import android.hardware.cts.helpers.TestSensorEvent;

/**
 * Tests for {@link MagnitudeVerification}.
 */
public class MagnitudeVerificationTest extends TestCase {

    /**
     * Test {@link MagnitudeVerification#verify(TestSensorEnvironment, SensorStats)}.
     */
    public void testVerify() {
        float[][] values = {
                {0, 3, 4},
                {4, 0, 3},
                {3, 4, 0},
                {0, 0, 4},
                {6, 0, 0},
        };

        runStats(5.0f, 0.1f, values, true, 5.0f);
        runStats(4.5f, 0.6f, values, true, 5.0f);
        runStats(5.5f, 0.6f, values, true, 5.0f);
        runStats(4.5f, 0.1f, values, false, 5.0f);
        runStats(5.5f, 0.1f, values, false, 5.0f);
    }

    private void runStats(float expected, float threshold, float[][] values, boolean pass, float magnitude) {
        SensorStats stats = new SensorStats();
        MagnitudeVerification verification = getVerification(expected, threshold, values);
        if (pass) {
            verification.verify(stats);
        } else {
            try {
                verification.verify(stats);
                fail("Expected an AssertionError");
            } catch (AssertionError e) {
                // Expected;
            }
        }
        assertEquals(pass, stats.getValue(MagnitudeVerification.PASSED_KEY));
        assertEquals(magnitude, (Float) stats.getValue(SensorStats.MAGNITUDE_KEY), 0.01);
    }

    private MagnitudeVerification getVerification(float expected, float threshold,
            float[] ... values) {
        MagnitudeVerification verification = new MagnitudeVerification(expected, threshold);
        for (float[] value : values) {
            verification.addSensorEvent(new TestSensorEvent(null, 0, 0, value));
        }
        return verification;
    }
}
