summaryrefslogtreecommitdiffstats
path: root/xpcom/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/tests/unit')
-rw-r--r--xpcom/tests/unit/bug725015.manifest3
-rw-r--r--xpcom/tests/unit/compmgr_warnings.manifest9
-rw-r--r--xpcom/tests/unit/data/SmallApp.app/Contents/Info.plist26
-rwxr-xr-xxpcom/tests/unit/data/SmallApp.app/Contents/MacOS/SmallAppbin0 -> 37988 bytes
-rw-r--r--xpcom/tests/unit/data/SmallApp.app/Contents/PkgInfo1
-rw-r--r--xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/InfoPlist.stringsbin0 -> 92 bytes
-rw-r--r--xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/designable.nib343
-rw-r--r--xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 3356 bytes
-rw-r--r--xpcom/tests/unit/data/bug121341-2.properties9
-rw-r--r--xpcom/tests/unit/data/bug121341.properties68
-rw-r--r--xpcom/tests/unit/data/child_process_directive_service.js21
-rw-r--r--xpcom/tests/unit/data/iniparser01-utf16leBOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser01-utf8BOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser01.ini0
-rw-r--r--xpcom/tests/unit/data/iniparser02-utf16leBOM.inibin0 -> 6 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser02-utf8BOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser02.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser03-utf16leBOM.inibin0 -> 10 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser03-utf8BOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser03.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser04-utf16leBOM.inibin0 -> 26 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser04-utf8BOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser04.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser05-utf16leBOM.inibin0 -> 34 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser05-utf8BOM.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser05.ini1
-rw-r--r--xpcom/tests/unit/data/iniparser06-utf16leBOM.inibin0 -> 30 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser06-utf8BOM.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser06.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser07-utf16leBOM.inibin0 -> 40 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser07-utf8BOM.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser07.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser08-utf16leBOM.inibin0 -> 42 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser08-utf8BOM.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser08.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser09-utf16leBOM.inibin0 -> 54 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser09-utf8BOM.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser09.ini2
-rw-r--r--xpcom/tests/unit/data/iniparser10-utf16leBOM.inibin0 -> 58 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser10-utf8BOM.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser10.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser11-utf16leBOM.inibin0 -> 76 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser11-utf8BOM.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser11.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser12-utf16leBOM.inibin0 -> 86 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser12-utf8BOM.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser12.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser13-utf16leBOM.inibin0 -> 94 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser13-utf8BOM.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser13.ini3
-rw-r--r--xpcom/tests/unit/data/iniparser14-utf16leBOM.inibin0 -> 160 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser14-utf8BOM.ini6
-rw-r--r--xpcom/tests/unit/data/iniparser14.ini6
-rw-r--r--xpcom/tests/unit/data/iniparser15-utf16leBOM.inibin0 -> 162 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser15-utf8BOM.ini6
-rw-r--r--xpcom/tests/unit/data/iniparser15.ini6
-rw-r--r--xpcom/tests/unit/data/iniparser16-utf16leBOM.inibin0 -> 210 bytes
-rw-r--r--xpcom/tests/unit/data/iniparser16-utf8BOM.ini13
-rw-r--r--xpcom/tests/unit/data/iniparser16.ini13
-rw-r--r--xpcom/tests/unit/data/main_process_directive_service.js21
-rw-r--r--xpcom/tests/unit/data/presentation.key/.typeAttributes.dict0
-rw-r--r--xpcom/tests/unit/data/presentation.key/Contents/PkgInfo1
-rw-r--r--xpcom/tests/unit/data/presentation.key/index.apxl.gzbin0 -> 83487 bytes
-rw-r--r--xpcom/tests/unit/data/presentation.key/thumbs/st0.tiffbin0 -> 16654 bytes
-rw-r--r--xpcom/tests/unit/data/process_directive.manifest5
-rw-r--r--xpcom/tests/unit/head_xpcom.js21
-rw-r--r--xpcom/tests/unit/test_bug121341.js71
-rw-r--r--xpcom/tests/unit/test_bug325418.js63
-rw-r--r--xpcom/tests/unit/test_bug332389.js19
-rw-r--r--xpcom/tests/unit/test_bug333505.js10
-rw-r--r--xpcom/tests/unit/test_bug364285-1.js51
-rw-r--r--xpcom/tests/unit/test_bug374754.js59
-rw-r--r--xpcom/tests/unit/test_bug476919.js27
-rw-r--r--xpcom/tests/unit/test_bug478086.js24
-rw-r--r--xpcom/tests/unit/test_bug656331.js39
-rw-r--r--xpcom/tests/unit/test_bug725015.js39
-rw-r--r--xpcom/tests/unit/test_bug745466.js6
-rw-r--r--xpcom/tests/unit/test_comp_no_aslr.js18
-rw-r--r--xpcom/tests/unit/test_compmgr_warnings.js71
-rw-r--r--xpcom/tests/unit/test_debugger_malloc_size_of.js34
-rw-r--r--xpcom/tests/unit/test_file_createUnique.js29
-rw-r--r--xpcom/tests/unit/test_file_equality.js43
-rw-r--r--xpcom/tests/unit/test_file_renameTo.js61
-rw-r--r--xpcom/tests/unit/test_hidden_files.js28
-rw-r--r--xpcom/tests/unit/test_home.js24
-rw-r--r--xpcom/tests/unit/test_iniProcessor.js288
-rw-r--r--xpcom/tests/unit/test_ioutil.js33
-rw-r--r--xpcom/tests/unit/test_localfile.js151
-rw-r--r--xpcom/tests/unit/test_mac_bundle.js18
-rw-r--r--xpcom/tests/unit/test_notxpcom_scriptable.js86
-rw-r--r--xpcom/tests/unit/test_nsIMutableArray.js184
-rw-r--r--xpcom/tests/unit/test_nsIProcess.js185
-rw-r--r--xpcom/tests/unit/test_nsIProcess_stress.js27
-rw-r--r--xpcom/tests/unit/test_pipe.js63
-rw-r--r--xpcom/tests/unit/test_process_directives.js25
-rw-r--r--xpcom/tests/unit/test_process_directives_child.js3
-rw-r--r--xpcom/tests/unit/test_seek_multiplex.js173
-rw-r--r--xpcom/tests/unit/test_storagestream.js162
-rw-r--r--xpcom/tests/unit/test_streams.js157
-rw-r--r--xpcom/tests/unit/test_stringstream.js23
-rw-r--r--xpcom/tests/unit/test_symlinks.js144
-rw-r--r--xpcom/tests/unit/test_systemInfo.js20
-rw-r--r--xpcom/tests/unit/test_versioncomparator.js59
-rw-r--r--xpcom/tests/unit/test_windows_cmdline_file.js21
-rw-r--r--xpcom/tests/unit/test_windows_registry.js205
-rw-r--r--xpcom/tests/unit/test_windows_shortcut.js279
-rw-r--r--xpcom/tests/unit/xpcomtest.manifest1
-rw-r--r--xpcom/tests/unit/xpcshell.ini79
108 files changed, 3730 insertions, 0 deletions
diff --git a/xpcom/tests/unit/bug725015.manifest b/xpcom/tests/unit/bug725015.manifest
new file mode 100644
index 000000000..2f432f0b2
--- /dev/null
+++ b/xpcom/tests/unit/bug725015.manifest
@@ -0,0 +1,3 @@
+category bug725015-test-category bug725015-category-entry @bug725015.test.contract
+component {05070380-6e6e-42ba-aaa5-3289fc55ca5a} dummyfile.js
+contract @bug725015.test.contract {05070380-6e6e-42ba-aaa5-3289fc55ca5a}
diff --git a/xpcom/tests/unit/compmgr_warnings.manifest b/xpcom/tests/unit/compmgr_warnings.manifest
new file mode 100644
index 000000000..6b60990db
--- /dev/null
+++ b/xpcom/tests/unit/compmgr_warnings.manifest
@@ -0,0 +1,9 @@
+# The following line is malformed (mismatched braces)
+component {94b346d7-0cde-4e6e-b819-95d6f200bbf6 MyComponent.js
+
+component 94b346d7-0cde-4e6e-b819-95d6f200bbf7 MyComponent.js
+# The following line re-registers an existing CID
+component {94b346d7-0cde-4e6e-b819-95d6f200bbf7} MyOtherComponent.js
+
+# The following line maps a contractID to a non-existent CID
+contract @testing/foo {0c07730f-f875-436b-8deb-90c4251920ec}
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/Info.plist b/xpcom/tests/unit/data/SmallApp.app/Contents/Info.plist
new file mode 100644
index 000000000..8388fa2a5
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>SmallApp</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.SmallApp</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>SmallApp</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/MacOS/SmallApp b/xpcom/tests/unit/data/SmallApp.app/Contents/MacOS/SmallApp
new file mode 100755
index 000000000..c821003d3
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/MacOS/SmallApp
Binary files differ
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/PkgInfo b/xpcom/tests/unit/data/SmallApp.app/Contents/PkgInfo
new file mode 100644
index 000000000..bd04210fb
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/PkgInfo
@@ -0,0 +1 @@
+APPL???? \ No newline at end of file
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/InfoPlist.strings b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/InfoPlist.strings
new file mode 100644
index 000000000..5e45963c3
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/designable.nib b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/designable.nib
new file mode 100644
index 000000000..59f8803c5
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/designable.nib
@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.02">
+ <data>
+ <int key="IBDocument.SystemTarget">0</int>
+ <string key="IBDocument.SystemVersion">9E17</string>
+ <string key="IBDocument.InterfaceBuilderVersion">644</string>
+ <string key="IBDocument.AppKitVersion">949.33</string>
+ <string key="IBDocument.HIToolboxVersion">352.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="29"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1048">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomObject" id="1021">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSCustomObject" id="1014">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="1050">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSMenu" id="649796088">
+ <string key="NSTitle">AMainMenu</string>
+ <object class="NSMutableArray" key="NSMenuItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMenuItem" id="694149608">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">NewApplication</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <object class="NSCustomResource" key="NSOnImage" id="35465992">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="591987212">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="110575045">
+ <string key="NSTitle">NewApplication</string>
+ <object class="NSMutableArray" key="NSMenuItems">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMenuItem" id="632727374">
+ <reference key="NSMenu" ref="110575045"/>
+ <string key="NSTitle">Quit NewApplication</string>
+ <string key="NSKeyEquiv">q</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ </object>
+ <string key="NSName">_NSAppleMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="379814623">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">File</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ <object class="NSMenuItem" id="952259628">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Edit</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ <object class="NSMenuItem" id="626404410">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Format</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ <object class="NSMenuItem" id="586577488">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">View</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ <object class="NSMenuItem" id="713487014">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Window</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ <object class="NSMenuItem" id="391199113">
+ <reference key="NSMenu" ref="649796088"/>
+ <string key="NSTitle">Help</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="35465992"/>
+ <reference key="NSMixedImage" ref="591987212"/>
+ </object>
+ </object>
+ <string key="NSName">_NSMainMenu</string>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">terminate:</string>
+ <reference key="source" ref="1014"/>
+ <reference key="destination" ref="632727374"/>
+ </object>
+ <int key="connectionID">369</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="1049">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1048"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="1021"/>
+ <reference key="parent" ref="1049"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="1014"/>
+ <reference key="parent" ref="1049"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="1050"/>
+ <reference key="parent" ref="1049"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">29</int>
+ <reference key="object" ref="649796088"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="713487014"/>
+ <reference ref="694149608"/>
+ <reference ref="391199113"/>
+ <reference ref="952259628"/>
+ <reference ref="379814623"/>
+ <reference ref="586577488"/>
+ <reference ref="626404410"/>
+ </object>
+ <reference key="parent" ref="1049"/>
+ <string key="objectName">MainMenu</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="713487014"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="694149608"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="110575045"/>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">103</int>
+ <reference key="object" ref="391199113"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ <string key="objectName">1</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">217</int>
+ <reference key="object" ref="952259628"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">83</int>
+ <reference key="object" ref="379814623"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="110575045"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="632727374"/>
+ </object>
+ <reference key="parent" ref="694149608"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">136</int>
+ <reference key="object" ref="632727374"/>
+ <reference key="parent" ref="110575045"/>
+ <string key="objectName">1111</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">295</int>
+ <reference key="object" ref="586577488"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">299</int>
+ <reference key="object" ref="626404410"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="parent" ref="649796088"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.IBPluginDependency</string>
+ <string>-2.IBPluginDependency</string>
+ <string>-3.IBPluginDependency</string>
+ <string>103.IBPluginDependency</string>
+ <string>103.ImportedFromIB2</string>
+ <string>136.IBPluginDependency</string>
+ <string>136.ImportedFromIB2</string>
+ <string>19.IBPluginDependency</string>
+ <string>19.ImportedFromIB2</string>
+ <string>217.IBPluginDependency</string>
+ <string>217.ImportedFromIB2</string>
+ <string>29.IBEditorWindowLastContentRect</string>
+ <string>29.IBPluginDependency</string>
+ <string>29.ImportedFromIB2</string>
+ <string>29.WindowOrigin</string>
+ <string>29.editorWindowContentRectSynchronizationRect</string>
+ <string>295.IBPluginDependency</string>
+ <string>299.IBPluginDependency</string>
+ <string>56.IBPluginDependency</string>
+ <string>56.ImportedFromIB2</string>
+ <string>57.IBEditorWindowLastContentRect</string>
+ <string>57.IBPluginDependency</string>
+ <string>57.ImportedFromIB2</string>
+ <string>57.editorWindowContentRectSynchronizationRect</string>
+ <string>83.IBPluginDependency</string>
+ <string>83.ImportedFromIB2</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilderKit</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <integer value="1" id="9"/>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>{{0, 975}, {478, 20}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>{74, 862}</string>
+ <string>{{6, 978}, {478, 20}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>{{12, 952}, {218, 23}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ <string>{{23, 794}, {245, 183}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="9"/>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">374</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes"/>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">../SmallApp.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
diff --git a/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 000000000..bb27d4a5d
--- /dev/null
+++ b/xpcom/tests/unit/data/SmallApp.app/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/xpcom/tests/unit/data/bug121341-2.properties b/xpcom/tests/unit/data/bug121341-2.properties
new file mode 100644
index 000000000..f7885e4fc
--- /dev/null
+++ b/xpcom/tests/unit/data/bug121341-2.properties
@@ -0,0 +1,9 @@
+# this file contains invalid UTF-8 sequence
+# no property should be loaded
+
+1 = test
+
+# property with invalid UTF-8 sequence (0xa0)
+2 = ab
+
+3 = test2
diff --git a/xpcom/tests/unit/data/bug121341.properties b/xpcom/tests/unit/data/bug121341.properties
new file mode 100644
index 000000000..b45fc9698
--- /dev/null
+++ b/xpcom/tests/unit/data/bug121341.properties
@@ -0,0 +1,68 @@
+# simple check
+1=abc
+# test whitespace trimming in key and value
+ 2 = xy
+# test parsing of escaped values
+3 = \u1234\t\r\n\uAB\
+\u1\n
+# test multiline properties
+4 = this is \
+multiline property
+5 = this is \
+ another multiline property
+# property with DOS EOL
+6 = test\u0036
+# test multiline property with with DOS EOL
+7 = yet another multi\
+ line propery
+# trimming should not trim escaped whitespaces
+8 = \ttest5\u0020
+# another variant of #8
+9 = \ test6\t
+# test UTF-8 encoded property/value
+10aሴb = c췯d
+# next property should test unicode escaping at the boundary of parsing buffer
+# buffer size is expected to be 4096 so add comments to get to this offset
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+################################################################################
+###############################################################################
+11 = \uABCD
diff --git a/xpcom/tests/unit/data/child_process_directive_service.js b/xpcom/tests/unit/data/child_process_directive_service.js
new file mode 100644
index 000000000..9bc1c3206
--- /dev/null
+++ b/xpcom/tests/unit/data/child_process_directive_service.js
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+Components.utils.import("resource:///modules/XPCOMUtils.jsm");
+
+function TestProcessDirective() {}
+TestProcessDirective.prototype = {
+
+ /* Boilerplate */
+ QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupportsString]),
+ contractID: "@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1",
+ classID: Components.ID("{4bd1ba60-45c4-11e4-916c-0800200c9a66}"),
+
+ type: Components.interfaces.nsISupportsString.TYPE_STRING,
+ data: "child process",
+ toString: function() {
+ return this.data;
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestProcessDirective]);
diff --git a/xpcom/tests/unit/data/iniparser01-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser01-utf16leBOM.ini
new file mode 100644
index 000000000..46b134b19
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser01-utf16leBOM.ini
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/xpcom/tests/unit/data/iniparser01-utf8BOM.ini b/xpcom/tests/unit/data/iniparser01-utf8BOM.ini
new file mode 100644
index 000000000..5f282702b
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser01-utf8BOM.ini
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/xpcom/tests/unit/data/iniparser01.ini b/xpcom/tests/unit/data/iniparser01.ini
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser01.ini
diff --git a/xpcom/tests/unit/data/iniparser02-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser02-utf16leBOM.ini
new file mode 100644
index 000000000..49cc8ef0e
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser02-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser02-utf8BOM.ini b/xpcom/tests/unit/data/iniparser02-utf8BOM.ini
new file mode 100644
index 000000000..e02abfc9b
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser02-utf8BOM.ini
@@ -0,0 +1 @@
+
diff --git a/xpcom/tests/unit/data/iniparser02.ini b/xpcom/tests/unit/data/iniparser02.ini
new file mode 100644
index 000000000..d3f5a12fa
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser02.ini
@@ -0,0 +1 @@
+
diff --git a/xpcom/tests/unit/data/iniparser03-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser03-utf16leBOM.ini
new file mode 100644
index 000000000..05255100a
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser03-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser03-utf8BOM.ini b/xpcom/tests/unit/data/iniparser03-utf8BOM.ini
new file mode 100644
index 000000000..b76e44e19
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser03-utf8BOM.ini
@@ -0,0 +1 @@
+[]
diff --git a/xpcom/tests/unit/data/iniparser03.ini b/xpcom/tests/unit/data/iniparser03.ini
new file mode 100644
index 000000000..60b074253
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser03.ini
@@ -0,0 +1 @@
+[]
diff --git a/xpcom/tests/unit/data/iniparser04-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser04-utf16leBOM.ini
new file mode 100644
index 000000000..e95d97113
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser04-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser04-utf8BOM.ini b/xpcom/tests/unit/data/iniparser04-utf8BOM.ini
new file mode 100644
index 000000000..47ef32c0a
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser04-utf8BOM.ini
@@ -0,0 +1 @@
+[section1]
diff --git a/xpcom/tests/unit/data/iniparser04.ini b/xpcom/tests/unit/data/iniparser04.ini
new file mode 100644
index 000000000..23a50d155
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser04.ini
@@ -0,0 +1 @@
+[section1]
diff --git a/xpcom/tests/unit/data/iniparser05-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser05-utf16leBOM.ini
new file mode 100644
index 000000000..a49491816
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser05-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser05-utf8BOM.ini b/xpcom/tests/unit/data/iniparser05-utf8BOM.ini
new file mode 100644
index 000000000..eb33b5ccf
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser05-utf8BOM.ini
@@ -0,0 +1 @@
+[section1]junk
diff --git a/xpcom/tests/unit/data/iniparser05.ini b/xpcom/tests/unit/data/iniparser05.ini
new file mode 100644
index 000000000..ade137337
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser05.ini
@@ -0,0 +1 @@
+[section1]junk
diff --git a/xpcom/tests/unit/data/iniparser06-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser06-utf16leBOM.ini
new file mode 100644
index 000000000..e9023ac7c
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser06-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser06-utf8BOM.ini b/xpcom/tests/unit/data/iniparser06-utf8BOM.ini
new file mode 100644
index 000000000..073d841cf
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser06-utf8BOM.ini
@@ -0,0 +1,2 @@
+[section1]
+
diff --git a/xpcom/tests/unit/data/iniparser06.ini b/xpcom/tests/unit/data/iniparser06.ini
new file mode 100644
index 000000000..c24821e6e
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser06.ini
@@ -0,0 +1,2 @@
+[section1]
+
diff --git a/xpcom/tests/unit/data/iniparser07-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser07-utf16leBOM.ini
new file mode 100644
index 000000000..d1c167e6e
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser07-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser07-utf8BOM.ini b/xpcom/tests/unit/data/iniparser07-utf8BOM.ini
new file mode 100644
index 000000000..38176d944
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser07-utf8BOM.ini
@@ -0,0 +1,2 @@
+[section1]
+name1
diff --git a/xpcom/tests/unit/data/iniparser07.ini b/xpcom/tests/unit/data/iniparser07.ini
new file mode 100644
index 000000000..49816873b
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser07.ini
@@ -0,0 +1,2 @@
+[section1]
+name1
diff --git a/xpcom/tests/unit/data/iniparser08-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser08-utf16leBOM.ini
new file mode 100644
index 000000000..e450566a0
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser08-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser08-utf8BOM.ini b/xpcom/tests/unit/data/iniparser08-utf8BOM.ini
new file mode 100644
index 000000000..5fa7d2495
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser08-utf8BOM.ini
@@ -0,0 +1,2 @@
+[section1]
+name1=
diff --git a/xpcom/tests/unit/data/iniparser08.ini b/xpcom/tests/unit/data/iniparser08.ini
new file mode 100644
index 000000000..cfa15c9ff
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser08.ini
@@ -0,0 +1,2 @@
+[section1]
+name1=
diff --git a/xpcom/tests/unit/data/iniparser09-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser09-utf16leBOM.ini
new file mode 100644
index 000000000..ef1da39e2
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser09-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser09-utf8BOM.ini b/xpcom/tests/unit/data/iniparser09-utf8BOM.ini
new file mode 100644
index 000000000..e3edce4d4
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser09-utf8BOM.ini
@@ -0,0 +1,2 @@
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser09.ini b/xpcom/tests/unit/data/iniparser09.ini
new file mode 100644
index 000000000..1c87762ba
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser09.ini
@@ -0,0 +1,2 @@
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser10-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser10-utf16leBOM.ini
new file mode 100644
index 000000000..e5e70b661
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser10-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser10-utf8BOM.ini b/xpcom/tests/unit/data/iniparser10-utf8BOM.ini
new file mode 100644
index 000000000..bda15fcc7
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser10-utf8BOM.ini
@@ -0,0 +1,3 @@
+
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser10.ini b/xpcom/tests/unit/data/iniparser10.ini
new file mode 100644
index 000000000..037fd7930
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser10.ini
@@ -0,0 +1,3 @@
+
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser11-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser11-utf16leBOM.ini
new file mode 100644
index 000000000..932d4004b
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser11-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser11-utf8BOM.ini b/xpcom/tests/unit/data/iniparser11-utf8BOM.ini
new file mode 100644
index 000000000..78caafaba
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser11-utf8BOM.ini
@@ -0,0 +1,3 @@
+# comment
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser11.ini b/xpcom/tests/unit/data/iniparser11.ini
new file mode 100644
index 000000000..f8d573a28
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser11.ini
@@ -0,0 +1,3 @@
+# comment
+[section1]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser12-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser12-utf16leBOM.ini
new file mode 100644
index 000000000..8a2912722
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser12-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser12-utf8BOM.ini b/xpcom/tests/unit/data/iniparser12-utf8BOM.ini
new file mode 100644
index 000000000..09ca62779
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser12-utf8BOM.ini
@@ -0,0 +1,3 @@
+[section1]
+# [sectionBAD]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser12.ini b/xpcom/tests/unit/data/iniparser12.ini
new file mode 100644
index 000000000..2727940c0
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser12.ini
@@ -0,0 +1,3 @@
+[section1]
+# [sectionBAD]
+name1=value1
diff --git a/xpcom/tests/unit/data/iniparser13-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser13-utf16leBOM.ini
new file mode 100644
index 000000000..ebd9a51d3
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser13-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser13-utf8BOM.ini b/xpcom/tests/unit/data/iniparser13-utf8BOM.ini
new file mode 100644
index 000000000..8c9499b66
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser13-utf8BOM.ini
@@ -0,0 +1,3 @@
+[section1]
+name1=value1
+# nameBAD=valueBAD
diff --git a/xpcom/tests/unit/data/iniparser13.ini b/xpcom/tests/unit/data/iniparser13.ini
new file mode 100644
index 000000000..21d40b140
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser13.ini
@@ -0,0 +1,3 @@
+[section1]
+name1=value1
+# nameBAD=valueBAD
diff --git a/xpcom/tests/unit/data/iniparser14-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser14-utf16leBOM.ini
new file mode 100644
index 000000000..bbc3413aa
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser14-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser14-utf8BOM.ini b/xpcom/tests/unit/data/iniparser14-utf8BOM.ini
new file mode 100644
index 000000000..d109052c8
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser14-utf8BOM.ini
@@ -0,0 +1,6 @@
+[section1]
+name1=value1
+name2=value2
+[section2]
+name1=value1
+name2=foopy
diff --git a/xpcom/tests/unit/data/iniparser14.ini b/xpcom/tests/unit/data/iniparser14.ini
new file mode 100644
index 000000000..744af4cb6
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser14.ini
@@ -0,0 +1,6 @@
+[section1]
+name1=value1
+name2=value2
+[section2]
+name1=value1
+name2=foopy
diff --git a/xpcom/tests/unit/data/iniparser15-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser15-utf16leBOM.ini
new file mode 100644
index 000000000..e60525dec
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser15-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser15-utf8BOM.ini b/xpcom/tests/unit/data/iniparser15-utf8BOM.ini
new file mode 100644
index 000000000..172803f90
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser15-utf8BOM.ini
@@ -0,0 +1,6 @@
+[section1]
+name1=value1
+[section2]
+name1=foopy
+[section1]
+name1=newValue1
diff --git a/xpcom/tests/unit/data/iniparser15.ini b/xpcom/tests/unit/data/iniparser15.ini
new file mode 100644
index 000000000..608a27d8f
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser15.ini
@@ -0,0 +1,6 @@
+[section1]
+name1=value1
+[section2]
+name1=foopy
+[section1]
+name1=newValue1
diff --git a/xpcom/tests/unit/data/iniparser16-utf16leBOM.ini b/xpcom/tests/unit/data/iniparser16-utf16leBOM.ini
new file mode 100644
index 000000000..142b17590
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser16-utf16leBOM.ini
Binary files differ
diff --git a/xpcom/tests/unit/data/iniparser16-utf8BOM.ini b/xpcom/tests/unit/data/iniparser16-utf8BOM.ini
new file mode 100644
index 000000000..bba1018da
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser16-utf8BOM.ini
@@ -0,0 +1,13 @@
+#Ώṍҳϖ·̐˄ȡǨŅ©&
+[☺♫]
+#ѼΏṍҳϖ
+♫=☻
+#·̐˄ȡǨŅ©
+♪=♥
+#‽ἧᵿΏṍҳ
+#ϖ·̐˄ȡǨŅ©&
+[☼]
+♣=♠
+♦=♥
+#‽ἧᵿΏṍҳ
+#·̐˄ȡǨŅ©
diff --git a/xpcom/tests/unit/data/iniparser16.ini b/xpcom/tests/unit/data/iniparser16.ini
new file mode 100644
index 000000000..b94607d15
--- /dev/null
+++ b/xpcom/tests/unit/data/iniparser16.ini
@@ -0,0 +1,13 @@
+#Ώṍҳϖ·̐˄ȡǨŅ©&
+[☺♫]
+#ѼΏṍҳϖ
+♫=☻
+#·̐˄ȡǨŅ©
+♪=♥
+#‽ἧᵿΏṍҳ
+#ϖ·̐˄ȡǨŅ©&
+[☼]
+♣=♠
+♦=♥
+#‽ἧᵿΏṍҳ
+#·̐˄ȡǨŅ©
diff --git a/xpcom/tests/unit/data/main_process_directive_service.js b/xpcom/tests/unit/data/main_process_directive_service.js
new file mode 100644
index 000000000..f4eed11c9
--- /dev/null
+++ b/xpcom/tests/unit/data/main_process_directive_service.js
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+Components.utils.import("resource:///modules/XPCOMUtils.jsm");
+
+function TestProcessDirective() {}
+TestProcessDirective.prototype = {
+
+ /* Boilerplate */
+ QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupportsString]),
+ contractID: "@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1",
+ classID: Components.ID("{9b6f4160-45be-11e4-916c-0800200c9a66}"),
+
+ type: Components.interfaces.nsISupportsString.TYPE_STRING,
+ data: "main process",
+ toString: function() {
+ return this.data;
+ }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TestProcessDirective]);
diff --git a/xpcom/tests/unit/data/presentation.key/.typeAttributes.dict b/xpcom/tests/unit/data/presentation.key/.typeAttributes.dict
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/xpcom/tests/unit/data/presentation.key/.typeAttributes.dict
diff --git a/xpcom/tests/unit/data/presentation.key/Contents/PkgInfo b/xpcom/tests/unit/data/presentation.key/Contents/PkgInfo
new file mode 100644
index 000000000..b0bc8e076
--- /dev/null
+++ b/xpcom/tests/unit/data/presentation.key/Contents/PkgInfo
@@ -0,0 +1 @@
+???????? \ No newline at end of file
diff --git a/xpcom/tests/unit/data/presentation.key/index.apxl.gz b/xpcom/tests/unit/data/presentation.key/index.apxl.gz
new file mode 100644
index 000000000..26178d809
--- /dev/null
+++ b/xpcom/tests/unit/data/presentation.key/index.apxl.gz
Binary files differ
diff --git a/xpcom/tests/unit/data/presentation.key/thumbs/st0.tiff b/xpcom/tests/unit/data/presentation.key/thumbs/st0.tiff
new file mode 100644
index 000000000..8b49316b4
--- /dev/null
+++ b/xpcom/tests/unit/data/presentation.key/thumbs/st0.tiff
Binary files differ
diff --git a/xpcom/tests/unit/data/process_directive.manifest b/xpcom/tests/unit/data/process_directive.manifest
new file mode 100644
index 000000000..9cbf7f241
--- /dev/null
+++ b/xpcom/tests/unit/data/process_directive.manifest
@@ -0,0 +1,5 @@
+component {9b6f4160-45be-11e4-916c-0800200c9a66} main_process_directive_service.js process=main
+contract @mozilla.org/xpcom/tests/MainProcessDirectiveTest;1 {9b6f4160-45be-11e4-916c-0800200c9a66} process=main
+
+component {4bd1ba60-45c4-11e4-916c-0800200c9a66} child_process_directive_service.js process=content
+contract @mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1 {4bd1ba60-45c4-11e4-916c-0800200c9a66} process=content
diff --git a/xpcom/tests/unit/head_xpcom.js b/xpcom/tests/unit/head_xpcom.js
new file mode 100644
index 000000000..eacd5b4e6
--- /dev/null
+++ b/xpcom/tests/unit/head_xpcom.js
@@ -0,0 +1,21 @@
+function get_test_program(prog)
+{
+ var progPath = do_get_cwd();
+ progPath.append(prog);
+ progPath.leafName = progPath.leafName + mozinfo.bin_suffix;
+ return progPath;
+}
+
+function set_process_running_environment()
+{
+ var envSvc = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].
+ getService(Components.interfaces.nsIProperties);
+ var greBinDir = dirSvc.get("GreBinD", Components.interfaces.nsIFile);
+ envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path);
+ // For Linux
+ envSvc.set("LD_LIBRARY_PATH", greBinDir.path);
+ //XXX: handle windows
+}
+
diff --git a/xpcom/tests/unit/test_bug121341.js b/xpcom/tests/unit/test_bug121341.js
new file mode 100644
index 000000000..3aa04186e
--- /dev/null
+++ b/xpcom/tests/unit/test_bug121341.js
@@ -0,0 +1,71 @@
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+Cu.import("resource://gre/modules/NetUtil.jsm");
+
+function run_test() {
+ var ios = Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+
+ var dataFile = do_get_file("data/bug121341.properties");
+ var channel = NetUtil.newChannel({
+ uri: ios.newFileURI(dataFile, null, null),
+ loadUsingSystemPrincipal: true
+ });
+ var inp = channel.open2();
+
+ var properties = Components.classes["@mozilla.org/persistent-properties;1"].
+ createInstance(Components.interfaces.nsIPersistentProperties);
+ properties.load(inp);
+
+ var value;
+
+ value = properties.getStringProperty("1");
+ do_check_eq(value, "abc");
+
+ value = properties.getStringProperty("2");
+ do_check_eq(value, "xy");
+
+ value = properties.getStringProperty("3");
+ do_check_eq(value, "\u1234\t\r\n\u00AB\u0001\n");
+
+ value = properties.getStringProperty("4");
+ do_check_eq(value, "this is multiline property");
+
+ value = properties.getStringProperty("5");
+ do_check_eq(value, "this is another multiline property");
+
+ value = properties.getStringProperty("6");
+ do_check_eq(value, "test\u0036");
+
+ value = properties.getStringProperty("7");
+ do_check_eq(value, "yet another multiline propery");
+
+ value = properties.getStringProperty("8");
+ do_check_eq(value, "\ttest5\u0020");
+
+ value = properties.getStringProperty("9");
+ do_check_eq(value, " test6\t");
+
+ value = properties.getStringProperty("10a\u1234b");
+ do_check_eq(value, "c\uCDEFd");
+
+ value = properties.getStringProperty("11");
+ do_check_eq(value, "\uABCD");
+
+ dataFile = do_get_file("data/bug121341-2.properties");
+
+ var channel = NetUtil.newChannel({
+ uri: ios.newFileURI(dataFile, null, null),
+ loadUsingSystemPrincipal: true
+ });
+ inp = channel.open2();
+
+ var properties2 = Components.classes["@mozilla.org/persistent-properties;1"].
+ createInstance(Components.interfaces.nsIPersistentProperties);
+ try {
+ properties2.load(inp);
+ do_throw("load() didn't fail");
+ }
+ catch (e) {
+ }
+}
diff --git a/xpcom/tests/unit/test_bug325418.js b/xpcom/tests/unit/test_bug325418.js
new file mode 100644
index 000000000..b18866d7e
--- /dev/null
+++ b/xpcom/tests/unit/test_bug325418.js
@@ -0,0 +1,63 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+// 5 seconds.
+const kExpectedDelay1 = 5;
+// 1 second.
+const kExpectedDelay2 = 1;
+
+var gStartTime1;
+var gStartTime2;
+var timer;
+
+var observer1 = {
+ observe: function observeTC1(subject, topic, data) {
+ if (topic == "timer-callback") {
+ // Stop timer, so it doesn't repeat (if test runs slowly).
+ timer.cancel();
+
+ // Actual delay may not be exact, so convert to seconds and round.
+ do_check_eq(Math.round((Date.now() - gStartTime1) / 1000),
+ kExpectedDelay1);
+
+ timer = null;
+
+ do_print("1st timer triggered (before being cancelled). Should not have happened!");
+ do_check_true(false);
+ }
+ }
+};
+
+var observer2 = {
+ observe: function observeTC2(subject, topic, data) {
+ if (topic == "timer-callback") {
+ // Stop timer, so it doesn't repeat (if test runs slowly).
+ timer.cancel();
+
+ // Actual delay may not be exact, so convert to seconds and round.
+ do_check_eq(Math.round((Date.now() - gStartTime2) / 1000),
+ kExpectedDelay2);
+
+ timer = null;
+
+ do_test_finished();
+ }
+ }
+};
+
+function run_test() {
+ do_test_pending();
+
+ timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+
+ // Initialize the timer (with some delay), then cancel it.
+ gStartTime1 = Date.now();
+ timer.init(observer1, kExpectedDelay1 * 1000,
+ timer.TYPE_REPEATING_PRECISE_CAN_SKIP);
+ timer.cancel();
+
+ // Re-initialize the timer (with a different delay).
+ gStartTime2 = Date.now();
+ timer.init(observer2, kExpectedDelay2 * 1000,
+ timer.TYPE_REPEATING_PRECISE_CAN_SKIP);
+}
diff --git a/xpcom/tests/unit/test_bug332389.js b/xpcom/tests/unit/test_bug332389.js
new file mode 100644
index 000000000..91f8943e8
--- /dev/null
+++ b/xpcom/tests/unit/test_bug332389.js
@@ -0,0 +1,19 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function run_test() {
+ var f =
+ Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
+
+ var terminated = false;
+ for (var i = 0; i < 100; i++) {
+ if (f == null) {
+ terminated = true;
+ break;
+ }
+ f = f.parent;
+ }
+
+ do_check_true(terminated);
+}
diff --git a/xpcom/tests/unit/test_bug333505.js b/xpcom/tests/unit/test_bug333505.js
new file mode 100644
index 000000000..856468605
--- /dev/null
+++ b/xpcom/tests/unit/test_bug333505.js
@@ -0,0 +1,10 @@
+function run_test()
+{
+ var dirEntries = do_get_cwd().directoryEntries;
+
+ while (dirEntries.hasMoreElements())
+ dirEntries.getNext();
+
+ // We ensure there is no crash
+ dirEntries.hasMoreElements();
+}
diff --git a/xpcom/tests/unit/test_bug364285-1.js b/xpcom/tests/unit/test_bug364285-1.js
new file mode 100644
index 000000000..f8bd6ee15
--- /dev/null
+++ b/xpcom/tests/unit/test_bug364285-1.js
@@ -0,0 +1,51 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+
+var nameArray = [
+ "ascii", // ASCII
+ "fran\u00E7ais", // Latin-1
+ "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", // Cyrillic
+ "\u65E5\u672C\u8A9E", // Japanese
+ "\u4E2D\u6587", // Chinese
+ "\uD55C\uAD6D\uC5B4", // Korean
+ "\uD801\uDC0F\uD801\uDC2D\uD801\uDC3B\uD801\uDC2B" // Deseret
+];
+
+function getTempDir()
+{
+ var dirService = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties);
+ return dirService.get("TmpD", Ci.nsILocalFile);
+}
+
+function create_file(fileName)
+{
+ var outFile = getTempDir();
+ outFile.append(fileName);
+ outFile.createUnique(outFile.NORMAL_FILE_TYPE, 0o600);
+
+ var stream = Cc["@mozilla.org/network/file-output-stream;1"]
+ .createInstance(Ci.nsIFileOutputStream);
+ stream.init(outFile, 0x02 | 0x08 | 0x20, 0o600, 0);
+ stream.write("foo", 3);
+ stream.close();
+
+ do_check_eq(outFile.leafName.substr(0, fileName.length), fileName);
+
+ return outFile;
+}
+
+function test_create(fileName)
+{
+ var file1 = create_file(fileName);
+ var file2 = create_file(fileName);
+ file1.remove(false);
+ file2.remove(false);
+}
+
+function run_test()
+{
+ for (var i = 0; i < nameArray.length; ++i) {
+ test_create(nameArray[i]);
+ }
+}
diff --git a/xpcom/tests/unit/test_bug374754.js b/xpcom/tests/unit/test_bug374754.js
new file mode 100644
index 000000000..9b0ccf26e
--- /dev/null
+++ b/xpcom/tests/unit/test_bug374754.js
@@ -0,0 +1,59 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+var addedTopic = "xpcom-category-entry-added";
+var removedTopic = "xpcom-category-entry-removed";
+var testCategory = "bug-test-category";
+var testEntry = "@mozilla.org/bug-test-entry;1";
+
+var testValue= "check validity";
+var result = "";
+var expected = "add remove add remove ";
+var timer;
+
+var observer = {
+ QueryInterface: function(iid) {
+ if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIObserver))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ observe: function(subject, topic, data) {
+ if (topic == "timer-callback") {
+ do_check_eq(result, expected);
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ observerService.removeObserver(this, addedTopic);
+ observerService.removeObserver(this, removedTopic);
+
+ do_test_finished();
+
+ timer = null;
+ }
+
+ if (subject.QueryInterface(Ci.nsISupportsCString).data != testEntry || data != testCategory)
+ return;
+
+ if (topic == addedTopic)
+ result += "add ";
+ else if (topic == removedTopic)
+ result += "remove ";
+ }
+};
+
+function run_test() {
+ do_test_pending();
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ observerService.addObserver(observer, addedTopic, false);
+ observerService.addObserver(observer, removedTopic, false);
+
+ var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
+ categoryManager.addCategoryEntry(testCategory, testEntry, testValue, false, true);
+ categoryManager.addCategoryEntry(testCategory, testEntry, testValue, false, true);
+ categoryManager.deleteCategoryEntry(testCategory, testEntry, false);
+
+ timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.init(observer, 0, timer.TYPE_ONE_SHOT);
+}
diff --git a/xpcom/tests/unit/test_bug476919.js b/xpcom/tests/unit/test_bug476919.js
new file mode 100644
index 000000000..21cd9253e
--- /dev/null
+++ b/xpcom/tests/unit/test_bug476919.js
@@ -0,0 +1,27 @@
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function run_test() {
+ // skip this test on Windows
+ if (mozinfo.os != "win") {
+ var testDir = __LOCATION__.parent;
+ // create a test file, then symlink it, then check that we think it's a symlink
+ var targetFile = testDir.clone();
+ targetFile.append("target.txt");
+ if (!targetFile.exists())
+ targetFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+
+ var link = testDir.clone();
+ link.append("link");
+ if (link.exists())
+ link.remove(false);
+
+ var ln = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ ln.initWithPath("/bin/ln");
+ var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
+ process.init(ln);
+ var args = ["-s", targetFile.path, link.path];
+ process.run(true, args, args.length);
+ do_check_true(link.isSymlink());
+ }
+}
diff --git a/xpcom/tests/unit/test_bug478086.js b/xpcom/tests/unit/test_bug478086.js
new file mode 100644
index 000000000..bd6ea0d08
--- /dev/null
+++ b/xpcom/tests/unit/test_bug478086.js
@@ -0,0 +1,24 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+function run_test() {
+ var nsILocalFile = Components.interfaces.nsILocalFile;
+ var root = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+
+ // copied from http://mxr.mozilla.org/mozilla-central/source/image/test/unit/test_imgtools.js#135
+ // nsIXULRuntime.OS doesn't seem to be available in xpcshell, so we'll use
+ // this as a kludgy way to figure out if we're running on Windows.
+ if (mozinfo.os == "win") {
+ root.initWithPath("\\\\.");
+ } else {
+ return; // XXX disabled, since this causes intermittent failures on Mac (bug 481369).
+ root.initWithPath("/");
+ }
+ var drives = root.directoryEntries;
+ do_check_true(drives.hasMoreElements());
+ while (drives.hasMoreElements()) {
+ var newPath = drives.getNext().QueryInterface(nsILocalFile).path;
+ do_check_eq(newPath.indexOf("\0"), -1);
+ }
+}
diff --git a/xpcom/tests/unit/test_bug656331.js b/xpcom/tests/unit/test_bug656331.js
new file mode 100644
index 000000000..3bc1f82c0
--- /dev/null
+++ b/xpcom/tests/unit/test_bug656331.js
@@ -0,0 +1,39 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function info(s) {
+ dump("TEST-INFO | test_bug656331.js | " + s + "\n");
+}
+
+var gMessageExpected = /Native module.*has version 3.*expected/;
+var gFound = false;
+
+const kConsoleListener = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener]),
+
+ observe: function listener_observe(message) {
+ if (gMessageExpected.test(message.message))
+ gFound = true;
+ }
+};
+
+function run_test() {
+ let cs = Components.classes["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ cs.registerListener(kConsoleListener);
+
+ let manifest = do_get_file('components/bug656331.manifest');
+ registerAppManifest(manifest);
+
+ do_check_false("{f18fb09b-28b4-4435-bc5b-8027f18df743}" in Components.classesByID);
+
+ do_test_pending();
+ Components.classes["@mozilla.org/thread-manager;1"].
+ getService(Ci.nsIThreadManager).mainThread.dispatch(function() {
+ cs.unregisterListener(kConsoleListener);
+ do_check_true(gFound);
+ do_test_finished();
+ }, 0);
+}
diff --git a/xpcom/tests/unit/test_bug725015.js b/xpcom/tests/unit/test_bug725015.js
new file mode 100644
index 000000000..d6f62c509
--- /dev/null
+++ b/xpcom/tests/unit/test_bug725015.js
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const manifest = do_get_file('bug725015.manifest');
+const contract = "@bug725015.test.contract";
+const observerTopic = "xpcom-category-entry-added";
+const category = "bug725015-test-category";
+const entry = "bug725015-category-entry";
+const cid = Components.ID("{05070380-6e6e-42ba-aaa5-3289fc55ca5a}");
+
+function observe_category(subj, topic, data) {
+ try {
+ do_check_eq(topic, observerTopic);
+ if (data != category)
+ return;
+
+ var thisentry = subj.QueryInterface(Ci.nsISupportsCString).data;
+ do_check_eq(thisentry, entry);
+
+ do_check_eq(Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).getCategoryEntry(category, entry), contract);
+ do_check_true(Cc[contract].equals(cid));
+ }
+ catch (e) {
+ do_throw(e);
+ }
+ do_test_finished();
+}
+
+function run_test() {
+ do_test_pending();
+ Services.obs.addObserver(observe_category, observerTopic, false);
+ Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(manifest);
+}
diff --git a/xpcom/tests/unit/test_bug745466.js b/xpcom/tests/unit/test_bug745466.js
new file mode 100644
index 000000000..22a911ac5
--- /dev/null
+++ b/xpcom/tests/unit/test_bug745466.js
@@ -0,0 +1,6 @@
+Components.utils.import("resource://gre/modules/FileUtils.jsm");
+
+function run_test()
+{
+ do_check_true(FileUtils.File("~").equals(FileUtils.getDir("Home", [])));
+}
diff --git a/xpcom/tests/unit/test_comp_no_aslr.js b/xpcom/tests/unit/test_comp_no_aslr.js
new file mode 100644
index 000000000..7e15731c6
--- /dev/null
+++ b/xpcom/tests/unit/test_comp_no_aslr.js
@@ -0,0 +1,18 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function run_test() {
+ let manifest = do_get_file('components/testcompnoaslr.manifest');
+ registerAppManifest(manifest);
+ var sysInfo = Cc["@mozilla.org/system-info;1"].
+ getService(Ci.nsIPropertyBag2);
+ var ver = parseFloat(sysInfo.getProperty("version"));
+ if (ver < 6.0) {
+ // This is disabled on pre-Vista OSs.
+ do_check_true("{335fb596-e52d-418f-b01c-1bf16ce5e7e4}" in Components.classesByID);
+ } else {
+ do_check_false("{335fb596-e52d-418f-b01c-1bf16ce5e7e4}" in Components.classesByID);
+ }
+}
diff --git a/xpcom/tests/unit/test_compmgr_warnings.js b/xpcom/tests/unit/test_compmgr_warnings.js
new file mode 100644
index 000000000..be77b0d1b
--- /dev/null
+++ b/xpcom/tests/unit/test_compmgr_warnings.js
@@ -0,0 +1,71 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function info(s) {
+ dump("TEST-INFO | test_compmgr_warnings.js | " + s + "\n");
+}
+
+var gMessagesExpected = [
+ { line: 2, message: /Malformed CID/, found: false },
+ { line: 6, message: /re-register/, found: false },
+ { line: 9, message: /Could not/, found: false },
+ { line: 2, message: /binary component twice/, found: false },
+ { line: 3, message: /binary component twice/, found: false },
+];
+
+const kConsoleListener = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener]),
+
+ observe: function listener_observe(message) {
+ if (!(message instanceof Ci.nsIScriptError)) {
+ info("Not a script error: " + message.message);
+ return;
+ }
+
+ info("Script error... " + message.sourceName + ":" + message.lineNumber + ": " + message.errorMessage);
+ for (let expected of gMessagesExpected) {
+ if (message.lineNumber != expected.line)
+ continue;
+
+ if (!expected.message.test(message.errorMessage))
+ continue;
+
+ info("Found expected message: " + expected.message);
+ do_check_false(expected.found);
+
+ expected.found = true;
+ }
+ }
+};
+
+function run_deferred_event(fn) {
+ do_test_pending();
+ Components.classes["@mozilla.org/thread-manager;1"].
+ getService(Ci.nsIThreadManager).mainThread.dispatch(function() {
+ fn();
+ do_test_finished();
+ }, 0);
+}
+
+function run_test()
+{
+ let cs = Components.classes["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ cs.registerListener(kConsoleListener);
+
+ var manifest = do_get_file('compmgr_warnings.manifest');
+ registerAppManifest(manifest);
+ manifest = do_get_file('components/testcomponent.manifest');
+ registerAppManifest(manifest);
+
+ run_deferred_event(function() {
+ cs.unregisterListener(kConsoleListener);
+
+ for (let expected of gMessagesExpected) {
+ info("checking " + expected.message);
+ do_check_true(expected.found);
+ }
+ });
+}
diff --git a/xpcom/tests/unit/test_debugger_malloc_size_of.js b/xpcom/tests/unit/test_debugger_malloc_size_of.js
new file mode 100644
index 000000000..450d62793
--- /dev/null
+++ b/xpcom/tests/unit/test_debugger_malloc_size_of.js
@@ -0,0 +1,34 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This is just a sanity test that Gecko is giving SpiderMonkey a MallocSizeOf
+// function for new JSRuntimes. There is more extensive testing around the
+// expected byte sizes within SpiderMonkey's jit-tests, we just want to make
+// sure that Gecko is providing SpiderMonkey with the callback it needs.
+
+var Cu = Components.utils;
+const { byteSize } = Cu.getJSTestingFunctions();
+
+function run_test()
+{
+ const objects = [
+ {},
+ { w: 1, x: 2, y: 3, z:4, a: 5 },
+ [],
+ Array(10).fill(null),
+ new RegExp("(2|two) problems", "g"),
+ new Date(),
+ new Uint8Array(64),
+ Promise.resolve(1),
+ function f() {},
+ Object
+ ];
+
+ for (let obj of objects) {
+ do_print(uneval(obj));
+ ok(byteSize(obj), "We should get some (non-zero) byte size");
+ }
+}
diff --git a/xpcom/tests/unit/test_file_createUnique.js b/xpcom/tests/unit/test_file_createUnique.js
new file mode 100644
index 000000000..1ab204bab
--- /dev/null
+++ b/xpcom/tests/unit/test_file_createUnique.js
@@ -0,0 +1,29 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+
+function run_test()
+{
+ // Generate a leaf name that is 255 characters long.
+ var longLeafName = new Array(256).join("T");
+
+ // Generate the path for a file located in a directory with a long name.
+ var tempFile = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
+ tempFile.append(longLeafName);
+ tempFile.append("test.txt");
+
+ try {
+ tempFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
+ do_throw("Creating an item in a folder with a very long name should throw");
+ }
+ catch (e if (e instanceof Ci.nsIException &&
+ e.result == Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH)) {
+ // We expect the function not to crash but to raise this exception.
+ }
+}
diff --git a/xpcom/tests/unit/test_file_equality.js b/xpcom/tests/unit/test_file_equality.js
new file mode 100644
index 000000000..235792560
--- /dev/null
+++ b/xpcom/tests/unit/test_file_equality.js
@@ -0,0 +1,43 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cr = Components.results;
+var Ci = Components.interfaces;
+
+var CC = Components.Constructor;
+var LocalFile = CC("@mozilla.org/file/local;1", "nsILocalFile", "initWithPath");
+
+function run_test()
+{
+ test_normalized_vs_non_normalized();
+}
+
+function test_normalized_vs_non_normalized()
+{
+ // get a directory that exists on all platforms
+ var dirProvider = Components.classes["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+ var tmp1 = dirProvider.get("TmpD", Ci.nsILocalFile);
+ var exists = tmp1.exists();
+ do_check_true(exists);
+ if (!exists)
+ return;
+
+ // the test logic below assumes we're starting with a normalized path, but the
+ // default location on macos is a symbolic link, so resolve it before starting
+ tmp1.normalize();
+
+ // this has the same exact path as tmp1, it should equal tmp1
+ var tmp2 = new LocalFile(tmp1.path);
+ do_check_true(tmp1.equals(tmp2));
+
+ // this is a non-normalized version of tmp1, it should not equal tmp1
+ tmp2.appendRelativePath(".");
+ do_check_false(tmp1.equals(tmp2));
+
+ // normalize and make sure they are equivalent again
+ tmp2.normalize();
+ do_check_true(tmp1.equals(tmp2));
+}
diff --git a/xpcom/tests/unit/test_file_renameTo.js b/xpcom/tests/unit/test_file_renameTo.js
new file mode 100644
index 000000000..0a7196fe2
--- /dev/null
+++ b/xpcom/tests/unit/test_file_renameTo.js
@@ -0,0 +1,61 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+
+function run_test()
+{
+ // Create the base directory.
+ let base = Cc['@mozilla.org/file/directory_service;1']
+ .getService(Ci.nsIProperties)
+ .get('TmpD', Ci.nsILocalFile);
+ base.append('renameTesting');
+ if (base.exists()) {
+ base.remove(true);
+ }
+ base.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0777', 8));
+
+ // Create a sub directory under the base.
+ let subdir = base.clone();
+ subdir.append('subdir');
+ subdir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0777', 8));
+
+ // Create a file under the sub directory.
+ let tempFile = subdir.clone();
+ tempFile.append('file0.txt');
+ tempFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt('0777', 8));
+
+ // Test renameTo in the base directory
+ tempFile.renameTo(null, 'file1.txt');
+ do_check_true(exists(subdir, 'file1.txt'));
+
+ // Test moving across directories
+ tempFile = subdir.clone();
+ tempFile.append('file1.txt');
+ tempFile.renameTo(base, '');
+ do_check_true(exists(base, 'file1.txt'));
+
+ // Test moving across directories and renaming at the same time
+ tempFile = base.clone();
+ tempFile.append('file1.txt');
+ tempFile.renameTo(subdir, 'file2.txt');
+ do_check_true(exists(subdir, 'file2.txt'));
+
+ // Test moving a directory
+ subdir.renameTo(base, 'renamed');
+ do_check_true(exists(base, 'renamed'));
+ let renamed = base.clone();
+ renamed.append('renamed');
+ do_check_true(exists(renamed, 'file2.txt'));
+
+ base.remove(true);
+}
+
+function exists(parent, filename) {
+ let file = parent.clone();
+ file.append(filename);
+ return file.exists();
+}
diff --git a/xpcom/tests/unit/test_hidden_files.js b/xpcom/tests/unit/test_hidden_files.js
new file mode 100644
index 000000000..3383ba11b
--- /dev/null
+++ b/xpcom/tests/unit/test_hidden_files.js
@@ -0,0 +1,28 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+const NS_OS_TEMP_DIR = "TmpD";
+
+const CWD = do_get_cwd();
+
+var hiddenUnixFile;
+function createUNIXHiddenFile() {
+ var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+ var tmpDir = dirSvc.get(NS_OS_TEMP_DIR, Ci.nsIFile);
+ hiddenUnixFile = tmpDir.clone();
+ hiddenUnixFile.append(".foo");
+ // we don't care if this already exists because we don't care
+ // about the file's contents (just the name)
+ if (!hiddenUnixFile.exists())
+ hiddenUnixFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+ return hiddenUnixFile.exists();
+}
+
+function run_test() {
+ // Skip this test on Windows
+ if (mozinfo.os == "win")
+ return;
+
+ do_check_true(createUNIXHiddenFile());
+ do_check_true(hiddenUnixFile.isHidden());
+}
+
diff --git a/xpcom/tests/unit/test_home.js b/xpcom/tests/unit/test_home.js
new file mode 100644
index 000000000..61fa5b344
--- /dev/null
+++ b/xpcom/tests/unit/test_home.js
@@ -0,0 +1,24 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+
+const CWD = do_get_cwd();
+function checkOS(os) {
+ const nsILocalFile_ = "nsILocalFile" + os;
+ return nsILocalFile_ in Components.interfaces &&
+ CWD instanceof Components.interfaces[nsILocalFile_];
+}
+
+const isWin = checkOS("Win");
+
+function run_test() {
+ var envVar = isWin ? "USERPROFILE" : "HOME";
+
+ var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+ var homeDir = dirSvc.get("Home", Ci.nsIFile);
+
+ var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
+ var expected = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ expected.initWithPath(env.get(envVar));
+
+ do_check_eq(homeDir.path, expected.path);
+}
diff --git a/xpcom/tests/unit/test_iniProcessor.js b/xpcom/tests/unit/test_iniProcessor.js
new file mode 100644
index 000000000..3d3886d35
--- /dev/null
+++ b/xpcom/tests/unit/test_iniProcessor.js
@@ -0,0 +1,288 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+
+var testnum = 0;
+var factory;
+
+function parserForFile(filename) {
+ let parser = null;
+ try {
+ let file = do_get_file(filename);
+ do_check_true(!!file);
+ parser = factory.createINIParser(file);
+ do_check_true(!!parser);
+ } catch(e) {
+ dump("INFO | caught error: " + e);
+ // checkParserOutput will handle a null parser when it's expected.
+ }
+ return parser;
+
+}
+
+function checkParserOutput(parser, expected) {
+ // If the expected output is null, we expect the parser to have
+ // failed (and vice-versa).
+ if (!parser || !expected) {
+ do_check_eq(parser, null);
+ do_check_eq(expected, null);
+ return;
+ }
+
+ let output = getParserOutput(parser);
+ for (let section in expected) {
+ do_check_true(section in output);
+ for (let key in expected[section]) {
+ do_check_true(key in output[section]);
+ do_check_eq(output[section][key], expected[section][key]);
+ delete output[section][key];
+ }
+ for (let key in output[section])
+ do_check_eq(key, "wasn't expecting this key!");
+ delete output[section];
+ }
+ for (let section in output)
+ do_check_eq(section, "wasn't expecting this section!");
+}
+
+function getParserOutput(parser) {
+ let output = {};
+
+ let sections = parser.getSections();
+ do_check_true(!!sections);
+ while (sections.hasMore()) {
+ let section = sections.getNext();
+ do_check_false(section in output); // catch dupes
+ output[section] = {};
+
+ let keys = parser.getKeys(section);
+ do_check_true(!!keys);
+ while (keys.hasMore()) {
+ let key = keys.getNext();
+ do_check_false(key in output[section]); // catch dupes
+ let value = parser.getString(section, key);
+ output[section][key] = value;
+ }
+ }
+ return output;
+}
+
+function run_test() {
+try {
+
+var testdata = [
+ { filename: "data/iniparser01.ini", reference: {} },
+ { filename: "data/iniparser02.ini", reference: {} },
+ { filename: "data/iniparser03.ini", reference: {} },
+ { filename: "data/iniparser04.ini", reference: {} },
+ { filename: "data/iniparser05.ini", reference: {} },
+ { filename: "data/iniparser06.ini", reference: {} },
+ { filename: "data/iniparser07.ini", reference: {} },
+ { filename: "data/iniparser08.ini", reference: { section1: { name1: "" }} },
+ { filename: "data/iniparser09.ini", reference: { section1: { name1: "value1" } } },
+ { filename: "data/iniparser10.ini", reference: { section1: { name1: "value1" } } },
+ { filename: "data/iniparser11.ini", reference: { section1: { name1: "value1" } } },
+ { filename: "data/iniparser12.ini", reference: { section1: { name1: "value1" } } },
+ { filename: "data/iniparser13.ini", reference: { section1: { name1: "value1" } } },
+ { filename: "data/iniparser14.ini", reference:
+ { section1: { name1: "value1", name2: "value2" },
+ section2: { name1: "value1", name2: "foopy" }} },
+ { filename: "data/iniparser15.ini", reference:
+ { section1: { name1: "newValue1" },
+ section2: { name1: "foopy" }} },
+ { filename: "data/iniparser16.ini", reference:
+ { "☺♫": { "♫": "☻", "♪": "♥" },
+ "☼": { "♣": "♠", "♦": "♥" }} },
+
+ ];
+
+ testdata.push( { filename: "data/iniparser01-utf8BOM.ini",
+ reference: testdata[0].reference } );
+ testdata.push( { filename: "data/iniparser02-utf8BOM.ini",
+ reference: testdata[1].reference } );
+ testdata.push( { filename: "data/iniparser03-utf8BOM.ini",
+ reference: testdata[2].reference } );
+ testdata.push( { filename: "data/iniparser04-utf8BOM.ini",
+ reference: testdata[3].reference } );
+ testdata.push( { filename: "data/iniparser05-utf8BOM.ini",
+ reference: testdata[4].reference } );
+ testdata.push( { filename: "data/iniparser06-utf8BOM.ini",
+ reference: testdata[5].reference } );
+ testdata.push( { filename: "data/iniparser07-utf8BOM.ini",
+ reference: testdata[6].reference } );
+ testdata.push( { filename: "data/iniparser08-utf8BOM.ini",
+ reference: testdata[7].reference } );
+ testdata.push( { filename: "data/iniparser09-utf8BOM.ini",
+ reference: testdata[8].reference } );
+ testdata.push( { filename: "data/iniparser10-utf8BOM.ini",
+ reference: testdata[9].reference } );
+ testdata.push( { filename: "data/iniparser11-utf8BOM.ini",
+ reference: testdata[10].reference } );
+ testdata.push( { filename: "data/iniparser12-utf8BOM.ini",
+ reference: testdata[11].reference } );
+ testdata.push( { filename: "data/iniparser13-utf8BOM.ini",
+ reference: testdata[12].reference } );
+ testdata.push( { filename: "data/iniparser14-utf8BOM.ini",
+ reference: testdata[13].reference } );
+ testdata.push( { filename: "data/iniparser15-utf8BOM.ini",
+ reference: testdata[14].reference } );
+ testdata.push( { filename: "data/iniparser16-utf8BOM.ini",
+ reference: testdata[15].reference } );
+
+ let os = Cc["@mozilla.org/xre/app-info;1"]
+ .getService(Ci.nsIXULRuntime).OS;
+ if("WINNT" === os) {
+ testdata.push( { filename: "data/iniparser01-utf16leBOM.ini",
+ reference: testdata[0].reference } );
+ testdata.push( { filename: "data/iniparser02-utf16leBOM.ini",
+ reference: testdata[1].reference } );
+ testdata.push( { filename: "data/iniparser03-utf16leBOM.ini",
+ reference: testdata[2].reference } );
+ testdata.push( { filename: "data/iniparser04-utf16leBOM.ini",
+ reference: testdata[3].reference } );
+ testdata.push( { filename: "data/iniparser05-utf16leBOM.ini",
+ reference: testdata[4].reference } );
+ testdata.push( { filename: "data/iniparser06-utf16leBOM.ini",
+ reference: testdata[5].reference } );
+ testdata.push( { filename: "data/iniparser07-utf16leBOM.ini",
+ reference: testdata[6].reference } );
+ testdata.push( { filename: "data/iniparser08-utf16leBOM.ini",
+ reference: testdata[7].reference } );
+ testdata.push( { filename: "data/iniparser09-utf16leBOM.ini",
+ reference: testdata[8].reference } );
+ testdata.push( { filename: "data/iniparser10-utf16leBOM.ini",
+ reference: testdata[9].reference } );
+ testdata.push( { filename: "data/iniparser11-utf16leBOM.ini",
+ reference: testdata[10].reference } );
+ testdata.push( { filename: "data/iniparser12-utf16leBOM.ini",
+ reference: testdata[11].reference } );
+ testdata.push( { filename: "data/iniparser13-utf16leBOM.ini",
+ reference: testdata[12].reference } );
+ testdata.push( { filename: "data/iniparser14-utf16leBOM.ini",
+ reference: testdata[13].reference } );
+ testdata.push( { filename: "data/iniparser15-utf16leBOM.ini",
+ reference: testdata[14].reference } );
+ testdata.push( { filename: "data/iniparser16-utf16leBOM.ini",
+ reference: testdata[15].reference } );
+ }
+
+/* ========== 0 ========== */
+factory = Cc["@mozilla.org/xpcom/ini-processor-factory;1"].
+ getService(Ci.nsIINIParserFactory);
+do_check_true(!!factory);
+
+// Test reading from a variety of files. While we're at it, write out each one
+// and read it back to ensure that nothing changed.
+while (testnum < testdata.length) {
+ dump("\nINFO | test #" + ++testnum);
+ let filename = testdata[testnum -1].filename;
+ dump(", filename " + filename + "\n");
+ let parser = parserForFile(filename);
+ checkParserOutput(parser, testdata[testnum - 1].reference);
+ if (!parser)
+ continue;
+ do_check_true(parser instanceof Ci.nsIINIParserWriter);
+ // write contents out to a new file
+ let newfilename = filename + ".new";
+ let newfile = do_get_file(filename);
+ newfile.leafName += ".new";
+ parser.writeFile(newfile);
+ // read new file and make sure the contents are the same.
+ parser = parserForFile(newfilename);
+ checkParserOutput(parser, testdata[testnum - 1].reference);
+ // cleanup after the test
+ newfile.remove(false);
+}
+
+dump("INFO | test #" + ++testnum + "\n");
+
+// test writing to a new file.
+var newfile = do_get_file("data/");
+newfile.append("nonexistent-file.ini");
+if (newfile.exists())
+ newfile.remove(false);
+do_check_false(newfile.exists());
+
+var parser = factory.createINIParser(newfile);
+do_check_true(!!parser);
+do_check_true(parser instanceof Ci.nsIINIParserWriter);
+checkParserOutput(parser, {});
+parser.writeFile();
+do_check_true(newfile.exists());
+
+// test adding a new section and new key
+parser.setString("section", "key", "value");
+parser.writeFile();
+do_check_true(newfile.exists());
+checkParserOutput(parser, {section: {key: "value"} });
+// read it in again, check for same data.
+parser = parserForFile("data/nonexistent-file.ini");
+checkParserOutput(parser, {section: {key: "value"} });
+// cleanup after the test
+newfile.remove(false);
+
+dump("INFO | test #" + ++testnum + "\n");
+
+// test modifying a existing key's value (in an existing section)
+parser = parserForFile("data/iniparser09.ini");
+checkParserOutput(parser, {section1: {name1: "value1"} });
+
+do_check_true(parser instanceof Ci.nsIINIParserWriter);
+parser.setString("section1", "name1", "value2");
+checkParserOutput(parser, {section1: {name1: "value2"} });
+
+dump("INFO | test #" + ++testnum + "\n");
+
+// test trying to set illegal characters
+var caughtError;
+caughtError = false;
+checkParserOutput(parser, {section1: {name1: "value2"} });
+
+// Bad characters in section name
+try { parser.SetString("bad\0", "ok", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("bad\r", "ok", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("bad\n", "ok", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("bad[", "ok", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("bad]", "ok", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+
+// Bad characters in key name
+caughtError = false;
+try { parser.SetString("ok", "bad\0", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "bad\r", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "bad\n", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "bad=", "ok"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+
+// Bad characters in value
+caughtError = false;
+try { parser.SetString("ok", "ok", "bad\0"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "ok", "bad\r"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "ok", "bad\n"); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+caughtError = false;
+try { parser.SetString("ok", "ok", "bad="); } catch (e) { caughtError = true; }
+do_check_true(caughtError);
+
+} catch(e) {
+ throw "FAILED in test #" + testnum + " -- " + e;
+}
+}
diff --git a/xpcom/tests/unit/test_ioutil.js b/xpcom/tests/unit/test_ioutil.js
new file mode 100644
index 000000000..ef27f584f
--- /dev/null
+++ b/xpcom/tests/unit/test_ioutil.js
@@ -0,0 +1,33 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+
+const util = Cc["@mozilla.org/io-util;1"].getService(Ci.nsIIOUtil);
+
+function run_test()
+{
+ try {
+ util.inputStreamIsBuffered(null);
+ do_throw("inputStreamIsBuffered should have thrown");
+ } catch (e) {
+ do_check_eq(e.result, Cr.NS_ERROR_INVALID_POINTER);
+ }
+
+ try {
+ util.outputStreamIsBuffered(null);
+ do_throw("outputStreamIsBuffered should have thrown");
+ } catch (e) {
+ do_check_eq(e.result, Cr.NS_ERROR_INVALID_POINTER);
+ }
+
+ var s = Cc["@mozilla.org/io/string-input-stream;1"]
+ .createInstance(Ci.nsIStringInputStream);
+ var body = "This is a test";
+ s.setData(body, body.length);
+ do_check_eq(util.inputStreamIsBuffered(s), true);
+}
diff --git a/xpcom/tests/unit/test_localfile.js b/xpcom/tests/unit/test_localfile.js
new file mode 100644
index 000000000..25f4bf34b
--- /dev/null
+++ b/xpcom/tests/unit/test_localfile.js
@@ -0,0 +1,151 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cr = Components.results;
+var CC = Components.Constructor;
+var Ci = Components.interfaces;
+
+const MAX_TIME_DIFFERENCE = 2500;
+const MILLIS_PER_DAY = 1000 * 60 * 60 * 24;
+
+var LocalFile = CC("@mozilla.org/file/local;1", "nsILocalFile", "initWithPath");
+
+function run_test()
+{
+ test_toplevel_parent_is_null();
+ test_normalize_crash_if_media_missing();
+ test_file_modification_time();
+ test_directory_modification_time();
+ test_diskSpaceAvailable();
+}
+
+function test_toplevel_parent_is_null()
+{
+ try
+ {
+ var lf = new LocalFile("C:\\");
+
+ // not required by API, but a property on which the implementation of
+ // parent == null relies for correctness
+ do_check_true(lf.path.length == 2);
+
+ do_check_true(lf.parent === null);
+ }
+ catch (e)
+ {
+ // not Windows
+ do_check_eq(e.result, Cr.NS_ERROR_FILE_UNRECOGNIZED_PATH);
+ }
+}
+
+function test_normalize_crash_if_media_missing()
+{
+ const a="a".charCodeAt(0);
+ const z="z".charCodeAt(0);
+ for (var i = a; i <= z; ++i)
+ {
+ try
+ {
+ LocalFile(String.fromCharCode(i)+":.\\test").normalize();
+ }
+ catch (e)
+ {
+ }
+ }
+}
+
+// Tests that changing a file's modification time is possible
+function test_file_modification_time()
+{
+ var file = do_get_profile();
+ file.append("testfile");
+
+ // Should never happen but get rid of it anyway
+ if (file.exists())
+ file.remove(true);
+
+ var now = Date.now();
+ file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+ do_check_true(file.exists());
+
+ // Modification time may be out by up to 2 seconds on FAT filesystems. Test
+ // with a bit of leeway, close enough probably means it is correct.
+ var diff = Math.abs(file.lastModifiedTime - now);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ var yesterday = now - MILLIS_PER_DAY;
+ file.lastModifiedTime = yesterday;
+
+ diff = Math.abs(file.lastModifiedTime - yesterday);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ var tomorrow = now - MILLIS_PER_DAY;
+ file.lastModifiedTime = tomorrow;
+
+ diff = Math.abs(file.lastModifiedTime - tomorrow);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ var bug377307 = 1172950238000;
+ file.lastModifiedTime = bug377307;
+
+ diff = Math.abs(file.lastModifiedTime - bug377307);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ file.remove(true);
+}
+
+// Tests that changing a directory's modification time is possible
+function test_directory_modification_time()
+{
+ var dir = do_get_profile();
+ dir.append("testdir");
+
+ // Should never happen but get rid of it anyway
+ if (dir.exists())
+ dir.remove(true);
+
+ var now = Date.now();
+ dir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ do_check_true(dir.exists());
+
+ // Modification time may be out by up to 2 seconds on FAT filesystems. Test
+ // with a bit of leeway, close enough probably means it is correct.
+ var diff = Math.abs(dir.lastModifiedTime - now);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ var yesterday = now - MILLIS_PER_DAY;
+ dir.lastModifiedTime = yesterday;
+
+ diff = Math.abs(dir.lastModifiedTime - yesterday);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ var tomorrow = now - MILLIS_PER_DAY;
+ dir.lastModifiedTime = tomorrow;
+
+ diff = Math.abs(dir.lastModifiedTime - tomorrow);
+ do_check_true(diff < MAX_TIME_DIFFERENCE);
+
+ dir.remove(true);
+}
+
+function test_diskSpaceAvailable()
+{
+ let file = do_get_profile();
+ file.QueryInterface(Ci.nsILocalFile);
+
+ let bytes = file.diskSpaceAvailable;
+ do_check_true(bytes > 0);
+
+ file.append("testfile");
+ if (file.exists())
+ file.remove(true);
+ file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o644);
+
+ bytes = file.diskSpaceAvailable;
+ do_check_true(bytes > 0);
+
+ file.remove(true);
+}
diff --git a/xpcom/tests/unit/test_mac_bundle.js b/xpcom/tests/unit/test_mac_bundle.js
new file mode 100644
index 000000000..550a4abd6
--- /dev/null
+++ b/xpcom/tests/unit/test_mac_bundle.js
@@ -0,0 +1,18 @@
+function run_test() {
+ // this is a hack to skip the rest of the code on non-Mac platforms,
+ // since #ifdef is not available to xpcshell tests...
+ if (mozinfo.os != "mac") {
+ return;
+ }
+
+ // OK, here's the real part of the test:
+ // make sure these two test bundles are recognized as bundles (or "packages")
+ var keynoteBundle = do_get_file("data/presentation.key");
+ var appBundle = do_get_file("data/SmallApp.app");
+
+ do_check_true(keynoteBundle instanceof Components.interfaces.nsILocalFileMac);
+ do_check_true(appBundle instanceof Components.interfaces.nsILocalFileMac);
+
+ do_check_true(keynoteBundle.isPackage());
+ do_check_true(appBundle.isPackage());
+}
diff --git a/xpcom/tests/unit/test_notxpcom_scriptable.js b/xpcom/tests/unit/test_notxpcom_scriptable.js
new file mode 100644
index 000000000..5d5e24bd9
--- /dev/null
+++ b/xpcom/tests/unit/test_notxpcom_scriptable.js
@@ -0,0 +1,86 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+var Cr = Components.results;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const kCID = Components.ID("{1f9f7181-e6c5-4f4c-8f71-08005cec8468}");
+const kContract = "@testing/notxpcomtest";
+
+function run_test()
+{
+ let manifest = do_get_file("xpcomtest.manifest");
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.autoRegister(manifest);
+
+ ok(Ci.ScriptableWithNotXPCOM);
+
+ let method1Called = false;
+
+ let testObject = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.ScriptableOK,
+ Ci.ScriptableWithNotXPCOM,
+ Ci.ScriptableWithNotXPCOMBase]),
+
+ method1: function() {
+ method1Called = true;
+ },
+
+ method2: function() {
+ ok(false, "method2 should not have been called!");
+ },
+
+ method3: function() {
+ ok(false, "mehod3 should not have been called!");
+ },
+
+ jsonly: true,
+ };
+
+ let factory = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
+
+ createInstance: function(outer, iid) {
+ if (outer) {
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ }
+ return testObject.QueryInterface(iid);
+ },
+ };
+
+ registrar.registerFactory(kCID, null, kContract, factory);
+
+ let xpcomObject = Cc[kContract].createInstance();
+ ok(xpcomObject);
+ strictEqual(xpcomObject.jsonly, undefined);
+
+ xpcomObject.QueryInterface(Ci.ScriptableOK);
+
+ xpcomObject.method1();
+ ok(method1Called);
+
+ try {
+ xpcomObject.QueryInterface(Ci.ScriptableWithNotXPCOM);
+ ok(false, "Should not have implemented ScriptableWithNotXPCOM");
+ }
+ catch(e) {
+ ok(true, "Should not have implemented ScriptableWithNotXPCOM. Correctly threw error: " + e);
+ }
+ strictEqual(xpcomObject.method2, undefined);
+
+ try {
+ xpcomObject.QueryInterface(Ci.ScriptableWithNotXPCOMBase);
+ ok(false, "Should not have implemented ScriptableWithNotXPCOMBase");
+ }
+ catch (e) {
+ ok(true, "Should not have implemented ScriptableWithNotXPCOMBase. Correctly threw error: " + e);
+ }
+ strictEqual(xpcomObject.method3, undefined);
+}
+
diff --git a/xpcom/tests/unit/test_nsIMutableArray.js b/xpcom/tests/unit/test_nsIMutableArray.js
new file mode 100644
index 000000000..b491aee96
--- /dev/null
+++ b/xpcom/tests/unit/test_nsIMutableArray.js
@@ -0,0 +1,184 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var Cc = Components.classes;
+var CC = Components.Constructor;
+
+var MutableArray = CC("@mozilla.org/array;1", "nsIMutableArray");
+var SupportsString = CC("@mozilla.org/supports-string;1", "nsISupportsString");
+
+function create_n_element_array(n)
+{
+ var arr = new MutableArray();
+ for (let i=0; i<n; i++) {
+ let str = new SupportsString();
+ str.data = "element " + i;
+ arr.appendElement(str, false);
+ }
+ return arr;
+}
+
+function test_appending_null_actually_inserts()
+{
+ var arr = new MutableArray();
+ do_check_eq(0, arr.length);
+ arr.appendElement(null, false);
+ do_check_eq(1, arr.length);
+}
+
+function test_object_gets_appended()
+{
+ var arr = new MutableArray();
+ var str = new SupportsString();
+ str.data = "hello";
+ arr.appendElement(str, false);
+ do_check_eq(1, arr.length);
+ var obj = arr.queryElementAt(0, Ci.nsISupportsString);
+ do_check_eq(str, obj);
+}
+
+function test_insert_at_beginning()
+{
+ var arr = create_n_element_array(5);
+ // just a sanity check
+ do_check_eq(5, arr.length);
+ var str = new SupportsString();
+ str.data = "hello";
+ arr.insertElementAt(str, 0, false);
+ do_check_eq(6, arr.length);
+ var obj = arr.queryElementAt(0, Ci.nsISupportsString);
+ do_check_eq(str, obj);
+ // check the data of all the other objects
+ for (let i=1; i<arr.length; i++) {
+ let obj = arr.queryElementAt(i, Ci.nsISupportsString);
+ do_check_eq("element " + (i-1), obj.data);
+ }
+}
+
+function test_replace_element()
+{
+ var arr = create_n_element_array(5);
+ // just a sanity check
+ do_check_eq(5, arr.length);
+ var str = new SupportsString();
+ str.data = "hello";
+ // replace first element
+ arr.replaceElementAt(str, 0, false);
+ do_check_eq(5, arr.length);
+ var obj = arr.queryElementAt(0, Ci.nsISupportsString);
+ do_check_eq(str, obj);
+ // replace last element
+ arr.replaceElementAt(str, arr.length - 1, false);
+ do_check_eq(5, arr.length);
+ obj = arr.queryElementAt(arr.length - 1, Ci.nsISupportsString);
+ do_check_eq(str, obj);
+ // replace after last element, should insert empty elements
+ arr.replaceElementAt(str, 9, false);
+ do_check_eq(10, arr.length);
+ obj = arr.queryElementAt(9, Ci.nsISupportsString);
+ do_check_eq(str, obj);
+ // AFAIK there's no way to check the empty elements, since you can't QI them.
+}
+
+function test_clear()
+{
+ var arr = create_n_element_array(5);
+ // just a sanity check
+ do_check_eq(5, arr.length);
+ arr.clear();
+ do_check_eq(0, arr.length);
+}
+
+function test_enumerate()
+{
+ var arr = create_n_element_array(5);
+ do_check_eq(5, arr.length);
+ var en = arr.enumerate();
+ var i = 0;
+ while (en.hasMoreElements()) {
+ let str = en.getNext();
+ do_check_true(str instanceof Ci.nsISupportsString);
+ do_check_eq(str.data, "element " + i);
+ i++;
+ }
+ do_check_eq(arr.length, i);
+}
+
+function test_nssupportsarray_interop() {
+ // Tests to check that an nsSupportsArray instance can behave like an
+ // nsIArray.
+ let test = Components.classes["@mozilla.org/supports-array;1"]
+ .createInstance(Ci.nsISupportsArray);
+
+ let str = new SupportsString();
+ str.data = "element";
+ test.AppendElement(str);
+
+ // Now query to an nsIArray.
+ let iarray = test.QueryInterface(Ci.nsIArray);
+ do_check_neq(iarray, null);
+
+ // Make sure |nsIArray.length| works.
+ do_check_eq(iarray.length, 1);
+
+ // Make sure |nsIArray.queryElementAt| works.
+ let elm = iarray.queryElementAt(0, Ci.nsISupportsString);
+ do_check_eq(elm.data, "element");
+
+ // Make sure |nsIArray.indexOf| works.
+ let idx = iarray.indexOf(0, str);
+ do_check_eq(idx, 0);
+
+ // Make sure |nsIArray.enumerate| works.
+ let en = iarray.enumerate();
+ do_check_neq(en, null);
+ let i = 0;
+ while (en.hasMoreElements()) {
+ let str = en.getNext();
+ do_check_true(str instanceof Ci.nsISupportsString);
+ do_check_eq(str.data, "element");
+ i++;
+ }
+
+ do_check_eq(iarray.length, i);
+}
+
+function test_nsiarrayextensions() {
+ // Tests to check that the extensions that make an nsArray act like an
+ // nsISupportsArray for iteration purposes works.
+ // Note: we do not want to QI here, just want to make sure the magic glue
+ // works as a drop-in replacement.
+
+ let fake_nsisupports_array = create_n_element_array(5);
+
+ // Check that |Count| works.
+ do_check_eq(5, fake_nsisupports_array.Count());
+
+ for (let i = 0; i < fake_nsisupports_array.Count(); i++) {
+ // Check that the generic |GetElementAt| works.
+ let elm = fake_nsisupports_array.GetElementAt(i);
+ do_check_neq(elm, null);
+ let str = elm.QueryInterface(Ci.nsISupportsString);
+ do_check_neq(str, null);
+ do_check_eq(str.data, "element " + i);
+ }
+}
+
+var tests = [
+ test_appending_null_actually_inserts,
+ test_object_gets_appended,
+ test_insert_at_beginning,
+ test_replace_element,
+ test_clear,
+ test_enumerate,
+ test_nssupportsarray_interop,
+ test_nsiarrayextensions,
+];
+
+function run_test() {
+ for (var i = 0; i < tests.length; i++)
+ tests[i]();
+}
diff --git a/xpcom/tests/unit/test_nsIProcess.js b/xpcom/tests/unit/test_nsIProcess.js
new file mode 100644
index 000000000..6c6a5a683
--- /dev/null
+++ b/xpcom/tests/unit/test_nsIProcess.js
@@ -0,0 +1,185 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+// nsIProcess unit test
+const TEST_ARGS = ["mozilla", "firefox", "thunderbird", "seamonkey", "foo",
+ "bar", "argument with spaces", "\"argument with quotes\""];
+
+const TEST_UNICODE_ARGS = ["M\u00F8z\u00EEll\u00E5",
+ "\u041C\u043E\u0437\u0438\u043B\u043B\u0430",
+ "\u09AE\u09CB\u099C\u09BF\u09B2\u09BE",
+ "\uD808\uDE2C\uD808\uDF63\uD808\uDDB7"];
+
+// test if a process can be started, polled for its running status
+// and then killed
+function test_kill()
+{
+ var file = get_test_program("TestBlockingProcess");
+
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ do_check_false(process.isRunning);
+
+ try {
+ process.kill();
+ do_throw("Attempting to kill a not-running process should throw");
+ }
+ catch (e) { }
+
+ process.run(false, [], 0);
+
+ do_check_true(process.isRunning);
+
+ process.kill();
+
+ do_check_false(process.isRunning);
+
+ try {
+ process.kill();
+ do_throw("Attempting to kill a not-running process should throw");
+ }
+ catch (e) { }
+}
+
+// test if we can get an exit value from an application that is
+// guaranteed to return an exit value of 42
+function test_quick()
+{
+ var file = get_test_program("TestQuickReturn");
+
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ // to get an exit value it must be a blocking process
+ process.run(true, [], 0);
+
+ do_check_eq(process.exitValue, 42);
+}
+
+function test_args(file, args, argsAreASCII)
+{
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ if (argsAreASCII)
+ process.run(true, args, args.length);
+ else
+ process.runw(true, args, args.length);
+
+ do_check_eq(process.exitValue, 0);
+}
+
+// test if an argument can be successfully passed to an application
+// that will return 0 if "mozilla" is the only argument
+function test_arguments()
+{
+ test_args(get_test_program("TestArguments"), TEST_ARGS, true);
+}
+
+// test if Unicode arguments can be successfully passed to an application
+function test_unicode_arguments()
+{
+ test_args(get_test_program("TestUnicodeArguments"), TEST_UNICODE_ARGS, false);
+}
+
+function rename_and_test(asciiName, unicodeName, args, argsAreASCII)
+{
+ var asciiFile = get_test_program(asciiName);
+ var asciiLeaf = asciiFile.leafName;
+ var unicodeLeaf = asciiLeaf.replace(asciiName, unicodeName);
+
+ asciiFile.moveTo(null, unicodeLeaf);
+
+ var unicodeFile = get_test_program(unicodeName);
+
+ test_args(unicodeFile, args, argsAreASCII);
+
+ unicodeFile.moveTo(null, asciiLeaf);
+}
+
+// test passing ASCII and Unicode arguments to an application with a Unicode name
+function test_unicode_app()
+{
+ rename_and_test("TestArguments",
+ // "Unicode" in Tamil
+ "\u0BAF\u0BC1\u0BA9\u0BBF\u0B95\u0BCB\u0B9F\u0BCD",
+ TEST_ARGS, true);
+
+ rename_and_test("TestUnicodeArguments",
+ // "Unicode" in Thai
+ "\u0E22\u0E39\u0E19\u0E34\u0E42\u0E04\u0E14",
+ TEST_UNICODE_ARGS, false);
+}
+
+// test if we get notified about a blocking process
+function test_notify_blocking()
+{
+ var file = get_test_program("TestQuickReturn");
+
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ process.runAsync([], 0, {
+ observe: function(subject, topic, data) {
+ process = subject.QueryInterface(Components.interfaces.nsIProcess);
+ do_check_eq(topic, "process-finished");
+ do_check_eq(process.exitValue, 42);
+ test_notify_nonblocking();
+ }
+ });
+}
+
+// test if we get notified about a non-blocking process
+function test_notify_nonblocking()
+{
+ var file = get_test_program("TestArguments");
+
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ process.runAsync(TEST_ARGS, TEST_ARGS.length, {
+ observe: function(subject, topic, data) {
+ process = subject.QueryInterface(Components.interfaces.nsIProcess);
+ do_check_eq(topic, "process-finished");
+ do_check_eq(process.exitValue, 0);
+ test_notify_killed();
+ }
+ });
+}
+
+// test if we get notified about a killed process
+function test_notify_killed()
+{
+ var file = get_test_program("TestBlockingProcess");
+
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ process.runAsync([], 0, {
+ observe: function(subject, topic, data) {
+ process = subject.QueryInterface(Components.interfaces.nsIProcess);
+ do_check_eq(topic, "process-finished");
+ do_test_finished();
+ }
+ });
+
+ process.kill();
+}
+
+function run_test() {
+ set_process_running_environment();
+ test_kill();
+ test_quick();
+ test_arguments();
+ test_unicode_arguments();
+ test_unicode_app();
+ do_test_pending();
+ test_notify_blocking();
+}
diff --git a/xpcom/tests/unit/test_nsIProcess_stress.js b/xpcom/tests/unit/test_nsIProcess_stress.js
new file mode 100644
index 000000000..63799141d
--- /dev/null
+++ b/xpcom/tests/unit/test_nsIProcess_stress.js
@@ -0,0 +1,27 @@
+function run_test() {
+ set_process_running_environment();
+
+ var file = get_test_program("TestQuickReturn");
+ var thread = Components.classes["@mozilla.org/thread-manager;1"]
+ .getService().currentThread;
+
+ for (var i = 0; i < 1000; i++) {
+ var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(file);
+
+ process.run(false, [], 0);
+
+ try {
+ process.kill();
+ }
+ catch (e) { }
+
+ // We need to ensure that we process any events on the main thread -
+ // this allow threads to clean up properly and avoid out of memory
+ // errors during the test.
+ while (thread.hasPendingEvents())
+ thread.processNextEvent(false);
+ }
+
+} \ No newline at end of file
diff --git a/xpcom/tests/unit/test_pipe.js b/xpcom/tests/unit/test_pipe.js
new file mode 100644
index 000000000..c16b33ab0
--- /dev/null
+++ b/xpcom/tests/unit/test_pipe.js
@@ -0,0 +1,63 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var CC = Components.Constructor;
+
+var Pipe = CC("@mozilla.org/pipe;1", "nsIPipe", "init");
+
+function run_test()
+{
+ test_not_initialized();
+ test_ends_are_threadsafe();
+}
+
+function test_not_initialized()
+{
+ var p = Cc["@mozilla.org/pipe;1"]
+ .createInstance(Ci.nsIPipe);
+ try
+ {
+ var dummy = p.outputStream;
+ throw Cr.NS_ERROR_FAILURE;
+ }
+ catch (e)
+ {
+ if (e.result != Cr.NS_ERROR_NOT_INITIALIZED)
+ do_throw("using a pipe before initializing it should throw NS_ERROR_NOT_INITIALIZED");
+ }
+}
+
+function test_ends_are_threadsafe()
+{
+ var p, is, os;
+
+ p = new Pipe(true, true, 1024, 1, null);
+ is = p.inputStream.QueryInterface(Ci.nsIClassInfo);
+ os = p.outputStream.QueryInterface(Ci.nsIClassInfo);
+ do_check_true(Boolean(is.flags & Ci.nsIClassInfo.THREADSAFE));
+ do_check_true(Boolean(os.flags & Ci.nsIClassInfo.THREADSAFE));
+
+ p = new Pipe(true, false, 1024, 1, null);
+ is = p.inputStream.QueryInterface(Ci.nsIClassInfo);
+ os = p.outputStream.QueryInterface(Ci.nsIClassInfo);
+ do_check_true(Boolean(is.flags & Ci.nsIClassInfo.THREADSAFE));
+ do_check_true(Boolean(os.flags & Ci.nsIClassInfo.THREADSAFE));
+
+ p = new Pipe(false, true, 1024, 1, null);
+ is = p.inputStream.QueryInterface(Ci.nsIClassInfo);
+ os = p.outputStream.QueryInterface(Ci.nsIClassInfo);
+ do_check_true(Boolean(is.flags & Ci.nsIClassInfo.THREADSAFE));
+ do_check_true(Boolean(os.flags & Ci.nsIClassInfo.THREADSAFE));
+
+ p = new Pipe(false, false, 1024, 1, null);
+ is = p.inputStream.QueryInterface(Ci.nsIClassInfo);
+ os = p.outputStream.QueryInterface(Ci.nsIClassInfo);
+ do_check_true(Boolean(is.flags & Ci.nsIClassInfo.THREADSAFE));
+ do_check_true(Boolean(os.flags & Ci.nsIClassInfo.THREADSAFE));
+}
diff --git a/xpcom/tests/unit/test_process_directives.js b/xpcom/tests/unit/test_process_directives.js
new file mode 100644
index 000000000..807246f46
--- /dev/null
+++ b/xpcom/tests/unit/test_process_directives.js
@@ -0,0 +1,25 @@
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+
+Components.utils.import("resource:///modules/Services.jsm");
+
+function run_test()
+{
+ Components.manager.autoRegister(do_get_file("data/process_directive.manifest"));
+
+ let isChild = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
+
+ if (isChild) {
+ do_check_false("@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1" in Cc);
+ } else {
+ let svc = Cc["@mozilla.org/xpcom/tests/MainProcessDirectiveTest;1"].createInstance(Ci.nsISupportsString);
+ do_check_eq(svc.data, "main process");
+ }
+
+ if (!isChild) {
+ do_check_false("@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1" in Cc);
+ } else {
+ let svc = Cc["@mozilla.org/xpcom/tests/ChildProcessDirectiveTest;1"].createInstance(Ci.nsISupportsString);
+ do_check_eq(svc.data, "child process");
+ }
+}
diff --git a/xpcom/tests/unit/test_process_directives_child.js b/xpcom/tests/unit/test_process_directives_child.js
new file mode 100644
index 000000000..dca63b356
--- /dev/null
+++ b/xpcom/tests/unit/test_process_directives_child.js
@@ -0,0 +1,3 @@
+function run_test() {
+ run_test_in_child("test_process_directives.js");
+}
diff --git a/xpcom/tests/unit/test_seek_multiplex.js b/xpcom/tests/unit/test_seek_multiplex.js
new file mode 100644
index 000000000..31232d134
--- /dev/null
+++ b/xpcom/tests/unit/test_seek_multiplex.js
@@ -0,0 +1,173 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var CC = Components.Constructor;
+var Cc = Components.classes;
+
+// The string we use as data.
+const data = "0123456789";
+// Number of streams in the multiplex stream.
+const count = 10;
+
+function test_multiplex_streams() {
+ var MultiplexStream = CC("@mozilla.org/io/multiplex-input-stream;1",
+ "nsIMultiplexInputStream");
+ do_check_eq(1, 1);
+
+ var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
+ "nsIBinaryInputStream");
+ var BinaryOutputStream = Components.Constructor("@mozilla.org/binaryoutputstream;1",
+ "nsIBinaryOutputStream",
+ "setOutputStream");
+ var multiplex = new MultiplexStream();
+ for (var i = 0; i < count; ++i) {
+ let s = Cc["@mozilla.org/io/string-input-stream;1"]
+ .createInstance(Ci.nsIStringInputStream);
+ s.setData(data, data.length);
+
+ multiplex.appendStream(s);
+ }
+ var seekable = multiplex.QueryInterface(Ci.nsISeekableStream);
+ var sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(seekable);
+ // Read some data.
+ var readData = sis.read(20);
+ do_check_eq(readData, data + data);
+ // -- Tests for NS_SEEK_SET
+ // Seek to a non-zero, non-stream-boundary offset.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 2);
+ do_check_eq(seekable.tell(), 2);
+ do_check_eq(seekable.available(), 98);
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 9);
+ do_check_eq(seekable.tell(), 9);
+ do_check_eq(seekable.available(), 91);
+ // Seek across stream boundary.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 35);
+ do_check_eq(seekable.tell(), 35);
+ do_check_eq(seekable.available(), 65);
+ readData = sis.read(5);
+ do_check_eq(readData, data.slice(5));
+ do_check_eq(seekable.available(), 60);
+ // Seek at stream boundaries.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 40);
+ do_check_eq(seekable.tell(), 40);
+ do_check_eq(seekable.available(), 60);
+ readData = sis.read(10);
+ do_check_eq(readData, data);
+ do_check_eq(seekable.tell(), 50);
+ do_check_eq(seekable.available(), 50);
+ // Rewind and read across streams.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 39);
+ do_check_eq(seekable.tell(), 39);
+ do_check_eq(seekable.available(), 61);
+ readData = sis.read(11);
+ do_check_eq(readData, data.slice(9) + data);
+ do_check_eq(seekable.tell(), 50);
+ do_check_eq(seekable.available(), 50);
+ // Rewind to the beginning.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
+ do_check_eq(seekable.tell(), 0);
+ do_check_eq(seekable.available(), 100);
+ // Seek to some random location
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 50);
+ // -- Tests for NS_SEEK_CUR
+ // Positive seek.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, 15);
+ do_check_eq(seekable.tell(), 65);
+ do_check_eq(seekable.available(), 35);
+ readData = sis.read(10);
+ do_check_eq(readData, data.slice(5) + data.slice(0, 5));
+ do_check_eq(seekable.tell(), 75);
+ do_check_eq(seekable.available(), 25);
+ // Negative seek.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -15);
+ do_check_eq(seekable.tell(), 60);
+ do_check_eq(seekable.available(), 40);
+ readData = sis.read(10);
+ do_check_eq(readData, data);
+ do_check_eq(seekable.tell(), 70);
+ do_check_eq(seekable.available(), 30);
+
+ // -- Tests for NS_SEEK_END
+ // Normal read.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, -5);
+ do_check_eq(seekable.tell(), data.length * count - 5);
+ readData = sis.read(5);
+ do_check_eq(readData, data.slice(5));
+ do_check_eq(seekable.tell(), data.length * count);
+ // Read across streams.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, -15);
+ do_check_eq(seekable.tell(), data.length * count - 15);
+ readData = sis.read(15);
+ do_check_eq(readData, data.slice(5) + data);
+ do_check_eq(seekable.tell(), data.length * count);
+
+ // -- Try to do various edge cases
+ // Forward seek from the end, should throw.
+ var caught = false;
+ try {
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, 15);
+ } catch(e) {
+ caught = true;
+ }
+ do_check_eq(caught, true);
+ do_check_eq(seekable.tell(), data.length * count);
+ // Backward seek from the beginning, should be clamped.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
+ do_check_eq(seekable.tell(), 0);
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -15);
+ do_check_eq(seekable.tell(), 0);
+ // Seek too far: should be clamped.
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
+ do_check_eq(seekable.tell(), 0);
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, 3 * data.length * count);
+ do_check_eq(seekable.tell(), 100);
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, data.length * count);
+ do_check_eq(seekable.tell(), 100);
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -2 * data.length * count);
+ do_check_eq(seekable.tell(), 0);
+}
+
+function test_multiplex_bug797871() {
+
+ var data = "1234567890123456789012345678901234567890";
+
+ var MultiplexStream = CC("@mozilla.org/io/multiplex-input-stream;1",
+ "nsIMultiplexInputStream");
+ do_check_eq(1, 1);
+
+ var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1",
+ "nsIBinaryInputStream");
+ var BinaryOutputStream = Components.Constructor("@mozilla.org/binaryoutputstream;1",
+ "nsIBinaryOutputStream",
+ "setOutputStream");
+ var multiplex = new MultiplexStream();
+ let s = Cc["@mozilla.org/io/string-input-stream;1"]
+ .createInstance(Ci.nsIStringInputStream);
+ s.setData(data, data.length);
+
+ multiplex.appendStream(s);
+
+ var seekable = multiplex.QueryInterface(Ci.nsISeekableStream);
+ var sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(seekable);
+
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 8);
+ do_check_eq(seekable.tell(), 8);
+ readData = sis.read(2);
+ do_check_eq(seekable.tell(), 10);
+
+ seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 20);
+ do_check_eq(seekable.tell(), 20);
+}
+
+function run_test() {
+ test_multiplex_streams();
+ test_multiplex_bug797871();
+}
+
diff --git a/xpcom/tests/unit/test_storagestream.js b/xpcom/tests/unit/test_storagestream.js
new file mode 100644
index 000000000..33fdc2202
--- /dev/null
+++ b/xpcom/tests/unit/test_storagestream.js
@@ -0,0 +1,162 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+
+function run_test()
+{
+ test1();
+ test2();
+ test3();
+ test4();
+}
+
+/**
+ * Checks that getting an input stream from a storage stream which has never had
+ * anything written to it throws a not-initialized exception.
+ */
+function test1()
+{
+ var ss = Cc["@mozilla.org/storagestream;1"]
+ .createInstance(Ci.nsIStorageStream);
+ ss.init(1024, 1024, null);
+
+ var out = ss.getOutputStream(0);
+ var inp2 = ss.newInputStream(0);
+ do_check_eq(inp2.available(), 0);
+ do_check_true(inp2.isNonBlocking());
+
+ var sis =
+ Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(inp2);
+
+ var threw = false;
+ try {
+ sis.read(1);
+ } catch (ex if ex.result == Cr.NS_BASE_STREAM_WOULD_BLOCK) {
+ threw = true;
+ }
+ do_check_true(threw);
+}
+
+/**
+ * Checks that getting an input stream from a storage stream to which 0 bytes of
+ * data have been explicitly written doesn't throw an exception.
+ */
+function test2()
+{
+ var ss = Cc["@mozilla.org/storagestream;1"]
+ .createInstance(Ci.nsIStorageStream);
+ ss.init(1024, 1024, null);
+
+ var out = ss.getOutputStream(0);
+ out.write("", 0);
+ try
+ {
+ var inp2 = ss.newInputStream(0);
+ }
+ catch (e)
+ {
+ do_throw("shouldn't throw exception when new input stream created");
+ }
+}
+
+/**
+ * Checks that reading any non-zero amount of data from a storage stream
+ * which has had 0 bytes written to it explicitly works correctly.
+ */
+function test3()
+{
+ var ss = Cc["@mozilla.org/storagestream;1"]
+ .createInstance(Ci.nsIStorageStream);
+ ss.init(1024, 1024, null);
+
+ var out = ss.getOutputStream(0);
+ out.write("", 0);
+ try
+ {
+ var inp = ss.newInputStream(0);
+ }
+ catch (e)
+ {
+ do_throw("newInputStream(0) shouldn't throw if write() is called: " + e);
+ }
+
+ do_check_true(inp.isNonBlocking(), "next test expects a non-blocking stream");
+
+ try
+ {
+ var threw = false;
+ var bis = BIS(inp);
+ var dummy = bis.readByteArray(5);
+ }
+ catch (e)
+ {
+ if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK)
+ do_throw("wrong error thrown: " + e);
+ threw = true;
+ }
+ do_check_true(threw,
+ "should have thrown (nsStorageInputStream is nonblocking)");
+}
+
+/**
+ * Basic functionality test for storagestream: write data to it, get an input
+ * stream, and read the data back to see that it matches.
+ */
+function test4()
+{
+ var bytes = [65, 66, 67, 68, 69, 70, 71, 72, 73, 74];
+
+ var ss = Cc["@mozilla.org/storagestream;1"]
+ .createInstance(Ci.nsIStorageStream);
+ ss.init(1024, 1024, null);
+
+ var outStream = ss.getOutputStream(0);
+
+ var bos = Cc["@mozilla.org/binaryoutputstream;1"]
+ .createInstance(Ci.nsIBinaryOutputStream);
+ bos.setOutputStream(outStream);
+
+ bos.writeByteArray(bytes, bytes.length);
+ bos.close();
+
+ var inp = ss.newInputStream(0);
+ var bis = BIS(inp);
+
+ var count = 0;
+ while (count < bytes.length)
+ {
+ var data = bis.read8(1);
+ do_check_eq(data, bytes[count++]);
+ }
+
+ var threw = false;
+ try
+ {
+ data = bis.read8(1);
+ }
+ catch (e)
+ {
+ if (e.result != Cr.NS_ERROR_FAILURE)
+ do_throw("wrong error thrown: " + e);
+ threw = true;
+ }
+ if (!threw)
+ do_throw("should have thrown but instead returned: '" + data + "'");
+}
+
+
+function BIS(input)
+{
+ var bis = Cc["@mozilla.org/binaryinputstream;1"]
+ .createInstance(Ci.nsIBinaryInputStream);
+ bis.setInputStream(input);
+ return bis;
+}
diff --git a/xpcom/tests/unit/test_streams.js b/xpcom/tests/unit/test_streams.js
new file mode 100644
index 000000000..e668cb8d5
--- /dev/null
+++ b/xpcom/tests/unit/test_streams.js
@@ -0,0 +1,157 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Ci = Components.interfaces;
+var Cr = Components.results;
+var CC = Components.Constructor;
+
+var Pipe = CC("@mozilla.org/pipe;1",
+ "nsIPipe",
+ "init");
+var BinaryOutput = CC("@mozilla.org/binaryoutputstream;1",
+ "nsIBinaryOutputStream",
+ "setOutputStream");
+var BinaryInput = CC("@mozilla.org/binaryinputstream;1",
+ "nsIBinaryInputStream",
+ "setInputStream");
+
+/**
+ * Binary stream tests.
+ */
+function test_binary_streams() {
+ var p, is, os;
+
+ p = new Pipe(false, false, 1024, 1, null);
+ is = new BinaryInput(p.inputStream);
+ os = new BinaryOutput(p.outputStream);
+
+ const LargeNum = Math.pow(2, 18) + Math.pow(2, 12) + 1;
+ const HugeNum = Math.pow(2, 62);
+ const HelloStr = "Hello World";
+ const HelloArray = Array.map(HelloStr, function(c) {return c.charCodeAt(0)});
+ var countObj = {};
+ var msg = {};
+ var buffer = new ArrayBuffer(HelloArray.length);
+
+ // Test reading immediately after writing.
+ os.writeBoolean(true);
+ do_check_eq(is.readBoolean(), true);
+ os.write8(4);
+ do_check_eq(is.read8(), 4);
+ os.write16(4);
+ do_check_eq(is.read16(), 4);
+ os.write16(1024);
+ do_check_eq(is.read16(), 1024);
+ os.write32(7);
+ do_check_eq(is.read32(), 7);
+ os.write32(LargeNum);
+ do_check_eq(is.read32(), LargeNum);
+ os.write64(LargeNum);
+ do_check_eq(is.read64(), LargeNum);
+ os.write64(1024);
+ do_check_eq(is.read64(), 1024);
+ os.write64(HugeNum);
+ do_check_eq(is.read64(), HugeNum);
+ os.writeFloat(2.5);
+ do_check_eq(is.readFloat(), 2.5);
+// os.writeDouble(Math.SQRT2);
+// do_check_eq(is.readDouble(), Math.SQRT2);
+ os.writeStringZ("Mozilla");
+ do_check_eq(is.readCString(), "Mozilla");
+ os.writeWStringZ("Gecko");
+ do_check_eq(is.readString(), "Gecko");
+ os.writeBytes(HelloStr, HelloStr.length);
+ do_check_eq(is.available(), HelloStr.length);
+ msg = is.readBytes(HelloStr.length);
+ do_check_eq(msg, HelloStr);
+ msg = null;
+ countObj.value = -1;
+ os.writeByteArray(HelloArray, HelloArray.length);
+ do_check_eq(is.available(), HelloStr.length);
+ msg = is.readByteArray(HelloStr.length)
+ do_check_eq(typeof msg, typeof HelloArray);
+ do_check_eq(msg.toSource(), HelloArray.toSource());
+ do_check_eq(is.available(), 0);
+ os.writeByteArray(HelloArray, HelloArray.length);
+ do_check_eq(is.readArrayBuffer(buffer.byteLength, buffer), HelloArray.length);
+ do_check_eq([...(new Uint8Array(buffer))].toSource(), HelloArray.toSource());
+ do_check_eq(is.available(), 0);
+
+ // Test writing in one big chunk.
+ os.writeBoolean(true);
+ os.write8(4);
+ os.write16(4);
+ os.write16(1024);
+ os.write32(7);
+ os.write32(LargeNum);
+ os.write64(LargeNum);
+ os.write64(1024);
+ os.write64(HugeNum);
+ os.writeFloat(2.5);
+// os.writeDouble(Math.SQRT2);
+ os.writeStringZ("Mozilla");
+ os.writeWStringZ("Gecko");
+ os.writeBytes(HelloStr, HelloStr.length);
+ os.writeByteArray(HelloArray, HelloArray.length);
+ // Available should not be zero after a long write like this.
+ do_check_neq(is.available(), 0);
+
+ // Test reading in one big chunk.
+ do_check_eq(is.readBoolean(), true);
+ do_check_eq(is.read8(), 4);
+ do_check_eq(is.read16(), 4);
+ do_check_eq(is.read16(), 1024);
+ do_check_eq(is.read32(), 7);
+ do_check_eq(is.read32(), LargeNum);
+ do_check_eq(is.read64(), LargeNum);
+ do_check_eq(is.read64(), 1024);
+ do_check_eq(is.read64(), HugeNum);
+ do_check_eq(is.readFloat(), 2.5);
+// do_check_eq(is.readDouble(), Math.SQRT2);
+ do_check_eq(is.readCString(), "Mozilla");
+ do_check_eq(is.readString(), "Gecko");
+ // Remember, we wrote HelloStr twice - once as a string, and then as an array.
+ do_check_eq(is.available(), HelloStr.length * 2);
+ msg = is.readBytes(HelloStr.length);
+ do_check_eq(msg, HelloStr);
+ msg = null;
+ countObj.value = -1;
+ do_check_eq(is.available(), HelloStr.length);
+ msg = is.readByteArray(HelloStr.length)
+ do_check_eq(typeof msg, typeof HelloArray);
+ do_check_eq(msg.toSource(), HelloArray.toSource());
+ do_check_eq(is.available(), 0);
+
+ // Test for invalid actions.
+ os.close();
+ is.close();
+
+ try {
+ os.writeBoolean(false);
+ do_throw("Not reached!");
+ } catch (e if (e instanceof Ci.nsIException &&
+ e.result == Cr.NS_BASE_STREAM_CLOSED)) {
+ // do nothing
+ }
+
+ try {
+ is.available();
+ do_throw("Not reached!");
+ } catch (e if (e instanceof Ci.nsIException &&
+ e.result == Cr.NS_BASE_STREAM_CLOSED)) {
+ // do nothing
+ }
+
+ try {
+ is.readBoolean();
+ do_throw("Not reached!");
+ } catch (e if (e instanceof Ci.nsIException &&
+ e.result == Cr.NS_ERROR_FAILURE)) {
+ // do nothing
+ }
+}
+
+function run_test() {
+ test_binary_streams();
+}
diff --git a/xpcom/tests/unit/test_stringstream.js b/xpcom/tests/unit/test_stringstream.js
new file mode 100644
index 000000000..60503a58f
--- /dev/null
+++ b/xpcom/tests/unit/test_stringstream.js
@@ -0,0 +1,23 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cr = Components.results;
+
+function run_test()
+{
+ var s = Cc["@mozilla.org/io/string-input-stream;1"]
+ .createInstance(Ci.nsIStringInputStream);
+ var body = "This is a test";
+ s.setData(body, body.length);
+ do_check_eq(s.available(), body.length);
+
+ var sis = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ sis.init(s);
+
+ do_check_eq(sis.read(body.length), body);
+}
diff --git a/xpcom/tests/unit/test_symlinks.js b/xpcom/tests/unit/test_symlinks.js
new file mode 100644
index 000000000..a615af8d5
--- /dev/null
+++ b/xpcom/tests/unit/test_symlinks.js
@@ -0,0 +1,144 @@
+const CWD = do_get_cwd();
+
+const DIR_TARGET = "target";
+const DIR_LINK = "link";
+const DIR_LINK_LINK = "link_link";
+const FILE_TARGET = "target.txt";
+const FILE_LINK = "link.txt";
+const FILE_LINK_LINK = "link_link.txt";
+
+const DOES_NOT_EXIST = "doesnotexist";
+const DANGLING_LINK = "dangling_link";
+const LOOP_LINK = "loop_link";
+
+const nsIFile = Components.interfaces.nsIFile;
+
+var process;
+function createSymLink(from, to) {
+ if (!process) {
+ var ln = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ ln.initWithPath("/bin/ln");
+
+ process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ process.init(ln);
+ }
+
+ const args = ["-s", from, to];
+ process.run(true, args, args.length);
+ do_check_eq(process.exitValue, 0);
+}
+
+function makeSymLink(from, toName, relative) {
+ var to = from.parent;
+ to.append(toName);
+
+ if (relative) {
+ createSymLink(from.leafName, to.path);
+ }
+ else {
+ createSymLink(from.path, to.path);
+ }
+
+ do_check_true(to.isSymlink());
+
+ print("---");
+ print(from.path);
+ print(to.path);
+ print(to.target);
+
+ if (from.leafName != DOES_NOT_EXIST && from.isSymlink()) {
+ // XXXjag wish I could set followLinks to false so we'd just get
+ // the symlink's direct target instead of the final target.
+ do_check_eq(from.target, to.target);
+ }
+ else {
+ do_check_eq(from.path, to.target);
+ }
+
+ return to;
+}
+
+function setupTestDir(testDir, relative) {
+ var targetDir = testDir.clone();
+ targetDir.append(DIR_TARGET);
+
+ if (testDir.exists()) {
+ testDir.remove(true);
+ }
+ do_check_true(!testDir.exists());
+
+ testDir.create(nsIFile.DIRECTORY_TYPE, 0o777);
+
+ targetDir.create(nsIFile.DIRECTORY_TYPE, 0o777);
+
+ var targetFile = testDir.clone();
+ targetFile.append(FILE_TARGET);
+ targetFile.create(nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ var imaginary = testDir.clone();
+ imaginary.append(DOES_NOT_EXIST);
+
+ var loop = testDir.clone();
+ loop.append(LOOP_LINK);
+
+ var dirLink = makeSymLink(targetDir, DIR_LINK, relative);
+ var fileLink = makeSymLink(targetFile, FILE_LINK, relative);
+
+ makeSymLink(dirLink, DIR_LINK_LINK, relative);
+ makeSymLink(fileLink, FILE_LINK_LINK, relative);
+
+ makeSymLink(imaginary, DANGLING_LINK, relative);
+
+ try {
+ makeSymLink(loop, LOOP_LINK, relative);
+ do_check_true(false);
+ }
+ catch (e) {
+ }
+}
+
+function createSpaces(dirs, files, links) {
+ function longest(a, b) {
+ return a.length > b.length ? a : b;
+ }
+ return dirs.concat(files, links).reduce(longest, "").replace(/./g, " ");
+}
+
+function testSymLinks(testDir, relative) {
+ setupTestDir(testDir, relative);
+
+ const dirLinks = [DIR_LINK, DIR_LINK_LINK];
+ const fileLinks = [FILE_LINK, FILE_LINK_LINK];
+ const otherLinks = [DANGLING_LINK, LOOP_LINK];
+ const dirs = [DIR_TARGET].concat(dirLinks);
+ const files = [FILE_TARGET].concat(fileLinks);
+ const links = otherLinks.concat(dirLinks, fileLinks);
+
+ const spaces = createSpaces(dirs, files, links);
+ const bools = {false: " false", true: " true "};
+ print(spaces + " dir file symlink");
+ var dirEntries = testDir.directoryEntries;
+ while (dirEntries.hasMoreElements()) {
+ const file = dirEntries.getNext().QueryInterface(nsIFile);
+ const name = file.leafName;
+ print(name + spaces.substring(name.length) + bools[file.isDirectory()] +
+ bools[file.isFile()] + bools[file.isSymlink()]);
+ do_check_eq(file.isDirectory(), dirs.indexOf(name) != -1);
+ do_check_eq(file.isFile(), files.indexOf(name) != -1);
+ do_check_eq(file.isSymlink(), links.indexOf(name) != -1);
+ }
+}
+
+function run_test() {
+ // Skip this test on Windows
+ if (mozinfo.os == "win")
+ return;
+
+ var testDir = CWD;
+ testDir.append("test_symlinks");
+
+ testSymLinks(testDir, false);
+ testSymLinks(testDir, true);
+}
diff --git a/xpcom/tests/unit/test_systemInfo.js b/xpcom/tests/unit/test_systemInfo.js
new file mode 100644
index 000000000..58fa8042c
--- /dev/null
+++ b/xpcom/tests/unit/test_systemInfo.js
@@ -0,0 +1,20 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+function run_test() {
+ const PROPERTIES = ["name", "host", "arch", "version", "pagesize",
+ "pageshift", "memmapalign", "cpucount", "memsize"];
+ let sysInfo = Components.classes["@mozilla.org/system-info;1"].
+ getService(Components.interfaces.nsIPropertyBag2);
+
+ PROPERTIES.forEach(function(aPropertyName) {
+ print("Testing property: " + aPropertyName);
+ let value = sysInfo.getProperty(aPropertyName);
+ do_check_true(!!value);
+ });
+
+ // This property must exist, but its value might be zero.
+ print("Testing property: umask")
+ do_check_eq(typeof sysInfo.getProperty("umask"), "number");
+}
diff --git a/xpcom/tests/unit/test_versioncomparator.js b/xpcom/tests/unit/test_versioncomparator.js
new file mode 100644
index 000000000..35f8f6eee
--- /dev/null
+++ b/xpcom/tests/unit/test_versioncomparator.js
@@ -0,0 +1,59 @@
+// Versions to test listed in ascending order, none can be equal
+var comparisons = [
+ "0.9",
+ "0.9.1",
+ "1.0pre1",
+ "1.0pre2",
+ "1.0",
+ "1.1pre",
+ "1.1pre1a",
+ "1.1pre1",
+ "1.1pre10a",
+ "1.1pre10",
+ "1.1",
+ "1.1.0.1",
+ "1.1.1",
+ "1.1.*",
+ "1.*",
+ "2.0",
+ "2.1",
+ "3.0.-1",
+ "3.0"
+];
+
+// Every version in this list means the same version number
+var equality = [
+ "1.1pre",
+ "1.1pre0",
+ "1.0+"
+];
+
+function run_test()
+{
+ var vc = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
+ .getService(Components.interfaces.nsIVersionComparator);
+
+ for (var i = 0; i < comparisons.length; i++) {
+ for (var j = 0; j < comparisons.length; j++) {
+ var result = vc.compare(comparisons[i], comparisons[j]);
+ if (i == j) {
+ if (result != 0)
+ do_throw(comparisons[i] + " should be the same as itself");
+ }
+ else if (i < j) {
+ if (!(result < 0))
+ do_throw(comparisons[i] + " should be less than " + comparisons[j]);
+ }
+ else if (!(result > 0)) {
+ do_throw(comparisons[i] + " should be greater than " + comparisons[j]);
+ }
+ }
+ }
+
+ for (i = 0; i < equality.length; i++) {
+ for (j = 0; j < equality.length; j++) {
+ if (vc.compare(equality[i], equality[j]) != 0)
+ do_throw(equality[i] + " should equal " + equality[j]);
+ }
+ }
+}
diff --git a/xpcom/tests/unit/test_windows_cmdline_file.js b/xpcom/tests/unit/test_windows_cmdline_file.js
new file mode 100644
index 000000000..4a3a6cc5f
--- /dev/null
+++ b/xpcom/tests/unit/test_windows_cmdline_file.js
@@ -0,0 +1,21 @@
+let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+
+let executableFile = Services.dirsvc.get("CurProcD", Ci.nsIFile);
+executableFile.append("xpcshell.exe");
+function run_test() {
+ let quote = '"'; // Windows' cmd processor doesn't actually use single quotes.
+ for (let suffix of ["", " -osint", ` --blah "%PROGRAMFILES%"`]) {
+ let cmdline = quote + executableFile.path + quote + suffix;
+ do_print(`Testing with ${cmdline}`);
+ let f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFileWin);
+ f.initWithCommandLine(cmdline);
+ Assert.equal(f.path, executableFile.path, "Should be able to recover executable path");
+ }
+
+ let f = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFileWin);
+ f.initWithCommandLine("%ComSpec% -c echo 'hi'");
+ let cmd = Services.dirsvc.get("SysD", Ci.nsIFile);
+ cmd.append("cmd.exe");
+ Assert.equal(f.path, cmd.path, "Should be able to replace env vars.");
+}
diff --git a/xpcom/tests/unit/test_windows_registry.js b/xpcom/tests/unit/test_windows_registry.js
new file mode 100644
index 000000000..9a17678f8
--- /dev/null
+++ b/xpcom/tests/unit/test_windows_registry.js
@@ -0,0 +1,205 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Cr = Components.results;
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+const CC = Components.Constructor;
+
+const nsIWindowsRegKey = Ci.nsIWindowsRegKey;
+let regKeyComponent = Cc["@mozilla.org/windows-registry-key;1"];
+
+function run_test()
+{
+ //* create a key structure in a spot that's normally writable (somewhere under HKCU).
+ let testKey = regKeyComponent.createInstance(nsIWindowsRegKey);
+
+ // If it's already present because a previous test crashed or didn't clean up properly, clean it up first.
+ let keyName = BASE_PATH + "\\" + TESTDATA_KEYNAME;
+ setup_test_run(testKey, keyName);
+
+ //* test that the write* functions write stuff
+ test_writing_functions(testKey);
+
+ //* check that the valueCount/getValueName functions work for the values we just wrote
+ test_value_functions(testKey);
+
+ //* check that the get* functions work for the values we just wrote.
+ test_reading_functions(testKey);
+
+ //* check that the get* functions fail with the right exception codes if we ask for the wrong type or if the value name doesn't exist at all
+ test_invalidread_functions(testKey);
+
+ //* check that creating/enumerating/deleting child keys works
+ test_childkey_functions(testKey);
+
+ test_watching_functions(testKey);
+
+ //* clean up
+ cleanup_test_run(testKey, keyName);
+}
+
+function setup_test_run(testKey, keyName)
+{
+ do_print("Setup test run");
+ try {
+ testKey.open(nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, keyName, nsIWindowsRegKey.ACCESS_READ);
+ do_print("Test key exists. Needs cleanup.");
+ cleanup_test_run(testKey, keyName);
+ }
+ catch (e if (e instanceof Ci.nsIException && e.result == Cr.NS_ERROR_FAILURE))
+ {
+ }
+
+ testKey.create(nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, keyName, nsIWindowsRegKey.ACCESS_ALL);
+}
+
+function test_writing_functions(testKey)
+{
+ strictEqual(testKey.valueCount, 0);
+
+ strictEqual(testKey.hasValue(TESTDATA_STRNAME), false);
+ testKey.writeStringValue(TESTDATA_STRNAME, TESTDATA_STRVALUE);
+ strictEqual(testKey.hasValue(TESTDATA_STRNAME), true);
+
+ strictEqual(testKey.hasValue(TESTDATA_INTNAME), false);
+ testKey.writeIntValue(TESTDATA_INTNAME, TESTDATA_INTVALUE);
+
+ strictEqual(testKey.hasValue(TESTDATA_INT64NAME), false);
+ testKey.writeInt64Value(TESTDATA_INT64NAME, TESTDATA_INT64VALUE);
+
+ strictEqual(testKey.hasValue(TESTDATA_BINARYNAME), false);
+ testKey.writeBinaryValue(TESTDATA_BINARYNAME, TESTDATA_BINARYVALUE);
+}
+
+function test_value_functions(testKey)
+{
+ strictEqual(testKey.valueCount, 4);
+ strictEqual(testKey.getValueName(0), TESTDATA_STRNAME);
+ strictEqual(testKey.getValueName(1), TESTDATA_INTNAME);
+ strictEqual(testKey.getValueName(2), TESTDATA_INT64NAME);
+ strictEqual(testKey.getValueName(3), TESTDATA_BINARYNAME);
+}
+
+function test_reading_functions(testKey)
+{
+ strictEqual(testKey.getValueType(TESTDATA_STRNAME), nsIWindowsRegKey.TYPE_STRING);
+ strictEqual(testKey.readStringValue(TESTDATA_STRNAME), TESTDATA_STRVALUE);
+
+ strictEqual(testKey.getValueType(TESTDATA_INTNAME), nsIWindowsRegKey.TYPE_INT);
+ strictEqual(testKey.readIntValue(TESTDATA_INTNAME), TESTDATA_INTVALUE);
+
+ strictEqual(testKey.getValueType(TESTDATA_INT64NAME), nsIWindowsRegKey.TYPE_INT64);
+ strictEqual( testKey.readInt64Value(TESTDATA_INT64NAME), TESTDATA_INT64VALUE);
+
+ strictEqual(testKey.getValueType(TESTDATA_BINARYNAME), nsIWindowsRegKey.TYPE_BINARY);
+ strictEqual( testKey.readBinaryValue(TESTDATA_BINARYNAME), TESTDATA_BINARYVALUE);
+}
+
+function test_invalidread_functions(testKey)
+{
+ try {
+ testKey.readIntValue(TESTDATA_STRNAME);
+ do_throw("Reading an integer from a string registry value should throw.");
+ } catch (e if (e instanceof Ci.nsIException && e.result == Cr.NS_ERROR_FAILURE)) {
+ }
+
+ try {
+ let val = testKey.readStringValue(TESTDATA_INTNAME);
+ do_throw("Reading an string from an Int registry value should throw." + val);
+ } catch (e if (e instanceof Ci.nsIException && e.result == Cr.NS_ERROR_FAILURE)) {
+ }
+
+ try {
+ testKey.readStringValue(TESTDATA_INT64NAME);
+ do_throw("Reading an string from an Int64 registry value should throw.");
+ } catch (e if (e instanceof Ci.nsIException && e.result == Cr.NS_ERROR_FAILURE)) {
+ }
+
+ try {
+ testKey.readStringValue(TESTDATA_BINARYNAME);
+ do_throw("Reading a string from an Binary registry value should throw.");
+ } catch (e if (e instanceof Ci.nsIException && e.result == Cr.NS_ERROR_FAILURE)) {
+ }
+
+}
+
+function test_childkey_functions(testKey)
+{
+ strictEqual(testKey.childCount, 0);
+ strictEqual(testKey.hasChild(TESTDATA_CHILD_KEY), false);
+
+ let childKey = testKey.createChild(TESTDATA_CHILD_KEY, nsIWindowsRegKey.ACCESS_ALL);
+ childKey.close();
+
+ strictEqual(testKey.childCount, 1);
+ strictEqual(testKey.hasChild(TESTDATA_CHILD_KEY), true);
+ strictEqual(testKey.getChildName(0), TESTDATA_CHILD_KEY);
+
+ childKey = testKey.openChild(TESTDATA_CHILD_KEY, nsIWindowsRegKey.ACCESS_ALL);
+ testKey.removeChild(TESTDATA_CHILD_KEY);
+ strictEqual(testKey.childCount, 0);
+ strictEqual(testKey.hasChild(TESTDATA_CHILD_KEY), false);
+}
+
+function test_watching_functions(testKey)
+{
+ strictEqual(testKey.isWatching(), false);
+ strictEqual(testKey.hasChanged(), false);
+
+ testKey.startWatching(true);
+ strictEqual(testKey.isWatching(), true);
+
+ testKey.stopWatching();
+ strictEqual(testKey.isWatching(), false);
+
+ // Create a child key, and update a value
+ let childKey = testKey.createChild(TESTDATA_CHILD_KEY, nsIWindowsRegKey.ACCESS_ALL);
+ childKey.writeIntValue(TESTDATA_INTNAME, TESTDATA_INTVALUE);
+
+ // Start a recursive watch, and update the child's value
+ testKey.startWatching(true);
+ strictEqual(testKey.isWatching(), true);
+
+ childKey.writeIntValue(TESTDATA_INTNAME, 0);
+ strictEqual(testKey.hasChanged(), true);
+ testKey.stopWatching();
+ strictEqual(testKey.isWatching(), false);
+
+ childKey.removeValue(TESTDATA_INTNAME);
+ childKey.close();
+ testKey.removeChild(TESTDATA_CHILD_KEY);
+}
+
+function cleanup_test_run(testKey, keyName)
+{
+ do_print("Cleaning up test.");
+
+ for (var i = 0; i < testKey.childCount; i++) {
+ testKey.removeChild(testKey.getChildName(i));
+ }
+ testKey.close();
+
+ let baseKey = regKeyComponent.createInstance(nsIWindowsRegKey);
+ baseKey.open(nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, BASE_PATH, nsIWindowsRegKey.ACCESS_ALL);
+ baseKey.removeChild(TESTDATA_KEYNAME);
+ baseKey.close();
+}
+
+// Test data used above.
+const BASE_PATH = "SOFTWARE";
+const TESTDATA_KEYNAME = "TestRegXPC";
+const TESTDATA_STRNAME = "AString";
+const TESTDATA_STRVALUE = "The quick brown fox jumps over the lazy dog.";
+const TESTDATA_INTNAME = "AnInteger";
+const TESTDATA_INTVALUE = 65536;
+const TESTDATA_INT64NAME = "AnInt64";
+const TESTDATA_INT64VALUE = 9223372036854775807;
+const TESTDATA_BINARYNAME = "ABinary";
+const TESTDATA_BINARYVALUE = "She sells seashells by the seashore";
+const TESTDATA_CHILD_KEY = "TestChildKey";
diff --git a/xpcom/tests/unit/test_windows_shortcut.js b/xpcom/tests/unit/test_windows_shortcut.js
new file mode 100644
index 000000000..42cb023ff
--- /dev/null
+++ b/xpcom/tests/unit/test_windows_shortcut.js
@@ -0,0 +1,279 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
+
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var Cr = Components.results;
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cu = Components.utils;
+var CC = Components.Constructor;
+
+const LocalFile = CC("@mozilla.org/file/local;1", "nsILocalFile", "initWithPath");
+
+Cu.import("resource://gre/modules/Services.jsm");
+
+function run_test()
+{
+ // This test makes sense only on Windows, so skip it on other platforms
+ if ("nsILocalFileWin" in Ci
+ && do_get_cwd() instanceof Ci.nsILocalFileWin) {
+
+ let tempDir = Services.dirsvc.get("TmpD", Ci.nsILocalFile);
+ tempDir.append("shortcutTesting");
+ tempDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o666);
+
+ test_create_noargs(tempDir);
+ test_create_notarget(tempDir);
+ test_create_targetonly(tempDir);
+ test_create_normal(tempDir);
+ test_create_unicode(tempDir);
+
+ test_update_noargs(tempDir);
+ test_update_notarget(tempDir);
+ test_update_targetonly(tempDir);
+ test_update_normal(tempDir);
+ test_update_unicode(tempDir);
+ }
+}
+
+function test_create_noargs(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("shouldNeverExist.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ try
+ {
+ win.setShortcut();
+ do_throw("Creating a shortcut with no args (no target) should throw");
+ }
+ catch(e if (e instanceof Ci.nsIException
+ && e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST))
+ {
+
+ }
+}
+
+function test_create_notarget(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("shouldNeverExist2.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ try
+ {
+ win.setShortcut(null,
+ do_get_cwd(),
+ "arg1 arg2",
+ "Shortcut with no target");
+ do_throw("Creating a shortcut with no target should throw");
+ }
+ catch(e if (e instanceof Ci.nsIException
+ && e.result == Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST))
+ {
+
+ }
+}
+
+function test_create_targetonly(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile);
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(targetFile));
+}
+
+function test_create_normal(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "Ordinary shortcut");
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(targetFile))
+}
+
+function test_create_unicode(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("ṩhогТϾừ†Target.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(), // XXX: This should probably be a unicode dir
+ "ᾶṟǵ1 ᾶṟǵ2",
+ "ῧṋіḉѻₑ");
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(targetFile))
+}
+
+function test_update_noargs(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "A sample shortcut");
+
+ win.setShortcut();
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(targetFile))
+}
+
+function test_update_notarget(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "A sample shortcut");
+
+ win.setShortcut(null,
+ do_get_profile(),
+ "arg3 arg4",
+ "An UPDATED shortcut");
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(targetFile))
+}
+
+function test_update_targetonly(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "A sample shortcut");
+
+ let newTargetFile = tempDir.clone();
+ newTargetFile.append("shortcutTarget.exe");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ win.setShortcut(newTargetFile);
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(newTargetFile))
+}
+
+function test_update_normal(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "A sample shortcut");
+
+ let newTargetFile = tempDir.clone();
+ newTargetFile.append("shortcutTarget.exe");
+ newTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ win.setShortcut(newTargetFile,
+ do_get_profile(),
+ "arg3 arg4",
+ "An UPDATED shortcut");
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(newTargetFile))
+}
+
+function test_update_unicode(tempDir)
+{
+ let shortcutFile = tempDir.clone();
+ shortcutFile.append("createdShortcut.lnk");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let targetFile = tempDir.clone();
+ targetFile.append("shortcutTarget.exe");
+ targetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ let win = shortcutFile.QueryInterface(Ci.nsILocalFileWin);
+
+ win.setShortcut(targetFile,
+ do_get_cwd(),
+ "arg1 arg2",
+ "A sample shortcut");
+
+ let newTargetFile = tempDir.clone();
+ newTargetFile.append("ṩhогТϾừ†Target.exe");
+ shortcutFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+
+ win.setShortcut(newTargetFile,
+ do_get_profile(), // XXX: This should probably be unicode
+ "ᾶṟǵ3 ᾶṟǵ4",
+ "A ῧṋіḉѻₑ shortcut");
+
+ let shortcutTarget = LocalFile(shortcutFile.target);
+ do_check_true(shortcutTarget.equals(newTargetFile))
+}
diff --git a/xpcom/tests/unit/xpcomtest.manifest b/xpcom/tests/unit/xpcomtest.manifest
new file mode 100644
index 000000000..43a4931c6
--- /dev/null
+++ b/xpcom/tests/unit/xpcomtest.manifest
@@ -0,0 +1 @@
+interfaces xpcomtest.xpt
diff --git a/xpcom/tests/unit/xpcshell.ini b/xpcom/tests/unit/xpcshell.ini
new file mode 100644
index 000000000..cf8d93627
--- /dev/null
+++ b/xpcom/tests/unit/xpcshell.ini
@@ -0,0 +1,79 @@
+[DEFAULT]
+head = head_xpcom.js
+tail =
+support-files =
+ bug725015.manifest
+ compmgr_warnings.manifest
+ data/**
+ xpcomtest.xpt
+ xpcomtest.manifest
+generated-files =
+ xpcomtest.xpt
+
+[test_bug121341.js]
+[test_bug325418.js]
+[test_bug332389.js]
+[test_bug333505.js]
+[test_bug364285-1.js]
+# Bug 902073: test fails consistently on Android x86
+skip-if = os == "android"
+[test_bug374754.js]
+[test_bug476919.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_bug478086.js]
+[test_bug656331.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_bug725015.js]
+[test_debugger_malloc_size_of.js]
+[test_compmgr_warnings.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_file_createUnique.js]
+[test_file_equality.js]
+[test_hidden_files.js]
+[test_home.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_iniProcessor.js]
+[test_ioutil.js]
+[test_localfile.js]
+[test_mac_bundle.js]
+[test_nsIMutableArray.js]
+[test_nsIProcess.js]
+skip-if = os == "win" || os == "linux" # bug 582821, bug 1325609
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_nsIProcess_stress.js]
+skip-if = os == "win" # bug 676412, test isn't needed on windows and runs really slowly
+[test_pipe.js]
+[test_process_directives.js]
+skip-if = os == "android"
+[test_process_directives_child.js]
+skip-if = os == "android"
+[test_storagestream.js]
+[test_streams.js]
+[test_seek_multiplex.js]
+[test_stringstream.js]
+[test_symlinks.js]
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_systemInfo.js]
+# Bug 902081: test fails consistently on Android 2.2, passes on 4.0
+skip-if = os == "android"
+[test_versioncomparator.js]
+[test_comp_no_aslr.js]
+skip-if = os != "win"
+[test_windows_shortcut.js]
+skip-if = os != "win"
+[test_windows_cmdline_file.js]
+skip-if = os != "win"
+[test_bug745466.js]
+skip-if = os == "win"
+# Bug 676998: test fails consistently on Android
+fail-if = os == "android"
+[test_file_renameTo.js]
+[test_notxpcom_scriptable.js]
+[test_windows_registry.js]
+skip-if = os != "win"