react-native-firebase/tests/lib/TestDSL.js

252 lines
8.4 KiB
JavaScript

/**
* Class that provides DSL for declaratively defining tests. Provides a declarative
* interface for {@link TestSuiteDefinition} and only reveals methods that are part
* of the test definition DSL.
*/
class TestDSL {
/**
* Create a new instance of TestDSL
* @param {TestSuiteDefinition} testSuiteDefinition - Class to delegate the heavy lifting
* of satisfying the DSL, to.
* @param {Object} firebase - Object containing native and web firebase instances
* @param {Object} firebase.native - Native firebase instance
* @para {Object} firebase.web - Web firebase instance
*/
constructor(testSuiteDefinition, firebase) {
this._testSuiteDefinition = testSuiteDefinition;
this.firebase = firebase;
this.after = this.after.bind(this);
this.afterEach = this.afterEach.bind(this);
this.before = this.before.bind(this);
this.beforeEach = this.beforeEach.bind(this);
this.describe = this.describe.bind(this);
/** Alias for {@link TestDSL#describe } */
this.context = this.describe;
this.fdescribe = this.fdescribe.bind(this);
/** Alias for {@link TestDSL#fdescribe } */
this.fcontext = this.fdescribe;
this.xdescribe = this.xdescribe.bind(this);
/** Alias for {@link TestDSL#xdescribe } */
this.xcontext = this.xdescribe;
this.tryCatch = this.tryCatch.bind(this);
this.it = this.it.bind(this);
this.xit = this.xit.bind(this);
this.fit = this.fit.bind(this);
}
/**
* Add a function as a before hook to the current test context
* @param {Object=} options - Options object
* @param {Number=10000} options.timeout - Number of milliseconds before callback times
* out
* @param {Function} callback - Function to add as before hook to current test context
*/
before(options, callback = undefined) {
const _options = callback ? options : {};
const _callback = callback || options;
this._testSuiteDefinition.addBeforeHook(_callback, _options);
}
/**
* Add a function as a before each hook to the current test context
* @param {Object=} options - Options object
* @param {Number=10000} options.timeout - Number of milliseconds before callback times
* out
* @param {Function} callback - Function to add as before each hook to current test
* context
*/
beforeEach(options, callback = undefined) {
const _options = callback ? options : {};
const _callback = callback || options;
this._testSuiteDefinition.addBeforeEachHook(_callback, _options);
}
/**
* Add a function as a after each hook to the current test context
* @param {Object=} options - Options object
* @param {Number=10000} options.timeout - Number of milliseconds before callback times
* out
* @param {Function} callback - Function to add as after each hook to current test context
*/
afterEach(options, callback = undefined) {
const _options = callback ? options : {};
const _callback = callback || options;
this._testSuiteDefinition.addAfterEachHook(_callback, _options);
}
/**
* Add a function as a after hook to the current test context
* @param {Object=} options - Options object
* @param {Number=10000} options.timeout - Number of milliseconds before callback times
* out
* @param {Function} callback - Function to add as after hook to current test context
*/
after(options, callback = undefined) {
const _options = callback ? options : {};
const _callback = callback || options;
this._testSuiteDefinition.addAfterHook(_callback, _options);
}
/**
* Starts a new test context
* @param {String} name - name of new test context
* @param {ContextOptions} options - options for context
* @param {Function} [testDefinitions={}] - function that defines further test contexts and
* tests using the test DSL
*/
describe(name, options, testDefinitions) {
let _testDefinitions;
let _options;
if (testDefinitions) {
_testDefinitions = testDefinitions;
_options = options;
} else {
_testDefinitions = options;
_options = {};
}
this._testSuiteDefinition.pushTestContext(name, _options);
_testDefinitions();
this._testSuiteDefinition.popTestContext();
}
/**
* Starts a new pending test context. Tests in a pending test context are not
* run when the test suite is executed. They also appear greyed out.
* @param {String} name - name of new test context
* @param {ContextOptions} [options={}] - options for context
* @param {Function} testDefinitions - function that defines further test contexts and
* tests using the test DSL
*/
xdescribe(name, options, testDefinitions = undefined) {
let _options = {};
let _testDefinitions;
if (typeof options === 'function') {
_options = { pending: true };
_testDefinitions = options;
} else {
Object.assign(_options, options, { pending: true });
_testDefinitions = testDefinitions;
}
this.describe(name, _options, _testDefinitions);
}
/**
* Starts a new focused test context. Tests in a focused test context are the only
* ones that appear and are run when the test suite is executed.
* @param {String} name - name of new test context
* @param {ContextOptions} [options={}] - options for context
* @param {Function} testDefinitions - function that defines further test contexts and
* tests using the test DSL
*/
fdescribe(name, options, testDefinitions = undefined) {
let _options = {};
let _testDefinitions;
if (typeof options === 'function') {
_options = { focus: true };
_testDefinitions = options;
} else {
Object.assign(_options, options, { focus: true });
_testDefinitions = testDefinitions;
}
this.describe(name, _options, _testDefinitions);
}
/**
* Defines a new test.
* @param {String} description - Brief description of what the test expects
* @param {TestOptions} options - Options of whether test should be focused or pending
* @param {Function} testFunction - Body of the test containing setup and assertions
*/
it(description, options, testFunction = undefined) {
this._testSuiteDefinition.addTest(description, options, testFunction);
}
/**
* Defines a new pending test. Pending tests are not run when the test suite is
* executed. They also appear greyed out.
* @param {String} description - Brief description of what the test expects
* @param {ContextOptions} [options={}] - Options of whether test should be focused or pending
* @param {Function} testFunction - Body of the test containing setup and assertions
*/
xit(description, options, testFunction = undefined) {
let _options = {};
let _testFunction;
if (typeof options === 'function') {
_options = { pending: true };
_testFunction = options;
} else {
Object.assign(_options, options, { pending: true });
_testFunction = testFunction;
}
this.it(description, _options, _testFunction);
}
/**
* Defines a new focused test. Focused tests are the only
* ones that appear and are run when the test suite is executed.
* @param {String} description - Brief description of what the test expects
* @param {ContextOptions} [options={}] - Options of whether test should be focused or pending
* @param {Function} testFunction - Body of the test containing setup and assertions
*/
fit(description, options, testFunction = undefined) {
let _options = {};
let _testFunction;
if (typeof options === 'function') {
_options = { focus: true };
_testFunction = options;
} else {
Object.assign(_options, options, { focus: true });
_testFunction = testFunction;
}
this.it(description, _options, _testFunction);
}
/**
* Tries evaluating a function and calls a reject callback if it throws an error
* @param {Function} callback - Function to evaluate
* @param {Function} reject - Function to call if callback throws an error
* @returns {function(...[*])} a function that will catch any errors thrown by callback,
* passing them to reject instead.
*/
tryCatch(callback, reject) {
return (...args) => {
try {
callback(...args);
} catch (error) {
reject(error);
}
};
}
}
/**
* Log a test DSL error to the console.
* @param {String} error - Message to included in message logged to the console
*/
function testDSLError(error) {
console.error(`ReactNativeFirebaseTests.TestDSLError: ${error}`);
console.error('This test was ignored.');
}
export default TestDSL;