1283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org#!/usr/bin/env python
2283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
314821d9ce557f087f24d0016c2a5b9b7278b8560thakis@chromium.org# Copyright (c) 2012 Google Inc. All rights reserved.
4283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org# Use of this source code is governed by a BSD-style license that can be
5283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org# found in the LICENSE file.
6283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
7283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org"""
8283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.orgVerifies that app bundles are built correctly.
9283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org"""
10283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
11283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.orgimport TestGyp
12a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.orgimport TestMac
13283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
14c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.orgimport os
15203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.orgimport plistlib
16203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.orgimport subprocess
17283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.orgimport sys
18283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
19203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org
20203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.orgdef ExpectEq(expected, actual):
21203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org  if expected != actual:
22203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    print >>sys.stderr, 'Expected "%s", got "%s"' % (expected, actual)
23203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    test.fail_test()
24c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org
25c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.orgdef ls(path):
26c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  '''Returns a list of all files in a directory, relative to the directory.'''
27c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  result = []
28c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  for dirpath, _, files in os.walk(path):
29c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org    for f in files:
30c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org      result.append(os.path.join(dirpath, f)[len(path) + 1:])
31c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  return result
32c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org
33c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org
34283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.orgif sys.platform == 'darwin':
3514821d9ce557f087f24d0016c2a5b9b7278b8560thakis@chromium.org  test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode'])
36283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
37283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  test.run_gyp('test.gyp', chdir='app-bundle')
38283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
39283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  test.build('test.gyp', test.ALL, chdir='app-bundle')
40283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
41283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  # Binary
429a4bc857d95712446f5f71418e975e08c7b542e7thakis@chromium.org  test.built_file_must_exist('Test App Gyp.app/Contents/MacOS/Test App Gyp',
43283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org                             chdir='app-bundle')
44283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
45283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  # Info.plist
466377b5422801f251819bfcf4761e60a6391a8522thakis@chromium.org  info_plist = test.built_file_path('Test App Gyp.app/Contents/Info.plist',
476377b5422801f251819bfcf4761e60a6391a8522thakis@chromium.org                                    chdir='app-bundle')
486377b5422801f251819bfcf4761e60a6391a8522thakis@chromium.org  test.must_exist(info_plist)
49a40f2e5ced62fc42e03916641f30841de2ae05cbthakis@chromium.org  test.must_contain(info_plist, 'com.google.Test-App-Gyp')  # Variable expansion
504eace4f5d8a1f4cdfc2fb1c9452f735926390557thakis@chromium.org  test.must_not_contain(info_plist, '${MACOSX_DEPLOYMENT_TARGET}');
51283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
52203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org  if test.format != 'make':
53203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    # TODO: Synthesized plist entries aren't hooked up in the make generator.
54a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    machine = subprocess.check_output(['sw_vers', '-buildVersion']).rstrip('\n')
55203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    plist = plistlib.readPlist(info_plist)
56a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    ExpectEq(machine, plist['BuildMachineOSBuild'])
57ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org
58ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org    # Prior to Xcode 5.0.0, SDKROOT (and thus DTSDKName) was only defined if
59ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org    # set in the Xcode project file. Starting with that version, it is always
60ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org    # defined.
61ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org    expected = ''
62a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    if TestMac.Xcode.Version() >= '0500':
63a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org      version = TestMac.Xcode.SDKVersion()
64ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org      expected = 'macosx' + version
65ebde26be3915c0c7baf9029b8b2e667b0ce3675dsdefresne@chromium.org    ExpectEq(expected, plist['DTSDKName'])
66a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    sdkbuild = TestMac.Xcode.SDKBuild()
67203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    if not sdkbuild:
68203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org      # Above command doesn't work in Xcode 4.2.
69203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org      sdkbuild = plist['BuildMachineOSBuild']
70203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org    ExpectEq(sdkbuild, plist['DTSDKBuild'])
71a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    ExpectEq(TestMac.Xcode.Version(), plist['DTXcode'])
72a1cecb7b8d5c92a6655e851f7e794cc17dd3bb5dsdefresne@chromium.org    ExpectEq(TestMac.Xcode.Build(), plist['DTXcodeBuild'])
73203dfad2aa74a389c60017250fc70cd5b07cff23thakis@chromium.org
74283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  # Resources
75ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org  strings_files = ['InfoPlist.strings', 'utf-16be.strings', 'utf-16le.strings']
76ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org  for f in strings_files:
77ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org    strings = test.built_file_path(
78ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org        os.path.join('Test App Gyp.app/Contents/Resources/English.lproj', f),
79ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org        chdir='app-bundle')
80ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org    test.must_exist(strings)
81ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org    # Xcodes writes UTF-16LE with BOM.
82ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org    contents = open(strings, 'rb').read()
83ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org    if not contents.startswith('\xff\xfe' + '/* Localized'.encode('utf-16le')):
84ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org      test.fail_test()
853a479acaceb2157d3fe729db731a353608914731thakis@chromium.org
86283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  test.built_file_must_exist(
879a4bc857d95712446f5f71418e975e08c7b542e7thakis@chromium.org      'Test App Gyp.app/Contents/Resources/English.lproj/MainMenu.nib',
88283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org      chdir='app-bundle')
89283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
90283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  # Packaging
919a4bc857d95712446f5f71418e975e08c7b542e7thakis@chromium.org  test.built_file_must_exist('Test App Gyp.app/Contents/PkgInfo',
92283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org                             chdir='app-bundle')
93e3a8d23a80e1d777c9d2beb1f75d0e4f4dbd2715thakis@chromium.org  test.built_file_must_match('Test App Gyp.app/Contents/PkgInfo', 'APPLause',
94e3a8d23a80e1d777c9d2beb1f75d0e4f4dbd2715thakis@chromium.org                             chdir='app-bundle')
95e3a8d23a80e1d777c9d2beb1f75d0e4f4dbd2715thakis@chromium.org
96c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  # Check that no other files get added to the bundle.
97c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org  if set(ls(test.built_file_path('Test App Gyp.app', chdir='app-bundle'))) != \
98c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org     set(['Contents/MacOS/Test App Gyp',
99c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org          'Contents/Info.plist',
100c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org          'Contents/Resources/English.lproj/MainMenu.nib',
101c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org          'Contents/PkgInfo',
102ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org          ] +
103ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org         [os.path.join('Contents/Resources/English.lproj', f)
104ca650e4f12ca7f8384534fba090bfde8a736dd6bthakis@chromium.org             for f in strings_files]):
105c72d7889b27045b85b56ec572c8064f51a8ec6f6thakis@chromium.org    test.fail_test()
106283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org
107283c650658850e499b64d9d4b9b0b383fbfe50e0thakis@chromium.org  test.pass_test()
108