// Copyright 2015 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.build.lib.packages; import static com.google.common.truth.Truth.assertThat; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL; import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.syntax.Type.INTEGER; import static com.google.devtools.build.lib.syntax.Type.STRING; import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; import static org.junit.Assert.fail; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.analysis.config.transitions.SplitTransition; import com.google.devtools.build.lib.analysis.util.TestAspects; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute.SplitTransitionProvider; import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.FileType; import com.google.devtools.build.lib.util.FileTypeSet; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** Tests of Attribute code. */ @RunWith(JUnit4.class) public class AttributeTest { private void assertDefaultValue(Object expected, Attribute attr) { assertThat(attr.getDefaultValue(null)).isEqualTo(expected); } private void assertType(Type expectedType, Attribute attr) { assertThat(attr.getType()).isEqualTo(expectedType); } @Test public void testBasics() throws Exception { Attribute attr = attr("foo", Type.INTEGER).mandatory().value(3).build(); assertThat(attr.getName()).isEqualTo("foo"); assertThat(attr.getDefaultValue(null)).isEqualTo(3); assertThat(attr.getType()).isEqualTo(Type.INTEGER); assertThat(attr.isMandatory()).isTrue(); assertThat(attr.isDocumented()).isTrue(); attr = attr("$foo", Type.INTEGER).build(); assertThat(attr.isDocumented()).isFalse(); } @Test public void testNonEmptyReqiresListType() throws Exception { try { attr("foo", Type.INTEGER).nonEmpty().value(3).build(); fail(); } catch (NullPointerException e) { assertThat(e).hasMessage("attribute 'foo' must be a list"); } } @Test public void testNonEmpty() throws Exception { Attribute attr = attr("foo", BuildType.LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build(); assertThat(attr.getName()).isEqualTo("foo"); assertThat(attr.getType()).isEqualTo(BuildType.LABEL_LIST); assertThat(attr.isNonEmpty()).isTrue(); } @Test public void testSingleArtifactReqiresLabelType() throws Exception { try { attr("foo", Type.INTEGER).singleArtifact().value(3).build(); fail(); } catch (IllegalStateException e) { assertThat(e).hasMessage("attribute 'foo' must be a label-valued type"); } } @Test public void testDoublePropertySet() { Attribute.Builder builder = attr("x", STRING).mandatory() .cfg(HostTransition.INSTANCE) .undocumented("") .value("y"); try { builder.mandatory(); fail(); } catch (IllegalStateException expected) { // expected } try { builder.cfg(HostTransition.INSTANCE); fail(); } catch (IllegalStateException expected) { // expected } try { builder.undocumented(""); fail(); } catch (IllegalStateException expected) { // expected } try { builder.value("z"); fail(); } catch (IllegalStateException expected) { // expected } builder = attr("$x", STRING); try { builder.undocumented(""); fail(); } catch (IllegalStateException expected) { // expected } } /** * Tests the "convenience factories" (string, label, etc) for default * values. */ @Test public void testConvenienceFactoriesDefaultValues() throws Exception { assertDefaultValue(0, attr("x", INTEGER).build()); assertDefaultValue(42, attr("x", INTEGER).value(42).build()); assertDefaultValue("", attr("x", STRING).build()); assertDefaultValue("foo", attr("x", STRING).value("foo").build()); Label label = Label.parseAbsolute("//foo:bar", ImmutableMap.of()); assertDefaultValue(null, attr("x", LABEL).legacyAllowAnyFileType().build()); assertDefaultValue(label, attr("x", LABEL).legacyAllowAnyFileType().value(label).build()); List slist = Arrays.asList("foo", "bar"); assertDefaultValue(Collections.emptyList(), attr("x", STRING_LIST).build()); assertDefaultValue(slist, attr("x", STRING_LIST).value(slist).build()); List