Add presubmit for Java against *ForTesting in production

For (Objective-)C++, there is
_CheckNoProductionCodeUsingTestOnlyFunctions in //PRESUBMIT.py which
can detect when a method with a ForTesting suffix is referenced in
production code.

This bug tracks adding such similar presubmit check for production
.java files, which are approximated as .java files with no "test"
or "junit" in the path and filename.

The check is a modified copy of the one for C++. It does not attempt
to share code with the C++ check, because some details are simpler for
Java (e.g., no need to consider *_for_testing as well). The check is
just a presubmit prompt, not error, because there are false positives
to be expected.

Bug: 821981
Change-Id: I3bb137197070ac696fbe0fd35d50abbfb823a8d8
Reviewed-on: https://chromium-review.googlesource.com/977581
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: agrieve <[email protected]>
Reviewed-by: Bernhard Bauer <[email protected]>
Commit-Queue: Vaclav Brozek <[email protected]>
Cr-Commit-Position: refs/heads/master@{#546063}
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py
index eba421c0..886d802 100755
--- a/PRESUBMIT_test.py
+++ b/PRESUBMIT_test.py
@@ -1591,5 +1591,52 @@
     self.assertEqual(0, len(results))
 
 
+class NoProductionJavaCodeUsingTestOnlyFunctions(unittest.TestCase):
+  def testTruePositives(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('dir/java/src/foo.java', ['FooForTesting();']),
+      MockFile('dir/java/src/bar.java', ['FooForTests(x);']),
+      MockFile('dir/java/src/baz.java', ['FooForTest(','y',');']),
+      MockFile('dir/java/src/mult.java', [
+        'int x = SomethingLongHere()',
+        '    * SomethingLongHereForTesting();'
+      ]),
+    ]
+
+    results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(1, len(results))
+    self.assertEqual(4, len(results[0].items))
+    self.assertTrue('foo.java' in results[0].items[0])
+    self.assertTrue('bar.java' in results[0].items[1])
+    self.assertTrue('baz.java' in results[0].items[2])
+    self.assertTrue('mult.java' in results[0].items[3])
+
+  def testFalsePositives(self):
+    mock_input_api = MockInputApi()
+    mock_input_api.files = [
+      MockFile('dir/java/src/foo.xml', ['FooForTesting();']),
+      MockFile('dir/java/src/foo.java', ['FooForTests() {']),
+      MockFile('dir/java/src/bar.java', ['// FooForTest();']),
+      MockFile('dir/java/src/bar2.java', ['x = 1; // FooForTest();']),
+      MockFile('dir/javatests/src/baz.java', ['FooForTest(','y',');']),
+      MockFile('dir/junit/src/baz.java', ['FooForTest(','y',');']),
+      MockFile('dir/junit/src/javadoc.java', [
+        '/** Use FooForTest(); to obtain foo in tests.'
+        ' */'
+      ]),
+      MockFile('dir/junit/src/javadoc2.java', [
+        '/** ',
+        ' * Use FooForTest(); to obtain foo in tests.'
+        ' */'
+      ]),
+    ]
+
+    results = PRESUBMIT._CheckNoProductionCodeUsingTestOnlyFunctionsJava(
+        mock_input_api, MockOutputApi())
+    self.assertEqual(0, len(results))
+
+
 if __name__ == '__main__':
   unittest.main()