# HG changeset patch
# User Ted Mielczarek <ted@mielczarek.org>
# Date 1516205959 18000
# Node ID 02e71426ed3e13eecc04ba8184c18b398dca3f67
# Parent  c1d6bc7887c3d0311ec0e8b3a1de1856188e23fe
bug 1255485 - add some tests for building programs in dist/bin. r=nalexander

MozReview-Commit-ID: 94uOsInnWmT

diff --git a/python/mozbuild/mozbuild/test/backend/common.py b/python/mozbuild/mozbuild/test/backend/common.py
--- a/python/mozbuild/mozbuild/test/backend/common.py
+++ b/python/mozbuild/mozbuild/test/backend/common.py
@@ -192,16 +192,24 @@ CONFIGS = defaultdict(lambda: {
         'defines': {},
         'non_global_defines': [],
         'substs': {
             'COMPILE_ENVIRONMENT': '1',
             'LIB_SUFFIX': '.a',
             'BIN_SUFFIX': '',
         },
     },
+    'program-paths': {
+        'defines': {},
+        'non_global_defines': [],
+        'substs': {
+            'COMPILE_ENVIRONMENT': '1',
+            'BIN_SUFFIX': '.prog',
+        },
+    },
 })
 
 
 class BackendTester(unittest.TestCase):
     def setUp(self):
         self._old_env = dict(os.environ)
         os.environ.pop('MOZ_OBJDIR', None)
 
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-bin/moz.build
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+Program('dist-bin')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/dist-subdir/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_SUBDIR = 'foo'
+Program('dist-subdir')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/final-target/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = 'final/target'
+Program('final-target')
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/moz.build
@@ -0,0 +1,13 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Program(name):
+    PROGRAM = name
+
+DIRS += [
+    'dist-bin',
+    'dist-subdir',
+    'final-target',
+    'not-installed',
+]
diff --git a/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build b/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/backend/data/program-paths/not-installed/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_INSTALL = False
+Program('not-installed')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
+++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py
@@ -1021,11 +1021,30 @@ class TestRecursiveMakeBackend(BackendTe
         # Only mochitest.js should be in the install manifest.
         self.assertTrue('testing/mochitest/tests/mochitest.js' in m)
 
         # The path is odd here because we do not normalize at test manifest
         # processing time.  This is a fragile test because there's currently no
         # way to iterate the manifest.
         self.assertFalse('instrumentation/./not_packaged.java' in m)
 
+    def test_program_paths(self):
+        """PROGRAMs with various moz.build settings that change the destination should produce
+        the expected paths in backend.mk."""
+        env = self._consume('program-paths', RecursiveMakeBackend)
+
+        expected = [
+            ('dist-bin', '$(DEPTH)/dist/bin/dist-bin.prog'),
+            ('dist-subdir', '$(DEPTH)/dist/bin/foo/dist-subdir.prog'),
+            ('final-target', '$(DEPTH)/final/target/final-target.prog'),
+            ('not-installed', 'not-installed.prog'),
+        ]
+        prefix = 'PROGRAM = '
+        for (subdir, expected_program) in expected:
+            with open(os.path.join(env.topobjdir, subdir, 'backend.mk'), 'rb') as fh:
+                lines = fh.readlines()
+                program = [line.rstrip().split(prefix, 1)[1] for line in lines
+                           if line.startswith(prefix)][0]
+                self.assertEqual(program, expected_program)
+
 
 if __name__ == '__main__':
     main()
diff --git a/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-bin/moz.build b/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-bin/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-bin/moz.build
@@ -0,0 +1,4 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+Program('dist-bin')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-subdir/moz.build b/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-subdir/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/program-paths/dist-subdir/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_SUBDIR = 'foo'
+Program('dist-subdir')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/frontend/data/program-paths/final-target/moz.build b/python/mozbuild/mozbuild/test/frontend/data/program-paths/final-target/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/program-paths/final-target/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+FINAL_TARGET = 'final/target'
+Program('final-target')
diff --git a/python/mozbuild/mozbuild/test/frontend/data/program-paths/moz.build b/python/mozbuild/mozbuild/test/frontend/data/program-paths/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/program-paths/moz.build
@@ -0,0 +1,13 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+@template
+def Program(name):
+    PROGRAM = name
+
+DIRS += [
+    'dist-bin',
+    'dist-subdir',
+    'final-target',
+    'not-installed',
+]
diff --git a/python/mozbuild/mozbuild/test/frontend/data/program-paths/not-installed/moz.build b/python/mozbuild/mozbuild/test/frontend/data/program-paths/not-installed/moz.build
new file mode 100644
--- /dev/null
+++ b/python/mozbuild/mozbuild/test/frontend/data/program-paths/not-installed/moz.build
@@ -0,0 +1,5 @@
+# Any copyright is dedicated to the Public Domain.
+# http://creativecommons.org/publicdomain/zero/1.0/
+
+DIST_INSTALL = False
+Program('not-installed')
\ No newline at end of file
diff --git a/python/mozbuild/mozbuild/test/frontend/test_emitter.py b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -658,16 +658,29 @@ class TestEmitterBasic(unittest.TestCase
                          [mozpath.join(reader.config.topobjdir,
                                        'test_program1.%s' %
                                        reader.config.substs['OBJ_SUFFIX'])])
         self.assertEqual(objs[5].objs,
                          [mozpath.join(reader.config.topobjdir,
                                        'test_program2.%s' %
                                        reader.config.substs['OBJ_SUFFIX'])])
 
+    def test_program_paths(self):
+        """Various moz.build settings that change the destination of PROGRAM should be
+        accurately reflected in Program.output_path."""
+        reader = self.reader('program-paths')
+        objs = self.read_topsrcdir(reader)
+        prog_paths = [o.output_path for o in objs if isinstance(o, Program)]
+        self.assertEqual(prog_paths, [
+            '!/dist/bin/dist-bin.prog',
+            '!/dist/bin/foo/dist-subdir.prog',
+            '!/final/target/final-target.prog',
+            '!not-installed.prog',
+        ])
+
     def test_test_manifest_missing_manifest(self):
         """A missing manifest file should result in an error."""
         reader = self.reader('test-manifest-missing-manifest')
 
         with self.assertRaisesRegexp(BuildReaderError, 'IOError: Missing files'):
             self.read_topsrcdir(reader)
 
     def test_empty_test_manifest_rejected(self):
