blob: 626d08786dc7c8b9e96fe11333f09de81812abb0 [file] [log] [blame]
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.common.options.testing;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionEffectTag;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for the OptionsTester. */
@RunWith(JUnit4.class)
public final class OptionsTesterTest {
@Test
public void optionAnnotationCheck_PassesWhenAllFieldsAnnotated() throws Exception {
new OptionsTester(OptionAnnotationCheckAllFieldsAnnotated.class)
.testAllInstanceFieldsAnnotatedWithOption();
}
/** Test options class for optionAnnotationCheck_PassesWhenAllFieldsAnnotated. */
public static class BaseAllFieldsAnnotated extends OptionsBase {
@Option(
name = "public_inherited_field_with_annotation",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "defaultFoo"
)
public String inheritedField;
}
/** Test options class for optionAnnotationCheck_PassesWhenAllFieldsAnnotated. */
public static final class OptionAnnotationCheckAllFieldsAnnotated extends BaseAllFieldsAnnotated {
@Option(
name = "public_declared_field_with_annotation",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "defaultFoo"
)
public String publicField;
@Option(
name = "other_public_declared_field_with_annotation",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "defaultFoo"
)
public String publicField2;
}
@Test
public void optionAnnotationCheck_AllowsUnAnnotatedStaticFields() throws Exception {
new OptionsTester(OptionAnnotationCheckUnAnnotatedStaticField.class)
.testAllInstanceFieldsAnnotatedWithOption();
}
/** Test options class for optionAnnotationCheck_AllowsUnAnnotatedStaticFields. */
public static class BaseUnAnnotatedStaticField extends OptionsBase {
public static String parentClassUnAnnotatedStaticField;
}
/** Test options class for optionAnnotationCheck_AllowsUnAnnotatedStaticFields. */
public static final class OptionAnnotationCheckUnAnnotatedStaticField
extends BaseUnAnnotatedStaticField {
@SuppressWarnings("unused")
private static String privateDeclaredUnAnnotatedStaticField;
}
@Test
public void optionAnnotationCheck_FailsWhenFieldNotAnnotated() throws Exception {
try {
new OptionsTester(OptionAnnotationCheckUnAnnotatedField.class)
.testAllInstanceFieldsAnnotatedWithOption();
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("unAnnotatedField");
return;
}
fail("test is expected to have failed");
}
/** Test options class for optionAnnotationCheck_FailsWhenFieldNotAnnotated. */
public static class OptionAnnotationCheckUnAnnotatedField extends OptionsBase {
public String unAnnotatedField;
}
@Test
public void optionAnnotationCheck_FailsForUnAnnotatedFieldsInSuperclass() throws Exception {
try {
new OptionsTester(OptionAnnotationCheckInheritedUnAnnotatedField.class)
.testAllInstanceFieldsAnnotatedWithOption();
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("unAnnotatedField");
return;
}
fail("test is expected to have failed");
}
/** Test options class for optionAnnotationCheck_FailsForUnAnnotatedFieldsInSuperclass. */
public static final class OptionAnnotationCheckInheritedUnAnnotatedField
extends OptionAnnotationCheckUnAnnotatedField {}
@Test
public void optionAnnotationCheck_FailsForPrivateUnAnnotatedField() throws Exception {
try {
new OptionsTester(OptionAnnotationCheckPrivateUnAnnotatedField.class)
.testAllInstanceFieldsAnnotatedWithOption();
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("privateUnAnnotatedField");
return;
}
fail("test is expected to have failed");
}
/** Test options class for optionAnnotationCheck_FailsForPrivateUnAnnotatedField. */
public static final class OptionAnnotationCheckPrivateUnAnnotatedField extends OptionsBase {
@SuppressWarnings("unused")
private String privateUnAnnotatedField;
}
/** Test options class for optionAccessCheck_PassesWhenAllFieldsPublicNotStaticNotFinal. */
public static class BaseAllFieldsPublicNotStaticNotFinal extends OptionsBase {
@Option(
name = "public_inherited_field_with_annotation",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "defaultFoo"
)
public String inheritedField;
}
/** Test options class for optionAccessCheck_PassesWhenAllFieldsPublicNotStaticNotFinal. */
public static final class OptionAccessCheckAllFieldsPublicNotStaticNotFinal
extends BaseAllFieldsPublicNotStaticNotFinal {
@Option(
name = "public_declared_field_with_annotation",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "defaultFoo"
)
public String annotatedField;
}
/** Test options class for optionAccessCheck_IgnoresNonAnnotatedFields. */
public static class BaseNonAnnotatedFields extends OptionsBase {
protected static String parentClassUnAnnotatedStaticField;
final String parentClassUnAnnotatedFinalField = "";
}
/** Test options class for optionAccessCheck_IgnoresNonAnnotatedFields. */
public static final class OptionAccessCheckNonAnnotatedFields extends BaseNonAnnotatedFields {
@SuppressWarnings("unused")
private static String privateDeclaredUnAnnotatedStaticFinalField;
public static final String PUBLIC_DECLARED_UN_ANNOTATED_STATIC_FIELD = "";
protected String protectedDeclaredField;
}
/** Test converter class for testing testAllDefaultValuesTestedBy. */
public static final class TestConverter implements Converter<String> {
@Override
public String convert(String input) {
return input;
}
@Override
public String getTypeDescription() {
return "a string";
}
}
@Test
public void defaultTestCheck_PassesIfAllDefaultsTestedIgnoringNullAndAllowMultiple() {
new OptionsTester(DefaultTestCheck.class)
.testAllDefaultValuesTestedBy(
new ConverterTesterMap.Builder()
.add(
new ConverterTester(TestConverter.class)
.addEqualityGroup("testedDefault", "otherTestedDefault"))
.build());
}
/** Test options class for defaultTestCheck_PassesIfAllDefaultsTested. */
public static final class DefaultTestCheck extends OptionsBase {
@Option(
name = "tested_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "testedDefault"
)
public String testedField;
@Option(
name = "field_implicitly_using_default_converter",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
defaultValue = "implicitConverterDefault"
)
public String implicitConverterField;
@Option(
name = "other_tested_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "otherTestedDefault"
)
public String otherTestedField;
@Option(
name = "field_with_null_default",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "null"
)
public String nullDefaultField;
@Option(
name = "allowMultiple_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "allowMultipleDefault",
allowMultiple = true
)
public List<String> allowMultipleField;
}
@Test
public void defaultTestCheck_FailsIfTesterIsPresentButValueIsNotTested() {
try {
new OptionsTester(DefaultTestCheckUntestedField.class)
.testAllDefaultValuesTestedBy(
new ConverterTesterMap.Builder()
.add(new ConverterTester(TestConverter.class).addEqualityGroup("testedDefault"))
.build());
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("untestedField");
assertThat(expected).hasMessageThat().contains("untestedDefault");
return;
}
fail("test is expected to have failed");
}
@Test
public void defaultTestCheck_FailsIfTesterIsAbsent() {
try {
new OptionsTester(DefaultTestCheckUntestedField.class)
.testAllDefaultValuesTestedBy(new ConverterTesterMap.Builder().build());
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("TestConverter");
return;
}
fail("test is expected to have failed");
}
/**
* Test options class for defaultTestCheck_FailsIfTesterIsPresentButValueIsNotTested and
* defaultTestCheck_FailsIfTesterIsAbsent.
*/
public static final class DefaultTestCheckUntestedField extends OptionsBase {
@Option(
name = "untested_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "untestedDefault"
)
public String untestedField;
}
@Test
public void defaultTestCheck_FailsIfTesterIsAbsentEvenForNullDefault() {
try {
new OptionsTester(DefaultTestCheckUntestedNullField.class)
.testAllDefaultValuesTestedBy(new ConverterTesterMap.Builder().build());
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("TestConverter");
return;
}
fail("test is expected to have failed");
}
/** Test options class for defaultTestCheck_FailsIfTesterIsAbsentEvenForNullDefault. */
public static final class DefaultTestCheckUntestedNullField extends OptionsBase {
@Option(
name = "untested_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "null"
)
public String untestedNullField;
}
@Test
public void defaultTestCheck_FailsIfTesterIsAbsentEvenForAllowMultiple() {
try {
new OptionsTester(DefaultTestCheckUntestedMultipleField.class)
.testAllDefaultValuesTestedBy(new ConverterTesterMap.Builder().build());
} catch (AssertionError expected) {
assertThat(expected).hasMessageThat().contains("TestConverter");
return;
}
fail("test is expected to have failed");
}
/** Test options class for defaultTestCheck_FailsIfTesterIsAbsentEvenForAllowMultiple. */
public static final class DefaultTestCheckUntestedMultipleField extends OptionsBase {
@Option(
name = "untested_field",
documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
effectTags = {OptionEffectTag.NO_OP},
converter = TestConverter.class,
defaultValue = "untestedDefault",
allowMultiple = true
)
public List<String> untestedMultipleField;
}
}