diff --git a/parse/parse-tests.ts b/parse/parse-tests.ts
new file mode 100644
index 000000000..6316aaf17
--- /dev/null
+++ b/parse/parse-tests.ts
@@ -0,0 +1,519 @@
+///
+
+function test_events() {
+
+ var object = new Parse.Events();
+ object.on("alert", (eventName: string) => alert("Triggered " + eventName));
+
+ object.trigger("alert", "an event");
+
+ var onChange = () => console.log('whatever');
+ var context: any;
+
+ object.off("change", onChange);
+ object.off("change");
+ object.off(null, onChange);
+ object.off(null, null, context);
+ object.off();
+}
+
+class GameScore extends Parse.Object {
+
+ constructor(options?: any) {
+
+ super("GameScore", options);
+ }
+}
+
+class Game extends Parse.Object {
+
+ constructor(options?: any) {
+
+ super("GameScore", options);
+ }
+
+ set score(score: GameScore) {
+ this.set('score', score);
+ }
+
+ get score(): GameScore {
+ return this.get("gameScore");
+ }
+}
+
+function test_object() {
+
+ var game = new Game();
+
+// Create a new instance of that class.
+ var gameScore = new GameScore();
+
+ gameScore.set("score", 1337);
+ gameScore.set("playerName", "Sean Plott");
+ gameScore.set("cheatMode", false);
+
+
+ var score = gameScore.get("score");
+ var playerName = gameScore.get("playerName");
+ var cheatMode = gameScore.get("cheatMode");
+
+ gameScore.increment("score");
+ gameScore.addUnique("skills", "flying");
+ gameScore.addUnique("skills", "kungfu");
+
+ game.set("gameScore", gameScore);
+ game.score = gameScore;
+
+ var newGameScore = game.score;
+
+ game.save(null, {
+ success: (game) => {
+ // Execute any logic that should take place after the object is saved.
+ console.log('New object created with objectId: ' + game.id);
+ },
+ error: (game, error) => {
+ // Execute any logic that should take place if the save fails.
+ // error is a Parse.Error with an error code and description.
+ console.log('Fa iled to create new object, with error code: ' + error.message);
+ }
+ }).then(
+
+ (response) => {
+
+ console.log(response);
+ },
+ (error) => {
+
+ console.log(error);
+ }
+ );
+
+ game.fetch().then(
+
+ (response) => {
+
+ console.log(response);
+ },
+ (error) => {
+
+ console.log(error);
+ }
+ );
+
+ game.destroy().then(
+
+ (response) => {
+
+ console.log(response);
+ },
+ (error) => {
+
+ console.log(error);
+ }
+ );
+}
+
+function test_query() {
+
+ var gameScore = new GameScore();
+
+ var query = new Parse.Query(GameScore);
+ query.equalTo("playerName", "Dan Stemkoski");
+ query.notEqualTo("playerName", "Michael Yabuti");
+ query.greaterThan("playerAge", 18);
+ query.limit(10);
+ query.skip(10);
+
+ // Sorts the results in ascending order by the score field
+ query.ascending("score");
+
+ // Sorts the results in descending order by the score field
+ query.descending("score");
+
+ // Restricts to wins < 50
+ query.lessThan("wins", 50);
+
+ // Restricts to wins <= 50
+ query.lessThanOrEqualTo("wins", 50);
+
+ // Restricts to wins > 50
+ query.greaterThan("wins", 50);
+
+ // Restricts to wins >= 50
+ query.greaterThanOrEqualTo("wins", 50);
+
+ // Finds scores from any of Jonathan, Dario, or Shawn
+ query.containedIn("playerName",
+ ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]);
+
+ // Finds scores from anyone who is neither Jonathan, Dario, nor Shawn
+ query.notContainedIn("playerName",
+ ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]);
+
+ // Finds objects that have the score set
+ query.exists("score");
+
+ // Finds objects that don't have the score set
+ query.doesNotExist("score");
+ query.matchesKeyInQuery("hometown", "city", query);
+ query.doesNotMatchKeyInQuery("hometown", "city", query);
+ query.select("score", "playerName");
+
+ // Find objects where the array in arrayKey contains 2.
+ query.equalTo("arrayKey", 2);
+
+ // Find objects where the array in arrayKey contains all of the elements 2, 3, and 4.
+ query.containsAll("arrayKey", [2, 3, 4]);
+
+ query.startsWith("name", "Big Daddy's");
+ query.equalTo("score", gameScore);
+ query.exists("score");
+ query.include("score");
+ query.include(["score.team"]);
+
+ var testQuery = Parse.Query.or(query, query);
+
+ query.count().then(
+ (object) => {
+
+ },
+ (error) => {
+ console.log("Error: " + error.code + " " + error.message);
+ }
+ );
+
+ query.find({
+ success: (results) => {
+ alert("Successfully retrieved " + results.length + " scores.");
+ // Do something with the returned Parse.Object values
+ for (var i = 0; i < results.length; i++) {
+ var object = results[i];
+ console.log(object.id + ' - ' + object.get('playerName'));
+ }
+ },
+ error: (error) => {
+ alert("Error: " + error.code + " " + error.message);
+ }
+ });
+
+ query.first().then(
+ (object) => {
+
+ },
+ (error) => {
+ console.log("Error: " + error.code + " " + error.message);
+ }
+ );
+}
+
+class TestCollection extends Parse.Collection
+ *
+ * @see Parse.Promise.prototype.then
+ * @class
+ */
+
+ interface IPromise {
+
+ then(resolvedCallback: (value: T) => IPromise, rejectedCallback?: (reason: any) => IPromise): IPromise;
+ then(resolvedCallback: (value: T) => U, rejectedCallback?: (reason: any) => IPromise): IPromise;
+ then(resolvedCallback: (value: T) => U, rejectedCallback?: (reason: any) => U): IPromise;
+ }
+
+ interface Promise {
+
+ always(callback: Function): Promise;
+ as(): Promise;
+ done(callback: Function): Promise;
+ error(): Promise;
+ fail(callback: Function): Promise;
+ is(): Promise;
+ reject(error: any): void;
+ resolve(result: any): void;
+ then(resolvedCallback: (value: T) => Promise,
+ rejectedCallback?: (reason: any) => Promise): IPromise;
+ then(resolvedCallback: (value: T) => U,
+ rejectedCallback?: (reason: any) => IPromise): IPromise;
+ then(resolvedCallback: (value: T) => U,
+ rejectedCallback?: (reason: any) => U): IPromise;
+
+ when(promises: Promise[]): Promise;
+ }
+
+ interface IBaseObject {
+ toJSON(): any;
+ }
+
+ class BaseObject implements IBaseObject {
+ toJSON(): any;
+ }
+
+ /**
+ * Creates a new ACL.
+ * If no argument is given, the ACL has no permissions for anyone.
+ * If the argument is a Parse.User, the ACL will have read and write
+ * permission for only that user.
+ * If the argument is any other JSON object, that object will be interpretted
+ * as a serialized ACL created with toJSON().
+ * @see Parse.Object#setACL
+ * @class
+ *
+ *
An ACL, or Access Control List can be added to any
+ * Parse.Object to restrict access to only a subset of users
+ * of your application.
+ */
+ class ACL extends BaseObject {
+
+ permissionsById: any;
+
+ constructor(arg1?: any);
+
+ setPublicReadAccess(allowed: boolean);
+ getPublicReadAccess(): boolean;
+
+ setPublicWriteAccess(allowed: boolean);
+ getPublicWriteAccess(): boolean;
+
+ setReadAccess(userId: User, allowed: boolean);
+ getReadAccess(userId: User): boolean;
+
+ setReadAccess(userId: string, allowed: boolean);
+ getReadAccess(userId: string): boolean;
+
+ setRoleReadAccess(role: Role, allowed: boolean);
+ setRoleReadAccess(role: string, allowed: boolean);
+ getRoleReadAccess(role: Role): boolean;
+ getRoleReadAccess(role: string): boolean;
+
+ setRoleWriteAccess(role: Role, allowed: boolean);
+ setRoleWriteAccess(role: string, allowed: boolean);
+ getRoleWriteAccess(role: Role): boolean;
+ getRoleWriteAccess(role: string): boolean;
+
+ setWriteAccess(userId: User, allowed: boolean);
+ setWriteAccess(userId: string, allowed: boolean);
+ getWriteAccess(userId: User): boolean;
+ getWriteAccess(userId: string): boolean;
+ }
+
+
+ /**
+ * A Parse.File is a local representation of a file that is saved to the Parse
+ * cloud.
+ * @class
+ * @param name {String} The file's name. This will be prefixed by a unique
+ * value once the file has finished saving. The file name must begin with
+ * an alphanumeric character, and consist of alphanumeric characters,
+ * periods, spaces, underscores, or dashes.
+ * @param data {Array} The data for the file, as either:
+ * 1. an Array of byte value Numbers, or
+ * 2. an Object like { base64: "..." } with a base64-encoded String.
+ * 3. a File object selected with a file upload control. (3) only works
+ * in Firefox 3.6+, Safari 6.0.2+, Chrome 7+, and IE 10+.
+ * For example:
+ * var fileUploadControl = $("#profilePhotoFileUpload")[0];
+ * if (fileUploadControl.files.length > 0) {
+ * var file = fileUploadControl.files[0];
+ * var name = "photo.jpg";
+ * var parseFile = new Parse.File(name, file);
+ * parseFile.save().then(function() {
+ * // The file has been saved to Parse.
+ * }, function(error) {
+ * // The file either could not be read, or could not be saved to Parse.
+ * });
+ * }
+ * @param type {String} Optional Content-Type header to use for the file. If
+ * this is omitted, the content type will be inferred from the name's
+ * extension.
+ */
+ class File {
+
+ constructor(name: string, data: any, type?: string);
+ name(): string;
+ url(): string;
+ save(options?: ParseDefaultOptions);
+
+ }
+
+ /**
+ * Creates a new GeoPoint with any of the following forms:
+ *
+ * new GeoPoint(otherGeoPoint)
+ * new GeoPoint(30, 30)
+ * new GeoPoint([30, 30])
+ * new GeoPoint({latitude: 30, longitude: 30})
+ * new GeoPoint() // defaults to (0, 0)
+ *
+ * @class
+ *
+ *
Represents a latitude / longitude point that may be associated
+ * with a key in a ParseObject or used as a reference point for geo queries.
+ * This allows proximity-based queries on the key.
+ *
+ *
Only one key in a class may contain a GeoPoint.
+ *
+ *
Example:
+ * var point = new Parse.GeoPoint(30.0, -20.0);
+ * var object = new Parse.Object("PlaceObject");
+ * object.set("location", point);
+ * object.save();
+ */
+ class GeoPoint extends BaseObject {
+
+ latitude: number;
+ longitude: number;
+
+ constructor(arg1?: any, arg2?: any);
+
+ current(options?: ParseDefaultOptions): GeoPoint;
+ radiansTo(point: GeoPoint): number;
+ kilometersTo(point: GeoPoint): number;
+ milesTo(point: GeoPoint): number;
+ }
+
+ /**
+ * History serves as a global router (per frame) to handle hashchange
+ * events or pushState, match the appropriate route, and trigger
+ * callbacks. You shouldn't ever have to create one of these yourself
+ * — you should use the reference to Parse.history
+ * that will be created for you automatically if you make use of
+ * Routers with routes.
+ * @class
+ *
+ *
A fork of Backbone.History, provided for your convenience. If you
+ * use this class, you must also include jQuery, or another library
+ * that provides a jQuery-compatible $ function. For more information,
+ * see the
+ * Backbone documentation.
+ *
Available in the client SDK only.
+ */
+ class History {
+
+ handlers: any[];
+ interval: number;
+ fragment: string;
+
+ checkUrl(e?: any): void;
+ getFragment(fragment?: string, forcePushState?: boolean): string;
+ getHash(windowOverride: Window): string;
+ loadUrl(fragmentOverride: any): boolean;
+ navigate(fragment: string, options?: any): any;
+ route(route: any, callback: Function): void;
+ start(options: any): boolean;
+ stop(): void;
+ }
+
+ /**
+ * A class that is used to access all of the children of a many-to-many relationship.
+ * Each instance of Parse.Relation is associated with a particular parent object and key.
+ */
+ class Relation extends BaseObject {
+
+ parent: Object;
+ key: string;
+ targetClassName: string;
+
+ constructor(parent?: Object, key?: string);
+
+ //Adds a Parse.Object or an array of Parse.Objects to the relation.
+ add(object: Object): void;
+
+ // Returns a Parse.Query that is limited to objects in this relation.
+ query(): Query;
+
+ // Removes a Parse.Object or an array of Parse.Objects from this relation.
+ remove(object: Object): void;
+ }
+
+ /**
+ * Creates a new model with defined attributes. A client id (cid) is
+ * automatically generated and assigned for you.
+ *
+ *
You won't normally call this method directly. It is recommended that
+ * you use a subclass of Parse.Object instead, created by calling
+ * extend.
+ *
+ *
However, if you don't want to use a subclass, or aren't sure which
+ * subclass is appropriate, you can use this form:
+ * var object = new Parse.Object("ClassName");
+ *
+ * That is basically equivalent to:
+ * var MyClass = Parse.Object.extend("ClassName");
+ * var object = new MyClass();
+ *
+ *
+ * @param {Object} attributes The initial set of data to store in the object.
+ * @param {Object} options A set of Backbone-like options for creating the
+ * object. The only option currently supported is "collection".
+ * @see Parse.Object.extend
+ *
+ * @class
+ *
+ *
The fundamental unit of Parse data, which implements the Backbone Model
+ * interface.
Parse.Events is a fork of Backbone's Events module, provided for your
+ * convenience.
+ *
+ *
A module that can be mixed in to any object in order to provide
+ * it with custom events. You may bind callback functions to an event
+ * with `on`, or remove these functions with `off`.
+ * Triggering an event fires all callbacks in the order that `on` was
+ * called.
+ *
+ *
+ */
+ class Events {
+
+ static off(events: string[], callback?: Function, context?: any);
+ static on(events: string[], callback?: Function, context?: any);
+ static trigger(events: string[]);
+ static bind();
+ static unbind();
+
+ on(eventName: string, callback?: Function, context?: any): any;
+ off(eventName?: string, callback?: Function, context?: any): any;
+ trigger(eventName: string, ...args: any[]): any;
+ bind(eventName: string, callback: Function, context?: any): any;
+ unbind(eventName?: string, callback?: Function, context?: any): any;
+
+ }
+
+ /**
+ * Creates a new parse Parse.Query for the given Parse.Object subclass.
+ * @param objectClass -
+ * An instance of a subclass of Parse.Object, or a Parse className string.
+ * @class
+ *
+ *
Parse.Query defines a query that is used to fetch Parse.Objects. The
+ * most common use case is finding all objects that match a query through the
+ * find method. For example, this sample code fetches all objects
+ * of class MyClass. It calls a different function depending on
+ * whether the fetch succeeded or not.
+ *
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.find({
+ * success: function(results) {
+ * // results is an array of Parse.Object.
+ * },
+ *
+ * error: function(error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });
+ *
+ *
A Parse.Query can also be used to retrieve a single object whose id is
+ * known, through the get method. For example, this sample code fetches an
+ * object of class MyClass and id myId. It calls a
+ * different function depending on whether the fetch succeeded or not.
+ *
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.get(myId, {
+ * success: function(object) {
+ * // object is an instance of Parse.Object.
+ * },
+ *
+ * error: function(object, error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });
+ *
+ *
A Parse.Query can also be used to count the number of objects that match
+ * the query without retrieving all of those objects. For example, this
+ * sample code counts the number of objects of the class MyClass
+ *
+ * var query = new Parse.Query(MyClass);
+ * query.count({
+ * success: function(number) {
+ * // There are number instances of MyClass.
+ * },
+ *
+ * error: function(error) {
+ * // error is an instance of Parse.Error.
+ * }
+ * });