You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by js...@apache.org on 2014/07/07 23:43:51 UTC

[45/51] [partial] CB-7087 Retire blackberry10/ directory

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/configUriOrigin.xml
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/configUriOrigin.xml b/bin/test/cordova/unit/configUriOrigin.xml
new file mode 100644
index 0000000..7635682
--- /dev/null
+++ b/bin/test/cordova/unit/configUriOrigin.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<widget xmlns=" http://www.w3.org/ns/widgets"
+        xmlns:rim="http://www.blackberry.com/ns/widgets"
+        version="1.0.0"
+        id="My WidgetId"
+        rim:header="RIM-Widget:rim/widget"
+        rim:userAgent="A Test-User-Agent/(Blackberry-Agent)">
+    <name>Demo</name>
+    <content src="local:///startPage.html"/>
+    <author rim:copyright="No Copyright"
+            href="http://www.rim.com/"
+            email = "author@rim.com">Research In Motion Ltd.</author>
+    <description>This app does everything.</description>
+    <license href="http://www.apache.org/licenses/LICENSE-2.0">My License</license>
+    <icon src="test.png" />
+    <rim:permissions>
+        <rim:permit>access_shared</rim:permit>
+        <rim:permit>read_geolocation</rim:permit>
+        <rim:permit>use_camera</rim:permit>
+    </rim:permissions>
+    <feature id="blackberry.app.orientation">
+        <param name="mode" value="portrait" />
+        <param name="other" value="portrait" />
+      </feature>
+    <feature id="blackberry.app" required="true" version="1.0.0.0">
+        <param name="childBrowser" value="disable" />
+        <param name="websecurity" value="disable" />
+        <param name="popupBlocker" value="enable" />
+    </feature>
+    <feature id="blackberry.system" required="true" version="1.0.0.3"/>
+    <access uri="http://www.somedomain1.com" subdomains="true">
+        <feature id="blackberry.app" required="true" version="1.0.0.0"/>
+        <feature id="blackberry.app.event" required="false" version="2.0.0.0"/>
+    </access>
+    <access origin="http://www.somedomain1.com" subdomains="true">
+        <feature id="blackberry.app" required="true" version="1.0.0.0"/>
+        <feature id="blackberry.app.event" required="false" version="2.0.0.0"/>
+    </access>
+    <rim:invoke-target id="com.domain.subdomain.appname.app1">
+	<type>APPLICATION</type>
+        <require-source-permissions>invoke_across_perimeters,access_shared</require-source-permissions>
+        <filter>
+            <action>bb.action.OPEN</action>
+            <action>bb.action.SET</action>
+            <action>bb.action.VIEW</action>
+            <mime-type>image/*</mime-type>
+            <mime-type>text/*</mime-type>
+            <property var="uris" value="ftp://" />
+            <property var="uris" value="http://" />
+            <property var="uris" value="https://" />
+            <property var="exts" value="jpg" />
+            <property var="exts" value="png" />
+            <property var="exts" value="txt" />
+            <property var="exts" value="doc" />
+        </filter>
+    </rim:invoke-target>
+</widget>

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/data/ascii_text.txt
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/data/ascii_text.txt b/bin/test/cordova/unit/data/ascii_text.txt
new file mode 100644
index 0000000..5e1c309
--- /dev/null
+++ b/bin/test/cordova/unit/data/ascii_text.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/data/ucs2be_text.txt
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/data/ucs2be_text.txt b/bin/test/cordova/unit/data/ucs2be_text.txt
new file mode 100644
index 0000000..f999e5f
Binary files /dev/null and b/bin/test/cordova/unit/data/ucs2be_text.txt differ

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/data/ucs2le_text.txt
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/data/ucs2le_text.txt b/bin/test/cordova/unit/data/ucs2le_text.txt
new file mode 100644
index 0000000..088fa80
Binary files /dev/null and b/bin/test/cordova/unit/data/ucs2le_text.txt differ

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/data/utf8_text.txt
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/data/utf8_text.txt b/bin/test/cordova/unit/data/utf8_text.txt
new file mode 100644
index 0000000..05eac02
--- /dev/null
+++ b/bin/test/cordova/unit/data/utf8_text.txt
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/params-bad.json
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/params-bad.json b/bin/test/cordova/unit/params-bad.json
new file mode 100644
index 0000000..16c75eb
--- /dev/null
+++ b/bin/test/cordova/unit/params-bad.json
@@ -0,0 +1,10 @@
+{
+EVIL!
+	"blackberry-signer": {
+		"-proxyhost": "abc.com",
+		"-proxyport": "80"
+	},
+	"blackberry-nativepackager": {
+
+	}
+}

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/params.json
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/params.json b/bin/test/cordova/unit/params.json
new file mode 100644
index 0000000..6a3506f
--- /dev/null
+++ b/bin/test/cordova/unit/params.json
@@ -0,0 +1,9 @@
+{
+	"blackberry-signer": {
+		"-proxyhost": "abc.com",
+		"-proxyport": "80"
+	},
+	"blackberry-nativepackager": {
+
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/spec/lib/bar-builder.js
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/spec/lib/bar-builder.js b/bin/test/cordova/unit/spec/lib/bar-builder.js
new file mode 100644
index 0000000..f701b34
--- /dev/null
+++ b/bin/test/cordova/unit/spec/lib/bar-builder.js
@@ -0,0 +1,55 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var srcPath = __dirname + "/../../../../../templates/project/cordova/lib/",
+    path = require("path"),
+    wrench = require("wrench"),
+    barBuilder = require(srcPath + "bar-builder"),
+    fileMgr = require(srcPath + "file-manager"),
+    nativePkgr = require(srcPath + "native-packager"),
+    logger = require(srcPath + "logger"),
+    testData = require("./test-data"),
+    extManager = null;
+
+describe("BAR builder", function () {
+    it("build() create BAR for specified session", function () {
+        var callback = jasmine.createSpy(),
+            session = testData.session,
+            config = testData.config,
+            target = session.targets[0];
+
+        wrench.mkdirSyncRecursive(path.join(session.sourcePaths.LIB, "config"));
+
+        spyOn(wrench, "mkdirSyncRecursive");
+        spyOn(fileMgr, "copyWebworks");
+        spyOn(fileMgr, "generateFrameworkModulesJS");
+        spyOn(nativePkgr, "exec").andCallFake(function (session, target, config, callback) {
+            callback(0);
+        });
+
+        barBuilder.build(session, testData.config, callback);
+
+        expect(wrench.mkdirSyncRecursive).toHaveBeenCalledWith(session.outputDir + "/" + target);
+        expect(fileMgr.generateFrameworkModulesJS).toHaveBeenCalledWith(session);
+        expect(nativePkgr.exec).toHaveBeenCalledWith(session, target, config, jasmine.any(Function));
+        expect(callback).toHaveBeenCalledWith(0);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/spec/lib/bbwpignore.js
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/spec/lib/bbwpignore.js b/bin/test/cordova/unit/spec/lib/bbwpignore.js
new file mode 100644
index 0000000..7c68ee9
--- /dev/null
+++ b/bin/test/cordova/unit/spec/lib/bbwpignore.js
@@ -0,0 +1,135 @@
+/*
+ *  Copyright 2012 Research In Motion Limited.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var srcPath = __dirname + "/../../../../../templates/project/cordova/lib/",
+    BBWPignore = require(srcPath + "bbwpignore"),
+    fs = require('fs');
+
+describe("bbwpignore can match", function () {
+    it("a basic file set", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abc.js\n" +
+                                           "x/y/def.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+        expect(bbwpignore.matchedFiles.length).toBe(4);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("x/y/def.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("a/b/x/y/def.js")).not.toBe(-1);
+    });
+
+    it("a basic file set with directories", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abc.js\n" +
+                                           "x/y/");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(4);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("x/y/def.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("a/b/x/y/def.js")).not.toBe(-1);
+    });
+
+    it("a basic file set with directories that being with slash", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abc.js\n" +
+                                           "/x/y/");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+        expect(bbwpignore.matchedFiles.length).toBe(4);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("/x/y")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("x/y/def.js")).not.toBe(-1);
+
+    });
+
+    it("a basic file set that begin with a slash on the directory", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abc.js\n" +
+                                           "/x/y/def.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(3);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("x/y/def.js")).not.toBe(-1);
+
+    });
+
+    it("a basic file set that begin with a slash", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abc.js\n" +
+                                           "/def.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(2);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+
+    });
+
+    it("a basic file set that begin with a slash and has a wildcard", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abcd.js\n" +
+                                           "/*.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(2);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("ted.js")).not.toBe(-1);
+
+    });
+
+    it("a basic file set that begin with a slash and has a wildcard", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("abcd.js\n" +
+                                           "a*.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["d/e/abc.js", "abc.js", "ted.js", ".DS_Store",
+                                        "x/y/def.js", "x/def.js", "a/b/x/y/def.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(2);
+        expect(bbwpignore.matchedFiles.indexOf("d/e/abc.js")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("abc.js")).not.toBe(-1);
+
+    });
+
+    it("a basic directory set that begin with a slash", function () {
+        var bbwpignore;
+        spyOn(fs, "readFileSync").andReturn("/simulator/\n" +
+                                           "banana.js");
+        bbwpignore = new BBWPignore("FileNameIgnoreForTests",
+                                    ["simulator/a.js"]);
+
+        expect(bbwpignore.matchedFiles.length).toBe(2);
+        expect(bbwpignore.matchedFiles.indexOf("/simulator")).not.toBe(-1);
+        expect(bbwpignore.matchedFiles.indexOf("simulator/a.js")).not.toBe(-1);
+
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/spec/lib/cmdline.js
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/spec/lib/cmdline.js b/bin/test/cordova/unit/spec/lib/cmdline.js
new file mode 100644
index 0000000..421a95b
--- /dev/null
+++ b/bin/test/cordova/unit/spec/lib/cmdline.js
@@ -0,0 +1,98 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var srcPath = __dirname + "/../../../../../templates/project/cordova/lib/",
+    localize = require(srcPath + "localize"),
+    cmdline = require(srcPath + "cmdline"),
+    cmd;
+
+describe("Command line", function () {
+    beforeEach(function () {
+        cmd = cmdline
+                .parse(process.argv)
+                .commander;
+    });
+
+    it("accepts -o with argument", function () {
+        cmd.parseOptions(["-o", "outdir"]);
+        expect(cmd.output).toEqual("outdir");
+    });
+
+    it("arg following -o is required", function () {
+        spyOn(process, "exit");
+        spyOn(console, "error");
+        cmd.parseOptions(["-o"]);
+        expect(console.error).toHaveBeenCalled();
+        expect(process.exit).toHaveBeenCalled();
+    });
+
+    it("accepts -s without argument", function () {
+        cmd.parseOptions(["-s"]);
+        expect(cmd.source).toBeTruthy();
+    });
+
+    it("accepts -s with argument", function () {
+        cmd.parseOptions(["-s", "mySourceDir"]);
+        expect(cmd.source).toEqual("mySourceDir");
+    });
+
+    it("accepts -d", function () {
+        cmd.parseOptions(["-d"]);
+        expect(cmd.debug).toBeTruthy();
+    });
+
+    it("accepts --loglevel with argument", function () {
+        cmd.parseOptions(["--loglevel", "warn"]);
+        expect(cmd.loglevel).toBe("warn");
+    });
+
+    it("accepts -l", function () {
+        cmd.parseOptions(["-l", "error"]);
+        expect(cmd.loglevel).toBe("error");
+    });
+
+    it("accepts -g with argument", function () {
+        cmd.parseOptions(["-g", "myPassword"]);
+        expect(cmd.password).toEqual("myPassword");
+    });
+
+    it("accepts --buildId with argument", function () {
+        cmd.parseOptions(["--buildId", "100"]);
+        expect(cmd.buildId).toEqual("100");
+    });
+
+    it("accepts -buildId with argument", function () {
+        cmd.parseOptions(["-buildId", "100"]);
+        expect(cmd.buildId).toEqual("100");
+    });
+
+    it("accepts --appdesc with argument", function () {
+        cmd.parseOptions(["--appdesc", "bardescriptor"]);
+        expect(cmd.appdesc).toEqual("bardescriptor");
+    });
+
+    it("throws an error for invalid multi-word arguments", function () {
+        expect(function () {
+            require(srcPath + "cmdline").parse(["--src"]);
+        }).toThrow(localize.translate("EXCEPTION_CMDLINE_ARG_INVALID", "--src"));
+    });
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/spec/lib/config-parser.js
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/spec/lib/config-parser.js b/bin/test/cordova/unit/spec/lib/config-parser.js
new file mode 100644
index 0000000..2947e1b
--- /dev/null
+++ b/bin/test/cordova/unit/spec/lib/config-parser.js
@@ -0,0 +1,1448 @@
+/*jshint sub:true*/
+
+var testData = require("./test-data"),
+    configParser = require(testData.libPath + "/config-parser"),
+    packagerUtils = require(testData.libPath + "/packager-utils"),
+    fileManager = require(testData.libPath + "/file-manager"),
+    logger = require(testData.libPath + "./logger"),
+    testUtilities = require("./test-utilities"),
+    xml2js = require('xml2js'),
+    localize = require(testData.libPath + "/localize"),
+    path = require("path"),
+    fs = require("fs"),
+    session = testData.session,
+    configPath = path.resolve("bin/test/cordova/unit/config.xml"),
+    configPathUri = path.resolve("bin/test/cordova/unit/configUri.xml"),
+    configPathUriOrigin = path.resolve("bin/test/cordova/unit/configUriOrigin.xml"),
+    configBadPath = path.resolve("test2/config.xml"),
+    configBareMinimumPath = path.resolve("bin/test/cordova/unit/config-bare-minimum.xml"),
+    mockParsing = testUtilities.mockParsing;
+
+describe("config parser", function () {
+    beforeEach(function () {
+        spyOn(logger, "warn");
+        spyOn(packagerUtils, "copyFile");
+    });
+
+    it("tries to open a config.xml file that doesn't exist", function () {
+        expect(function () {
+            configParser.parse(configBadPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_CONFIG_NOT_FOUND"));
+    });
+
+    it("parses standard elements in a config.xml", function () {
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.content).toEqual("local:///startPage.html");
+            expect(configObj.id).toEqual("My WidgetId");
+            expect(configObj.customHeaders).toEqual({ 'RIM-Widget' : 'rim/widget'});
+            expect(configObj.version).toEqual("1.0.0");
+            expect(configObj.license).toEqual("My License");
+            expect(configObj.licenseURL).toEqual("http://www.apache.org/licenses/LICENSE-2.0");
+            expect(configObj.icon).toEqual(["test.png"]);
+            expect(configObj.configXML).toEqual("config.xml");
+            expect(configObj.author).toEqual("Research In Motion Ltd.");
+            expect(configObj.authorURL).toEqual("http://www.rim.com/");
+            expect(configObj.copyright).toEqual("No Copyright");
+            expect(configObj.authorEmail).toEqual("author@rim.com");
+            expect(configObj.name).toEqual({ default : 'Demo' });
+            expect(configObj.description).toEqual({ default : 'This app does everything.' });
+            expect(configObj.permissions).toContain('access_shared');
+            expect(configObj.permissions).toContain('read_geolocation');
+            expect(configObj.permissions).toContain('use_camera');
+            expect(configObj.enableChildWebView).toBe(false);
+        });
+    });
+
+    it("parses Feature elements in a config.xml", function () {
+        var localAccessList,
+            accessListFeature;
+
+        configParser.parse(configPathUri, session, function (configObj) {
+            //validate WIDGET_LOCAL accessList
+            localAccessList = testUtilities.getAccessList(configObj.accessList, "WIDGET_LOCAL");
+            expect(localAccessList).toBeDefined();
+            expect(localAccessList.uri).toEqual("WIDGET_LOCAL");
+        });
+    });
+
+    it("parses Access elements a config.xml", function () {
+        var customAccessList,
+            accessListFeature;
+
+        configParser.parse(configPathUri, session, function (configObj) {
+            //validate http://www.somedomain1.com accessList
+            customAccessList = testUtilities.getAccessList(configObj.accessList, "http://www.somedomain1.com");
+            expect(customAccessList).toBeDefined();
+            expect(customAccessList.uri).toEqual("http://www.somedomain1.com");
+            expect(customAccessList.allowSubDomain).toEqual(true);
+        });
+    });
+
+    it("parses a bare minimum config.xml without error", function () {
+        var bareMinimumConfigPath = path.resolve("bin/test/cordova/unit/config-bare-minimum.xml");
+
+        configParser.parse(bareMinimumConfigPath, session, function (configObj) {
+            expect(configObj.content).toEqual("local:///startPage.html");
+            expect(configObj.version).toEqual("1.0.0");
+        });
+    });
+
+    it("license url is set even if license body is empty", function () {
+        var licenseConfigPath = path.resolve("bin/test/cordova/unit/config-license.xml");
+
+        configParser.parse(licenseConfigPath, session, function (configObj) {
+            expect(configObj.license).toEqual("");
+            expect(configObj.licenseURL).toEqual("http://www.apache.org/licenses/LICENSE-2.0");
+        });
+    });
+
+    it("fails when id is undefined", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["@"].id = undefined;
+
+        mockParsing(data);
+        //Should throw an EXCEPTION_INVALID_ID error
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_ID"));
+    });
+
+    it("fails when id is empty", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["@"].id = "";
+
+        mockParsing(data);
+
+        //Should throw an EXCEPTION_INVALID_ID error
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_ID"));
+    });
+
+    it("Fails when no name was provided - single element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = "";
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_NAME"));
+    });
+
+    it("Fails when no name was provided - multiple elements", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = ["",
+            { '#': 'API Smoke Test-FR', '@': { 'xml:lang': 'fr' } }
+        ];
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_NAME"));
+    });
+
+    it("Fails when localized name was provided but empty", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = ["API Smoke Test",
+            { '#': '', '@': { 'xml:lang': 'fr' } }
+        ];
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_NAME"));
+    });
+
+    it("Parses a name element - single element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = "API Smoke Test";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.name).toEqual({"default": "API Smoke Test"});
+        });
+    });
+
+    it("Parses a name element with xml:lang - single element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = { '#': 'EN VALUE', '@': { 'xml:lang': 'en' } };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.name).toEqual({"en": "EN VALUE"});
+        });
+    });
+
+    it("Parses a name element that is not case sensitive", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = { '#': 'EN VALUE', '@': { 'xml:lang': 'eN' } };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.name).toEqual({"en": "EN VALUE"});
+        });
+    });
+
+    it("Parses a name element with xml:lang - multi element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = ['API Smoke Test',
+            { '#': 'EN VALUE', '@': { 'xml:lang': 'en' } },
+            { '#': 'FR VALUE', '@': { 'xml:lang': 'fr' } }
+
+        ];
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.name).toEqual({"default": "API Smoke Test", "en": "EN VALUE", "fr": "FR VALUE"});
+        });
+    });
+
+    it("Fails when localized name was provided but empty", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.name = ['API Smoke Test',
+            { '#': '', '@': { 'xml:lang': 'fr' } }
+        ];
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_NAME"));
+    });
+
+    it("Parses a description element - single element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.description = "This is my app";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.description).toEqual({"default": "This is my app"});
+        });
+    });
+
+    it("Parses a description element with xml:lang - single element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.description = { '#': 'EN VALUE', '@': { 'xml:lang': 'en' } };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.description).toEqual({"en": "EN VALUE"});
+        });
+    });
+
+    it("Parses a description element that is not case sensitive", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.description = { '#': 'EN VALUE', '@': { 'xml:lang': 'eN' } };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.description).toEqual({"en": "EN VALUE"});
+        });
+    });
+
+    it("Parses a description element with xml:lang - multi element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.description = ['This is my app',
+            { '#': 'EN VALUE', '@': { 'xml:lang': 'en' } },
+            { '#': 'FR VALUE', '@': { 'xml:lang': 'fr' } }
+
+        ];
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.description).toEqual({"default": "This is my app", "en": "EN VALUE", "fr": "FR VALUE"});
+        });
+    });
+
+    it("adds local:/// protocol to urls", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.content["@"].src = "localFile.html";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.content).toEqual("local:///localFile.html");
+        });
+    });
+
+    it("cleans source folder on error", function () {
+        mockParsing({}, "ERROR");
+
+        spyOn(logger, "error");
+        spyOn(fileManager, "cleanSource");
+
+        configParser.parse(configPath, session, function () {});
+
+        expect(fileManager.cleanSource).toHaveBeenCalled();
+    });
+
+    it("parses a single permission (comes in as string)", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['rim:permissions'] = {};
+        data['rim:permissions']['rim:permit'] = 'onePermissionNoAttribs';
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toContain('onePermissionNoAttribs');
+        });
+    });
+
+    it("parses a single permission with attribs (comes in as object)", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['rim:permissions'] = {};
+        data['rim:permissions']['rim:permit'] = { '#': 'systemPerm', '@': { system: 'true' } };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toContain({ '#': 'systemPerm', '@': { system: 'true' } });
+        });
+    });
+
+    it("parses multiple permissions with no attribs (comes in as array)", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['rim:permissions'] = {};
+        data['rim:permissions']['rim:permit'] = [ 'access_shared', 'read_geolocation', 'use_camera' ];
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toContain('access_shared');
+            expect(configObj.permissions).toContain('read_geolocation');
+            expect(configObj.permissions).toContain('use_camera');
+        });
+    });
+
+    it("parses multiple permissions with attribs (comes in as array)", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['rim:permissions'] = {};
+        data['rim:permissions']['rim:permit'] = [
+            { '#': 'systemPerm', '@': { system: 'true' } },
+            { '#': 'nonSystemPerm', '@': { system: 'false' } }
+        ];
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toContain({ '#': 'systemPerm', '@': { system: 'true' } });
+            expect(configObj.permissions).toContain({ '#': 'nonSystemPerm', '@': { system: 'false' } });
+        });
+    });
+
+    it("parses a config with no permissions set", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        delete data['rim:permissions']; //No permissions set in config
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toEqual([]);
+        });
+    });
+
+    it("enables the enable-flash feature when specified", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add the enable-flash feature element
+        data['feature'] = {'@': {id: 'enable-flash'}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.enableFlash).toEqual(true);
+        });
+    });
+
+    it("does not enable the enable-flash feature when specified in an access element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add the enable-flash to an access element
+        data['access'] = {"@" : {"uri" : "http://somewebsite.com"}, "feature" : {"@": {id: 'enable-flash'}}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.enableFlash).toEqual(false);
+        });
+    });
+
+    it("disables the enable-flash feature by default", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['feature'] = undefined;//no features
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.enableFlash).toEqual(false);
+        });
+    });
+
+    it("sets autoDeferNetworkingAndJavaScript to false when the blackberry.push feature is specified", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add the blackberry.push feature element
+        data["rim:permissions"] = {}; // ensure no run_when_backgrounded permission exists
+        data['feature'] = {'@': {id: 'blackberry.push'}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.autoDeferNetworkingAndJavaScript).toEqual(false);
+        });
+    });
+
+    it("sets autoDeferNetworkingAndJavaScript to false when the run_when_backgrounded permission is specified", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add the run_when_backgrounded permission
+        data['feature'] = undefined; // no features
+        data["rim:permissions"] = {
+            "rim:permit" : [ 'read_geolocation', 'run_when_backgrounded', 'access_internet' ]
+        };
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.permissions).toContain('run_when_backgrounded');
+            expect(configObj.autoDeferNetworkingAndJavaScript).toEqual(false);
+        });
+    });
+
+    it("sets autoDeferNetworkingAndJavaScript to true by default", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        data['feature'] = undefined; // no features
+        data["rim:permissions"] = {}; // ensure no run_when_backgrounded permission exists
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.autoDeferNetworkingAndJavaScript).toEqual(true);
+        });
+    });
+
+    it("does not throw an exception with empty permit tags", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['rim:permit'] = ['read_geolocation', {}, 'access_internet' ];
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).not.toThrow();
+    });
+
+    it("throws a warning when both uri and origin attributes exist", function () {
+        configParser.parse(configPathUriOrigin, session, function (configObj) {});
+        expect(logger.warn).toHaveBeenCalled();
+    });
+
+    it("multi access should be false if no access", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            //hasMultiAccess was set to false
+            expect(configObj.hasMultiAccess).toEqual(false);
+            expect(configObj.accessList).toEqual([ {
+                uri : 'WIDGET_LOCAL',
+                allowSubDomain : true
+            } ]);
+        });
+    });
+
+    it("multi access should be false if no uri is equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = {"@" : {"uri" : "http://www.somedomain1.com"}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            //hasMultiAccess was set to false
+            expect(configObj.hasMultiAccess).toEqual(false);
+            expect(configObj.accessList).toEqual([ {
+                uri : 'WIDGET_LOCAL',
+                allowSubDomain : true
+            }, {
+                "uri" : "http://www.somedomain1.com"
+            } ]);
+        });
+    });
+
+    it("multi access should be false if no origin is equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = {"@" : {"origin" : "http://www.somedomain1.com"}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            //hasMultiAccess was set to false
+            expect(configObj.hasMultiAccess).toEqual(false);
+            expect(configObj.accessList).toEqual([ {
+                uri : 'WIDGET_LOCAL',
+                allowSubDomain : true
+            }, {
+                "uri" : "http://www.somedomain1.com"
+            } ]);
+        });
+    });
+
+    it("multi access should be true with the uri being equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = {"@" : {"uri" : "*"}};
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            //hasMultiAccess was set to true
+            expect(configObj.hasMultiAccess).toEqual(true);
+            expect(configObj.accessList).toEqual([ {
+                uri : 'WIDGET_LOCAL',
+                allowSubDomain : true
+            } ]);
+        });
+    });
+
+    it("multi access should be true with one uri being equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = [{"@" : {"uri" : "*"}}, {"@" : {"uri" : "http://www.somedomain1.com"}}];
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            //hasMultiAccess was set to true
+            expect(configObj.hasMultiAccess).toEqual(true);
+            expect(configObj.accessList).toEqual([ {
+                uri : 'WIDGET_LOCAL',
+                allowSubDomain : true
+            }, {
+                "uri" : "http://www.somedomain1.com"
+            } ]);
+        });
+    });
+
+    it("should fail when feature is defined with the uri being equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = {"@" : {"uri" : "*"}, "feature" : {"@": {"id": "blackberry.app"}}};
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_FEATURE_DEFINED_WITH_WILDCARD_ACCESS_URI_OR_ORIGIN"));
+    });
+
+    it("should fail when multi features are defined with the uri being equal to *", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data['access'] = {"@" : {"uri" : "*"}, "feature" : [{"@": {"id": "blackberry.app"}}, {"@": {"id": "blackberry.system"}}, {"@": {"id": "blackberry.invoke"}}]};
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_FEATURE_DEFINED_WITH_WILDCARD_ACCESS_URI_OR_ORIGIN"));
+    });
+
+    it("should fail when the access uri attribute does not specify a protocol", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add an access element with one feature
+        data['access'] = {
+            '@': {
+                uri: 'rim.net',
+                subdomains: 'true'
+            },
+            feature: {
+                '@': { id: 'blackberry.system' }
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_PROTOCOL", data['access']['@'].uri));
+    });
+
+    it("should fail when the access uri attribute does not specify a URN", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add an access element with one feature
+        data['access'] = {
+            '@': {
+                uri: 'http://',
+                subdomains: 'true'
+            },
+            feature: {
+                '@': { id: 'blackberry.system' }
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_ACCESS_URI_NO_URN", data['access']['@'].uri));
+    });
+
+    it("does not fail when there is a single feature element in the access list", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //Add an access element with one feature
+        data['access'] = {
+            '@': {
+                uri: 'http://rim.net',
+                subdomains: 'true'
+            },
+            feature: {
+                '@': { id: 'blackberry.system' }
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).not.toThrow();
+    });
+
+    it("supports 4 digit version [build id]", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["@"].version = "1.0.0.50";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.version).toEqual("1.0.0");
+            expect(configObj.buildId).toEqual("50");
+        });
+    });
+
+    it("uses --buildId when set", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+        //--buildId 100
+        session.buildId = "100";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.buildId).toEqual("100");
+        });
+    });
+
+    it("overrides the build id specified in version with --buildId flag", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["@"].version = "1.0.0.50";
+
+        //--buildId 100
+        session.buildId = "100";
+
+        mockParsing(data);
+
+        configParser.parse(configPath, session, function (configObj) {
+            expect(configObj.version).toEqual("1.0.0");
+            expect(configObj.buildId).toEqual("100");
+        });
+    });
+
+    it("throws a proper error when author tag is empty", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data.author = {};
+
+        mockParsing(data);
+
+        //Should throw an EXCEPTION_INVALID_AUTHOR error
+        expect(function () {
+            configParser.parse(configPath, session, {});
+        }).toThrow(localize.translate("EXCEPTION_INVALID_AUTHOR"));
+    });
+
+    it("can parse a standard rim:invoke-target element", function () {
+
+        configParser.parse(configPath, session, function (configObj) {
+            var invokeTarget = configObj["invoke-target"][0];
+
+            expect(invokeTarget).toBeDefined();
+            expect(invokeTarget["@"]).toBeDefined();
+            expect(invokeTarget["@"]["id"]).toBeDefined();
+            expect(invokeTarget["@"]["id"]).toEqual("com.domain.subdomain.appname.app1");
+            expect(invokeTarget.type).toBeDefined();
+            expect(invokeTarget.type).toEqual("APPLICATION");
+            expect(invokeTarget["require-source-permissions"]).toBeDefined();
+            expect(invokeTarget["require-source-permissions"]).toEqual("invoke_across_perimeters,access_shared");
+            expect(invokeTarget.filter).toBeDefined();
+            expect(invokeTarget.filter[0].action).toBeDefined();
+            expect(invokeTarget.filter[0].action).toContain("bb.action.VIEW");
+            expect(invokeTarget.filter[0].action).toContain("bb.action.SET");
+            expect(invokeTarget.filter[0].action).toContain("bb.action.OPEN");
+            expect(invokeTarget.filter[0]["mime-type"]).toBeDefined();
+            expect(invokeTarget.filter[0]["mime-type"]).toContain("image/*");
+            expect(invokeTarget.filter[0]["mime-type"]).toContain("text/*");
+            expect(invokeTarget.filter[0].property).toBeDefined();
+
+            invokeTarget.filter[0].property.forEach(function (property) {
+                expect(property["@"]).toBeDefined();
+                expect(property["@"]["var"]).toBeDefined();
+                expect(property["@"]["var"]).toMatch("^(exts|uris)$");
+                if (property["@"]["var"] === "uris") {
+                    expect(property["@"]["value"]).toMatch("^(ftp|http|https):\/\/$");
+                } else if (property["@"]["var"] === "exts") {
+                    expect(property["@"]["value"]).toMatch("^(jpg|png|txt|doc)$");
+                }
+            });
+        });
+    });
+
+    it("can parse multiple filters in one element", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            },
+            "type": "application",
+            "filter":  [{
+                "action":  "bb.action.OPEN",
+                "mime-type": ["text/*", "image/*"]
+            }, {
+                "action": "bb.action.SET",
+                "mime-type": "image/*"
+            }]
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).not.toThrow();
+    });
+
+    it("can parse multiple invoke targets", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = [{
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            },
+            "type": "application"
+        }, {
+            "@": {
+                "id": "com.domain.subdomain.appName.viewer"
+            },
+            "type": "viewer"
+        }];
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).not.toThrow();
+
+    });
+
+    it("throws an error when an invoke target doesn't specify an invocation id", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            type: "APPLICATION"
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_ID"));
+    });
+
+    it("throws and error when an invoke target xml doesn't specify an invocation type", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            },
+            type: {}
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_TYPE"));
+    });
+
+    it("throws an error when an invoke target doesn't specify an invocation type", function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVOKE_TARGET_INVALID_TYPE"));
+    });
+
+    it("throws an error when an invoke target filter doesn't contain an action",  function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            },
+            "type": "APPLICATION",
+            "filter": {
+                "mime-type": "text/*",
+                "property": [{
+                    "@": {
+                        "var": "uris",
+                        "value": "https://"
+                    }
+                }, {
+                    "@": {
+                        "var": "exts",
+                        "value": "html"
+                    }
+                }, {
+                    "@": {
+                        "var": "exts",
+                        "value": "htm"
+                    }
+                }]
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVOKE_TARGET_ACTION_INVALID"));
+    });
+
+    it("throws an error when a filter doesn't contain a mime-type",  function () {
+        var data = testUtilities.cloneObj(testData.xml2jsConfig);
+        data["rim:invoke-target"] = {
+            "@": {
+                "id": "com.domain.subdomain.appName.app"
+            },
+            "type": "application",
+            "filter": {
+                "action": "bb.action.OPEN",
+                "property": [{
+                    "@": {
+                        "var": "uris",
+                        "value": "https://"
+                    }
+                }, {
+                    "@": {
+                        "var": "exts",
+                        "value": "html"
+                    }
+                }]
+            }
+        };
+
+        mockParsing(data);
+
+        expect(function () {
+            configParser.parse(configPath, session, function (configObj) {});
+        }).toThrow(localize.translate("EXCEPTION_INVOKE_TARGET_MIME_TYPE_INVALID"));
+    });
+
+    describe("splash screen", function () {
+        it("throws error when rim:splash element does not contain src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = {};
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_SPLASH_SRC"));
+        });
+
+        it("throws error when rim:splash element contains empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = {
+                "@": {
+                    "src": ""
+                }
+            };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_SPLASH_SRC"));
+        });
+
+        it("throws error when one of many rim:splash elements does not contain attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "#": "blah"
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_SPLASH_SRC"));
+        });
+
+        it("allow one rim:splash element that contains non-empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = {
+                "@": {
+                    "src": "a.jpg"
+                }
+            };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).not.toThrow();
+        });
+
+        it("allow multiple rim:splash elements that contain non-empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "@": {
+                    "src": "b.jpg"
+                }
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).not.toThrow();
+        });
+
+        it("throws error when rim:splash src starts with 'locales' subfolder", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["rim:splash"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "@": {
+                    "src": "locales/en/b.jpg"
+                }
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_SPLASH_SRC_LOCALES"));
+        });
+    });
+
+    describe("icon", function () {
+        it("throws error when icon element does not contain src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = {};
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ICON_SRC"));
+        });
+
+        it("throws error when icon element contains empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = {
+                "@": {
+                    "src": ""
+                }
+            };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ICON_SRC"));
+        });
+
+        it("throws error when one of many icon elements does not contain attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "#": "blah"
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ICON_SRC"));
+        });
+
+        it("allow one icon element that contains non-empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = {
+                "@": {
+                    "src": "a.jpg"
+                }
+            };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).not.toThrow();
+        });
+
+        it("allow multiple icon elements that contain non-empty src attribute", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "@": {
+                    "src": "b.jpg"
+                }
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).not.toThrow();
+        });
+
+        it("throws error when icon src starts with 'locales' subfolder", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = [{
+                "@": {
+                    "src": "a.jpg"
+                }
+            }, {
+                "@": {
+                    "src": "locales/en/b.jpg"
+                }
+            }];
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ICON_SRC_LOCALES"));
+        });
+
+        it("should copy the default icon to the src dir when no icon specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).not.toThrow();
+
+            expect(packagerUtils.copyFile).toHaveBeenCalled();
+        });
+
+        it("should use the default icon config when no icon is specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+            mockParsing(data);
+
+            configParser.parse(configBareMinimumPath, session, function (configObj) {
+                expect(configObj.icon).toEqual(["default-icon.png"]);
+            });
+        });
+
+        it("should not use the default icon config when icon is specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["icon"] = {
+                "@": {
+                    "src": "test.png"
+                }
+            };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.icon).toEqual(["test.png"]);
+                expect(configObj.icon).not.toEqual(["default-icon.png"]);
+                expect(configObj.icon).not.toContain("default-icon.png");
+            });
+        });
+
+        it("sets orientation to landscape when specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'landscape' } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.orientation).toEqual("landscape");
+                expect(configObj.autoOrientation).toEqual(false);
+            });
+        });
+
+        it("sets orientation to portrait when specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'portrait' } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.orientation).toEqual("portrait");
+                expect(configObj.autoOrientation).toEqual(false);
+            });
+        });
+
+        it("sets auto orientation to true by default", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            delete data['preference'];//Remove any orientation data
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.autoOrientation).toEqual(true);
+            });
+        });
+
+        it("orientation remains auto when auto is specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'auto' } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.autoOrientation).toEqual(true);
+            });
+        });
+
+        it("orientation remains auto when default is specified", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'default' } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.autoOrientation).toEqual(true);
+            });
+        });
+
+        it("throws an error when preference.orientation value is invalid", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'invalid' } };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", "invalid"));
+
+        });
+
+        it("throws a warning when blackberry.app.orientation exists", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['feature'] = { '@': { id: 'blackberry.app.orientation', required: true },
+                param: { '@': { name: 'mode', value: 'portrait' } } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {});
+            expect(logger.warn).toHaveBeenCalled();
+        });
+
+        it("throws an error when blackberry.app orientation exists with an invalid mode param", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'orientation', value: 'notAValidMode' } };
+
+            mockParsing(data);
+
+            expect(function () {
+                configParser.parse(configPath, session, function (configObj) {});
+            }).toThrow(localize.translate("EXCEPTION_INVALID_ORIENTATION_MODE", "notavalidmode"));
+        });
+
+        it("sets backgroundColor when specified as a preference", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': {name: 'backgroundColor', value: '0xffffff' } };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.backgroundColor).toEqual(16777215);//Decimal value of 0xffffff
+            });
+        });
+
+        it("throws an error backgroundColor preference is not a number", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data['preference'] = { '@': { name: 'backgroundColor', value: '$UI*@@$' } };
+
+            mockParsing(data);
+
+            //Should throw an EXCEPTION_BGCOLOR_INVALID error
+            expect(function () {
+                configParser.parse(configPath, session, {});
+            }).toThrow(localize.translate("EXCEPTION_BGCOLOR_INVALID", "$ui*@@$"));
+        });
+
+        it("can properly parse the custom RIM-Widget:rim/widget element", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.customHeaders).toEqual({ 'RIM-Widget' : 'rim/widget'});
+            });
+        });
+
+        it("can properly parse the custom attributes but ignores improper headers", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["@"] = {
+                "xmlns": " http://www.w3.org/ns/widgets",
+                "xmlns:rim": "http://www.blackberry.com/ns/widgets",
+                "version": "1.0.0",
+                "id": "myID"
+            };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.id).toEqual("myID");
+                expect(configObj.customHeaders).toEqual(undefined);
+            });
+        });
+
+        it("can properly parse the custom attributes but ignores improper headers", function () {
+            var data = testUtilities.cloneObj(testData.xml2jsConfig);
+            data["@"] = {
+                "xmlns": " http://www.w3.org/ns/widgets",
+                "xmlns:rim": "http://www.blackberry.com/ns/widgets",
+                "version": "1.0.0",
+                "id": "myID",
+                "rim:userAgent" : "A Test-User-Agent/(Blackberry-Agent)"
+            };
+
+            mockParsing(data);
+
+            configParser.parse(configPath, session, function (configObj) {
+                expect(configObj.id).toEqual("myID");
+                expect(configObj.userAgent).toEqual("A Test-User-Agent/(Blackberry-Agent)");
+            });
+        });
+
+        describe('disabling childBrowser (childWebView)', function () {
+            it("sets enableChildWebView to true when childBrowser value is enable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'childBrowser', value: 'enable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableChildWebView).toBe(true);
+                });
+            });
+
+            it("sets enableChildWebView to false when value is disable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'childBrowser', value: 'disable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableChildWebView).toBe(false);
+                });
+            });
+        });
+
+        describe('disabling formcontrol', function () {
+            it("sets enableFormControl to true when HideKeyboardFormAccessoryBar value is disable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'HideKeyboardFormAccessoryBar', value: 'disable'  } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableFormControl).toBe(true);
+                });
+            });
+
+            it("sets enableFormControl to true when HideKeyboardFormAccessoryBar value is false", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'HideKeyboardFormAccessoryBar', value: 'false'  } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableFormControl).toBe(true);
+                });
+            });
+
+            it("sets enableFormControl to false when value is enable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'HideKeyboardFormAccessoryBar', value: 'enable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableFormControl).toBe(false);
+                });
+            });
+
+            it("sets enableFormControl to false when value is true", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'HideKeyboardFormAccessoryBar', value: 'true' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableFormControl).toBe(false);
+                });
+            });
+        });
+
+        describe('setting theme for some core ui elements', function () {
+            function testTheme(themeInConfig, themeParsed) {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+
+                if (themeInConfig) {
+                    data['preference'] = { '@': { name: 'theme', value: themeInConfig } };
+
+                    mockParsing(data);
+                }
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.theme).toBe(themeParsed);
+                });
+            }
+
+            it("sets theme to dark when config has theme with dark", function () {
+                testTheme("dark", "dark");
+            });
+
+            it("sets theme to bright when config has theme with bright", function () {
+                testTheme("bright", "bright");
+            });
+
+            it("sets theme to inherit when config has theme with inherit", function () {
+                testTheme("inherit", "inherit");
+            });
+
+            it("sets theme to default when config has theme with default", function () {
+                testTheme("default", "default");
+            });
+
+            it("sets theme to default when config has unsupported theme", function () {
+                testTheme("unsupportedthemename", "default");
+            });
+
+            it("sets theme to default when config has no theme provided", function () {
+                testTheme(undefined, "default");
+            });
+
+            it("sets theme to dark when config has theme with case insensitive dark", function () {
+                testTheme("dArK", "dark");
+            });
+
+            it("sets theme to bright when config has theme with case insensitive bright", function () {
+                testTheme("BriGht", "bright");
+            });
+
+            it("sets theme to inherit when config has theme with case insensitive inherit", function () {
+                testTheme("inHerIt", "inherit");
+            });
+
+            it("sets theme to inherit when config has theme with case insensitive inherit", function () {
+                testTheme("DefAulT", "default");
+            });
+
+            it("sets theme to default when config has NO theme tag provided", function () {
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.theme).toBe("default");
+                });
+            });
+        });
+
+        describe('disabling WebSecurity', function () {
+            it("doesn't set enableWebSecurity to anything when param value is anything but disable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'webSecurity', value: (new Date()).toString() } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableWebSecurity).toBe(undefined);
+                    expect(logger.warn).not.toHaveBeenCalledWith(localize.translate("WARNING_WEBSECURITY_DISABLED"));
+                });
+            });
+
+            it("sets enableWebSecurity to false when value is disable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'webSecurity', value: 'disable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableWebSecurity).toBe(false);
+                    expect(logger.warn).toHaveBeenCalledWith(localize.translate("WARNING_WEBSECURITY_DISABLED"));
+                });
+            });
+
+            it("sets enableWebSecurity to false when value is disable case insensitive", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'webSecurity', value: 'DisAble' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enableWebSecurity).toBe(false);
+                    expect(logger.warn).toHaveBeenCalledWith(localize.translate("WARNING_WEBSECURITY_DISABLED"));
+                });
+            });
+        });
+
+        describe('enabling popupBlocker', function () {
+            it("sets enablePopupBlocker to true when value is enable", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'popupBlocker', value: 'enable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enablePopupBlocker).toBe(true);
+                });
+            });
+
+            it("sets enablePopBlocker to false when value is disable case insensitive", function () {
+                var data = testUtilities.cloneObj(testData.xml2jsConfig);
+                data['preference'] = { '@': { name: 'popupBlocker', value: 'Disable' } };
+
+                mockParsing(data);
+
+                configParser.parse(configPath, session, function (configObj) {
+                    expect(configObj.enablePopupBlocker).toBe(false);
+                });
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-blackberry/blob/a6733a83/bin/test/cordova/unit/spec/lib/file-manager.js
----------------------------------------------------------------------
diff --git a/bin/test/cordova/unit/spec/lib/file-manager.js b/bin/test/cordova/unit/spec/lib/file-manager.js
new file mode 100644
index 0000000..ae17e7b
--- /dev/null
+++ b/bin/test/cordova/unit/spec/lib/file-manager.js
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var srcPath = __dirname + "/../../../../../templates/project/cordova/lib/",
+    barconf = require(srcPath + "bar-conf.js"),
+    fs = require("fs"),
+    path = require("path"),
+    util = require("util"),
+    packager_utils = require(srcPath + "packager-utils"),
+    localize = require(srcPath + "localize"),
+    wrench = require("wrench"),
+    logger = require(srcPath + "logger"),
+    conf = require(srcPath + "conf"),
+    fileMgr = require(srcPath + "file-manager"),
+    testData = require("./test-data"),
+    testUtilities = require("./test-utilities"),
+    session = testData.session,
+    extManager = {
+        getAllExtensionsToCopy: function (accessList) {
+            return ["app"];
+        },
+        getFeatureIdByExtensionBasename: function (extBasename) {
+            return "blackberry." + extBasename;
+        }
+    };
+
+describe("File manager", function () {
+
+    beforeEach(function () {
+        wrench.mkdirSyncRecursive(testData.session.outputDir);
+    });
+
+    afterEach(function () {
+        //cleanup packager-tests temp folder
+        wrench.rmdirSyncRecursive(testData.session.outputDir);
+    });
+
+    it("unzip() should extract 'from' zip file to 'to' directory", function () {
+        var from = session.archivePath,
+            to = session.sourceDir;
+
+        fileMgr.unzip(from, to);
+
+        expect(fs.statSync(session.sourceDir + "/a").isDirectory()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/a/dummy.txt").isFile()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/a/b").isDirectory()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/a/b/dummy2.txt").isFile()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/startPage.html").isFile()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/config.xml").isFile()).toBeTruthy();
+        expect(fs.statSync(session.sourceDir + "/test.png").isFile()).toBeTruthy();
+    });
+
+    it("cleanSource() should delete source folder", function () {
+        //Create packager-tests source folder
+        wrench.mkdirSyncRecursive(session.sourceDir);
+
+        fileMgr.cleanSource(session);
+        expect(fs.existsSync(session.sourceDir)).toBeFalsy();
+    });
+
+    it("prepareOutputFiles() should throw an error if the archive path doesn't exist", function () {
+        spyOn(wrench, "copyDirSyncRecursive");
+        var tempSession = testUtilities.cloneObj(session);
+        tempSession.archivePath = path.resolve("test/non-existant.zip");
+        expect(function () {
+            fileMgr.prepareOutputFiles(tempSession);
+        }).toThrow(localize.translate("EXCEPTION_INVALID_ARCHIVE_PATH", tempSession.archivePath));
+    });
+
+});