Index: components/policy/android/javatests/src/org/chromium/policy/test/annotations/Policies.java |
diff --git a/components/policy/android/javatests/src/org/chromium/policy/test/annotations/Policies.java b/components/policy/android/javatests/src/org/chromium/policy/test/annotations/Policies.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7dbe596f698ac888631c62c0e1567f7e78a5680d |
--- /dev/null |
+++ b/components/policy/android/javatests/src/org/chromium/policy/test/annotations/Policies.java |
@@ -0,0 +1,138 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.policy.test.annotations; |
+ |
+import android.content.Context; |
+import android.os.Bundle; |
+ |
+import junit.framework.Assert; |
+ |
+import org.chromium.base.test.BaseTestResult.PreTestHook; |
+import org.chromium.policy.AbstractAppRestrictionsProvider; |
+import org.chromium.policy.test.PolicyData; |
+ |
+import java.lang.annotation.ElementType; |
+import java.lang.annotation.Inherited; |
+import java.lang.annotation.Retention; |
+import java.lang.annotation.RetentionPolicy; |
+import java.lang.annotation.Target; |
+import java.lang.reflect.AnnotatedElement; |
+import java.lang.reflect.Method; |
+import java.util.ArrayList; |
+import java.util.HashSet; |
+import java.util.List; |
+import java.util.Set; |
+ |
+/** |
+ * Annotations and utilities for testing code dependent on policies. |
+ * |
+ * Usage example: |
+ * <pre> |
+ * @Policies.Add({ |
+ * @Policies.Item(key="Foo", string="Bar"), |
+ * @Policies.Item(key="Baz", stringArray={"Baz"}) |
+ * }) |
+ * public class MyTestClass extends BaseActivityInstrumentationTestCase<ContentActivity> { |
+ * |
+ * public void MyTest1() { |
+ * // Will run the Foo and Bar policies set |
+ * } |
+ * |
+ * @Policies.Remove(@Policies.Item(key="Baz")) |
+ * public void MyTest2() { |
+ * // Will run with only the Foo policy set |
+ * } |
+ * } |
+ * </pre> |
+ */ |
+public final class Policies { |
+ /** Items declared here will be added to the list of used policies. */ |
+ @Inherited |
+ @Retention(RetentionPolicy.RUNTIME) |
+ @Target({ElementType.METHOD, ElementType.TYPE}) |
+ public @interface Add { |
+ Item[] value(); |
+ } |
+ |
+ /** Items declared here will be removed from the list of used policies. */ |
+ @Inherited |
+ @Retention(RetentionPolicy.RUNTIME) |
+ @Target({ElementType.METHOD, ElementType.TYPE}) |
+ public @interface Remove { |
+ Item[] value(); |
+ } |
+ |
+ /** |
+ * Individual policy item. Identified by a {@link #key}, and optional data values. |
+ * At most one value argument (e.g. {@link #string()}, {@link #stringArray()}) can be used. A |
+ * test failure will be caused otherwise. |
+ */ |
+ @Inherited |
+ @Retention(RetentionPolicy.RUNTIME) |
+ @Target({ElementType.METHOD, ElementType.TYPE}) |
+ public @interface Item { |
+ String key(); |
+ |
+ String string() default ""; |
Bernhard Bauer
2015/11/06 10:25:34
Could you use null as the default value?
dgn
2015/11/06 16:07:08
I tried, but that's not allowed: "The value for an
Bernhard Bauer
2015/11/06 16:17:59
Ugh, Java. The language that allows assigning a va
|
+ |
+ String[] stringArray() default {}; |
+ } |
+ |
+ /** Parses the annotations to extract usable information as {@link PolicyData} objects. */ |
+ private static List<PolicyData> fromItems(Item[] items) { |
+ List<PolicyData> result = new ArrayList<>(); |
+ for (Item item : items) { |
+ PolicyData data = null; |
+ |
+ if (!item.string().isEmpty()) { |
+ Assert.assertNull("There can be at most one type of value for the policy", data); |
+ data = new PolicyData.Str(item.key(), item.string()); |
+ } |
+ |
+ if (item.stringArray().length != 0) { |
+ Assert.assertNull("There can be at most one type of value for the policy", data); |
+ data = new PolicyData.StrArray(item.key(), item.stringArray()); |
+ } |
+ |
+ if (data == null) data = new PolicyData.Undefined(item.key()); |
Bernhard Bauer
2015/11/06 10:25:35
What is the Undefined item going to do? Couldn't w
dgn
2015/11/06 16:07:08
It's not going to do anything when transforming it
Bernhard Bauer
2015/11/06 16:17:59
Oh, I see. Hm, would it then ever actually happen
dgn
2015/11/06 17:27:36
You're right, it should not. Replaced the noop wit
|
+ result.add(data); |
+ } |
+ return result; |
+ } |
+ |
+ /** @see PreTestHook */ |
+ public static PreTestHook getRegistrationHook() { |
+ return new RegistrationHook(); |
+ } |
+ |
+ private static Set<PolicyData> getPolicies(AnnotatedElement element) { |
+ AnnotatedElement parent = (element instanceof Method) |
+ ? ((Method) element).getDeclaringClass() |
+ : ((Class<?>) element).getSuperclass(); |
+ Set<PolicyData> flags = (parent == null) ? new HashSet<PolicyData>() : getPolicies(parent); |
+ |
+ if (element.isAnnotationPresent(Policies.Add.class)) { |
+ flags.addAll(fromItems(element.getAnnotation(Policies.Add.class).value())); |
+ } |
+ |
+ if (element.isAnnotationPresent(Policies.Remove.class)) { |
+ flags.removeAll(fromItems(element.getAnnotation(Policies.Remove.class).value())); |
+ } |
+ |
+ return flags; |
+ } |
+ |
+ /** |
+ * Registration hook for the {@link Policies} annotation family. Before a test, will parse |
+ * the declared policies and use them as cached policies. |
+ */ |
+ public static class RegistrationHook implements PreTestHook { |
+ @Override |
+ public void run(Context targetContext, Method testMethod) { |
+ final Bundle policyBundle = PolicyData.asBundle(getPolicies(testMethod)); |
+ AbstractAppRestrictionsProvider.setTestRestrictions(policyBundle); |
+ } |
+ } |
+} |