blob: 3e18319166adb52f6f8df38f85c0f48fdda74389 [file] [log] [blame]
Lukacs Berki14328eb2015-10-21 10:47:26 +00001// Copyright 2006 The Bazel Authors. All Rights Reserved.
Ulf Adams89f012d2015-02-26 13:39:28 +00002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.syntax;
16
Ulf Adams795895a2015-03-06 15:58:35 +000017import static com.google.common.truth.Truth.assertThat;
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000018import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.fail;
20
Ulf Adams89f012d2015-02-26 13:39:28 +000021import com.google.common.collect.Sets;
Han-Wen Nienhuysceae8c52015-09-22 16:24:45 +000022import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
Ulf Adams89f012d2015-02-26 13:39:28 +000023
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000024import org.junit.Test;
25import org.junit.runner.RunWith;
26import org.junit.runners.JUnit4;
27
Ulf Adams89f012d2015-02-26 13:39:28 +000028/**
29 * Tests of Environment.
30 */
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000031@RunWith(JUnit4.class)
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000032public class EnvironmentTest extends EvaluationTestCase {
33
34 @Override
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +000035 public Environment newEnvironment() {
36 return newBuildEnvironment();
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000037 }
Ulf Adams89f012d2015-02-26 13:39:28 +000038
39 // Test the API directly
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000040 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000041 public void testLookupAndUpdate() throws Exception {
Ulf Adams89f012d2015-02-26 13:39:28 +000042 try {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000043 lookup("foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000044 fail();
45 } catch (Environment.NoSuchVariableException e) {
Ulf Adams795895a2015-03-06 15:58:35 +000046 assertThat(e).hasMessage("no such variable: foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000047 }
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000048 update("foo", "bar");
49 assertEquals("bar", lookup("foo"));
Ulf Adams89f012d2015-02-26 13:39:28 +000050 }
51
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000052 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000053 public void testLookupWithDefault() throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000054 assertEquals(21, getEnvironment().lookup("VERSION", 21));
55 update("VERSION", 42);
56 assertEquals(42, getEnvironment().lookup("VERSION", 21));
Ulf Adams89f012d2015-02-26 13:39:28 +000057 }
58
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000059 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000060 public void testDoubleUpdateSucceeds() throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000061 update("VERSION", 42);
62 assertEquals(42, lookup("VERSION"));
63 update("VERSION", 43);
64 assertEquals(43, lookup("VERSION"));
Ulf Adams89f012d2015-02-26 13:39:28 +000065 }
66
67 // Test assign through interpreter, lookup through API:
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000068 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000069 public void testAssign() throws Exception {
Ulf Adams89f012d2015-02-26 13:39:28 +000070 try {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000071 lookup("foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000072 fail();
73 } catch (Environment.NoSuchVariableException e) {
Ulf Adams795895a2015-03-06 15:58:35 +000074 assertThat(e).hasMessage("no such variable: foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000075 }
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000076 eval("foo = 'bar'");
77 assertEquals("bar", lookup("foo"));
Ulf Adams89f012d2015-02-26 13:39:28 +000078 }
79
80 // Test update through API, reference through interpreter:
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000081 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000082 public void testReference() throws Exception {
Ulf Adams89f012d2015-02-26 13:39:28 +000083 try {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000084 eval("foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000085 fail();
86 } catch (EvalException e) {
Ulf Adams795895a2015-03-06 15:58:35 +000087 assertThat(e).hasMessage("name 'foo' is not defined");
Ulf Adams89f012d2015-02-26 13:39:28 +000088 }
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000089 update("foo", "bar");
90 assertEquals("bar", eval("foo"));
Ulf Adams89f012d2015-02-26 13:39:28 +000091 }
92
93 // Test assign and reference through interpreter:
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +000094 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +000095 public void testAssignAndReference() throws Exception {
Ulf Adams89f012d2015-02-26 13:39:28 +000096 try {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +000097 eval("foo");
Ulf Adams89f012d2015-02-26 13:39:28 +000098 fail();
99 } catch (EvalException e) {
Ulf Adams795895a2015-03-06 15:58:35 +0000100 assertThat(e).hasMessage("name 'foo' is not defined");
Ulf Adams89f012d2015-02-26 13:39:28 +0000101 }
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000102 eval("foo = 'bar'");
103 assertEquals("bar", eval("foo"));
Ulf Adams89f012d2015-02-26 13:39:28 +0000104 }
105
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000106 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000107 public void testGetVariableNames() throws Exception {
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000108 Environment outerEnv;
109 Environment innerEnv;
110 try (Mutability mut = Mutability.create("outer")) {
111 outerEnv = Environment.builder(mut)
112 .setGlobals(Environment.BUILD).build()
113 .update("foo", "bar")
114 .update("wiz", 3);
115 }
116 try (Mutability mut = Mutability.create("inner")) {
117 innerEnv = Environment.builder(mut)
118 .setGlobals(outerEnv.getGlobals()).build()
119 .update("foo", "bat")
120 .update("quux", 42);
121 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000122
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000123 assertEquals(Sets.newHashSet("foo", "wiz",
124 "False", "None", "True",
125 "-", "bool", "dict", "enumerate", "int", "len", "list",
Florian Weikertd5e33502015-12-14 12:06:10 +0000126 "range", "repr", "reversed", "select", "sorted", "str", "zip"),
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000127 outerEnv.getVariableNames());
128 assertEquals(Sets.newHashSet("foo", "wiz", "quux",
129 "False", "None", "True",
130 "-", "bool", "dict", "enumerate", "int", "len", "list",
Florian Weikertd5e33502015-12-14 12:06:10 +0000131 "range", "repr", "reversed", "select", "sorted", "str", "zip"),
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000132 innerEnv.getVariableNames());
Ulf Adams89f012d2015-02-26 13:39:28 +0000133 }
134
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000135 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000136 public void testToString() throws Exception {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000137 update("subject", new StringLiteral("Hello, 'world'.", '\''));
138 update("from", new StringLiteral("Java", '"'));
Francois-Rene Rideaubd0c7bb2015-09-21 16:54:19 +0000139 assertThat(getEnvironment().toString()).isEqualTo("<Environment[test]>");
Ulf Adams89f012d2015-02-26 13:39:28 +0000140 }
141
Han-Wen Nienhuysccf19ea2015-02-27 15:53:24 +0000142 @Test
Ulf Adams89f012d2015-02-26 13:39:28 +0000143 public void testBindToNullThrowsException() throws Exception {
144 try {
Francois-Rene Rideau5f3e30c2015-04-10 19:08:39 +0000145 update("some_name", null);
Ulf Adams89f012d2015-02-26 13:39:28 +0000146 fail();
147 } catch (NullPointerException e) {
Ulf Adams795895a2015-03-06 15:58:35 +0000148 assertThat(e).hasMessage("update(value == null)");
Ulf Adams89f012d2015-02-26 13:39:28 +0000149 }
150 }
Francois-Rene Rideau89312fb2015-09-10 18:53:03 +0000151
152 @Test
153 public void testFrozen() throws Exception {
154 Environment env;
155 try (Mutability mutability = Mutability.create("testFrozen")) {
156 env = Environment.builder(mutability)
157 .setGlobals(Environment.BUILD).setEventHandler(Environment.FAIL_FAST_HANDLER).build();
158 env.update("x", 1);
159 assertEquals(env.lookup("x"), 1);
160 env.update("y", 2);
161 assertEquals(env.lookup("y"), 2);
162 assertEquals(env.lookup("x"), 1);
163 env.update("x", 3);
164 assertEquals(env.lookup("x"), 3);
165 }
166 try {
167 // This update to an existing variable should fail because the environment was frozen.
168 env.update("x", 4);
169 throw new Exception("failed to fail"); // not an AssertionError like fail()
170 } catch (AssertionError e) {
171 assertThat(e).hasMessage("Can't update x to 4 in frozen environment");
172 }
173 try {
174 // This update to a new variable should also fail because the environment was frozen.
175 env.update("newvar", 5);
176 throw new Exception("failed to fail"); // not an AssertionError like fail()
177 } catch (AssertionError e) {
178 assertThat(e).hasMessage("Can't update newvar to 5 in frozen environment");
179 }
180 }
181
182 @Test
183 public void testReadOnly() throws Exception {
184 Environment env = newSkylarkEnvironment()
185 .setup("special_var", 42)
186 .update("global_var", 666);
187
188 // We don't even get a runtime exception trying to modify these,
189 // because we get compile-time exceptions even before we reach runtime!
190 try {
191 env.eval("special_var = 41");
192 throw new AssertionError("failed to fail");
193 } catch (IllegalArgumentException e) {
194 assertThat(e).hasMessage("ERROR 1:1: Variable special_var is read only");
195 }
196
197 try {
198 env.eval("def foo(x): x += global_var; global_var = 36; return x", "foo(1)");
199 throw new AssertionError("failed to fail");
200 } catch (EvalExceptionWithStackTrace e) {
201 assertThat(e.getMessage()).contains("Variable 'global_var' is referenced before assignment. "
202 + "The variable is defined in the global scope.");
203 }
204 }
Ulf Adams89f012d2015-02-26 13:39:28 +0000205}