Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
14,587 changes: 14,587 additions & 0 deletions .pnp.cjs

Large diffs are not rendered by default.

2,047 changes: 2,047 additions & 0 deletions .pnp.loader.mjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-21ad2b1333-8.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/install-state.gz
Binary file not shown.
14 changes: 14 additions & 0 deletions __mocks__/react-native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

const NativeModules = {};
const TurboModuleRegistry = {
get: jest.fn(() => null),
getEnforcing: jest.fn((name) => {
throw new Error(`TurboModuleRegistry.getEnforcing mock: '${name}' not available`);
}),
};

module.exports = {
NativeModules,
TurboModuleRegistry,
};
60 changes: 60 additions & 0 deletions __tests__/NativeSQLiteModule.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict';

describe('NativeSQLiteModule resolver', () => {
beforeEach(() => {
jest.resetModules();
});

test('resolveSQLite prefers TurboModuleRegistry.get("SQLite") when it returns a module', () => {
jest.doMock('react-native', () => {
const turboSentinel = { __tag: 'turbo' };
return {
NativeModules: { SQLite: { __tag: 'native' } },
TurboModuleRegistry: {
get: jest.fn(name => (name === 'SQLite' ? turboSentinel : null)),
},
};
});
const { resolveSQLite } = require('../src/NativeSQLiteModule');
const rn = require('react-native');
const resolved = resolveSQLite();
expect(resolved).toBe(rn.TurboModuleRegistry.get('SQLite'));
expect(resolved.__tag).toBe('turbo');
});

test('resolveSQLite falls back to NativeModules.SQLite when TurboModuleRegistry.get returns null', () => {
const nativeSentinel = { __tag: 'native' };
jest.doMock('react-native', () => ({
NativeModules: { SQLite: nativeSentinel },
TurboModuleRegistry: { get: jest.fn(() => null) },
}));
const { resolveSQLite } = require('../src/NativeSQLiteModule');
const rn = require('react-native');
const resolved = resolveSQLite();
expect(resolved).toBe(rn.NativeModules.SQLite);
expect(resolved.__tag).toBe('native');
});

test('resolveSQLite returns null when neither TurboModule nor NativeModule is present', () => {
jest.doMock('react-native', () => ({
NativeModules: {},
TurboModuleRegistry: { get: jest.fn(() => null) },
}));
const { resolveSQLite } = require('../src/NativeSQLiteModule');
expect(resolveSQLite()).toBeNull();
});

test('getSQLite memoises the resolved module across calls', () => {
const spy = jest.fn(() => ({ __tag: 'turbo' }));
jest.doMock('react-native', () => ({
NativeModules: {},
TurboModuleRegistry: { get: spy },
}));
const { getSQLite, __resetForTests } = require('../src/NativeSQLiteModule');
__resetForTests();
const first = getSQLite();
const second = getSQLite();
expect(first).toBe(second);
expect(spy).toHaveBeenCalledTimes(1);
});
});
19 changes: 19 additions & 0 deletions __tests__/attach.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

test('SQLitePlugin.attach invokes SQLite.attach with path/dbName/dbAlias', () => {
const native = {
open: jest.fn((_opts, success) => success()),
attach: jest.fn((_opts, success) => success()),
};
const { factory } = loadPlugin(native);
const db = factory.openDatabase({ name: 'main.db' }, () => {}, () => {});
const ok = jest.fn();
const err = jest.fn();
db.attach('other.db', 'other', ok, err);

expect(native.attach).toHaveBeenCalledTimes(1);
const [opts] = native.attach.mock.calls[0];
expect(opts).toEqual({ path: 'main.db', dbName: 'other.db', dbAlias: 'other' });
});
20 changes: 20 additions & 0 deletions __tests__/close.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

test('SQLitePlugin.close invokes SQLite.close with {path: dbname}', () => {
const native = {
open: jest.fn((_opts, success) => success()),
close: jest.fn((_opts, success) => success()),
};
const { factory } = loadPlugin(native);
const db = factory.openDatabase({ name: 't.db' }, () => {}, () => {});
const ok = jest.fn();
const err = jest.fn();
db.close(ok, err);
expect(native.close).toHaveBeenCalledTimes(1);
const [opts] = native.close.mock.calls[0];
expect(opts).toEqual({ path: 't.db' });
expect(ok).toHaveBeenCalled();
expect(err).not.toHaveBeenCalled();
});
16 changes: 16 additions & 0 deletions __tests__/deleteDatabase.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

test('SQLiteFactory.deleteDatabase invokes SQLite.delete with {path, dblocation}', () => {
const native = { delete: jest.fn((_opts, success) => success()) };
const { factory } = loadPlugin(native);
const ok = jest.fn();
const err = jest.fn();
factory.deleteDatabase({ name: 't.db', location: 'Library' }, ok, err);

expect(native.delete).toHaveBeenCalledTimes(1);
const [opts] = native.delete.mock.calls[0];
expect(opts.path).toBe('t.db');
expect(opts.dblocation).toBe('libs');
});
26 changes: 26 additions & 0 deletions __tests__/detach.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const { loadPlugin, flushAsync } = require('./helpers/loadPlugin');

test('SQLitePlugin.detach issues a DETACH DATABASE statement through the transaction queue', async () => {
const native = {
open: jest.fn((_opts, success) => success()),
backgroundExecuteSqlBatch: jest.fn((opts, success) => {
const results = opts.executes.map(() => ({ rows: [], rowsAffected: 0, insertId: 0 }));
success(results);
}),
};
const { factory } = loadPlugin(native);
const db = factory.openDatabase({ name: 'main.db' }, () => {}, () => {});
const ok = jest.fn();
const err = jest.fn();
db.detach('other', ok, err);

await flushAsync();
await flushAsync();

expect(native.backgroundExecuteSqlBatch).toHaveBeenCalled();
const allSql = native.backgroundExecuteSqlBatch.mock.calls
.flatMap(([opts]) => opts.executes.map(e => e.sql));
expect(allSql.some(sql => /^DETACH DATABASE /i.test(sql))).toBe(true);
});
34 changes: 34 additions & 0 deletions __tests__/echoTest.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

describe('SQLiteFactory.echoTest', () => {
test('calls SQLite.echoStringValue and succeeds on matching echo', () => {
const native = {
echoStringValue: jest.fn((opts, success) => success(opts.value)),
};
const { factory } = loadPlugin(native);
const ok = jest.fn();
const err = jest.fn();
factory.echoTest(ok, err);
expect(native.echoStringValue).toHaveBeenCalledTimes(1);
const [opts] = native.echoStringValue.mock.calls[0];
expect(opts).toEqual({ value: 'test-string' });
expect(ok).toHaveBeenCalledTimes(1);
expect(err).not.toHaveBeenCalled();
});

test('surfaces a mismatch via the error callback', () => {
const native = {
echoStringValue: jest.fn((_opts, success) => success('wrong-echo')),
};
const { factory } = loadPlugin(native);
const ok = jest.fn();
const err = jest.fn();
factory.echoTest(ok, err);
expect(ok).not.toHaveBeenCalled();
expect(err).toHaveBeenCalledTimes(1);
const [msg] = err.mock.calls[0];
expect(String(msg)).toMatch(/Mismatch/i);
});
});
32 changes: 32 additions & 0 deletions __tests__/executeSql.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

const { loadPlugin, flushAsync } = require('./helpers/loadPlugin');

test('SQLitePlugin.executeSql runs the statement via backgroundExecuteSqlBatch (never via single executeSql)', async () => {
const native = {
open: jest.fn((_opts, success) => success()),
backgroundExecuteSqlBatch: jest.fn((opts, success) => {
const results = opts.executes.map(() => ({ rows: [], rowsAffected: 0, insertId: 0 }));
success(results);
}),
executeSql: jest.fn(),
backgroundExecuteSql: jest.fn(),
};
const { factory } = loadPlugin(native);
const db = factory.openDatabase({ name: 't.db' }, () => {}, () => {});
const ok = jest.fn();
const err = jest.fn();
db.executeSql('SELECT 1', [], ok, err);

await flushAsync();
await flushAsync();

expect(native.backgroundExecuteSqlBatch).toHaveBeenCalledTimes(1);
const [opts] = native.backgroundExecuteSqlBatch.mock.calls[0];
expect(Array.isArray(opts.executes)).toBe(true);
expect(opts.executes.length).toBeGreaterThanOrEqual(1);
const sqls = opts.executes.map(e => e.sql);
expect(sqls).toContain('SELECT 1');
expect(native.executeSql).not.toHaveBeenCalled();
expect(native.backgroundExecuteSql).not.toHaveBeenCalled();
});
23 changes: 23 additions & 0 deletions __tests__/helpers/loadPlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

/**
* Test helper: loads the library's public entry (sqlite.js) with an
* injected native module. Returns the SQLiteFactory instance and the
* mutable native object so tests can rewire method implementations.
*/
function loadPlugin(native) {
jest.resetModules();
jest.doMock('../../src/NativeSQLiteModule', () => ({
resolveSQLite: () => native,
getSQLite: () => native,
__resetForTests: () => {},
}));
const factory = require('../../sqlite.js');
return { factory, native };
}

function flushAsync() {
return new Promise(resolve => setImmediate(resolve));
}

module.exports = { loadPlugin, flushAsync };
31 changes: 31 additions & 0 deletions __tests__/openDatabase.callback.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

describe('SQLiteFactory.openDatabase (callback mode)', () => {
test('openDatabase in callback mode invokes SQLite.open with the openargs dictionary', () => {
const native = { open: jest.fn((opts, success /*, error*/) => { success(); }) };
const { factory } = loadPlugin(native);
const ok = jest.fn();
const err = jest.fn();
factory.openDatabase({ name: 't.db' }, ok, err);
expect(native.open).toHaveBeenCalledTimes(1);
const [opts] = native.open.mock.calls[0];
expect(opts.name).toBe('t.db');
expect(opts.dblocation).toBe('nosync');
expect(ok).toHaveBeenCalledTimes(1);
expect(err).not.toHaveBeenCalled();
});

test('openDatabase callback mode delivers error via the provided errorcb', () => {
const native = { open: jest.fn((opts, success, error) => { error('boom'); }) };
const { factory } = loadPlugin(native);
const ok = jest.fn();
const err = jest.fn();
factory.openDatabase({ name: 't.db' }, ok, err);
expect(err).toHaveBeenCalledTimes(1);
const [received] = err.mock.calls[0];
expect(received).toBeTruthy();
expect(received.message || '').toMatch(/Could not open database/i);
});
});
21 changes: 21 additions & 0 deletions __tests__/openDatabase.promise.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

const { loadPlugin } = require('./helpers/loadPlugin');

describe('enablePromise(true)', () => {
test('turns openDatabase into a Promise that resolves on native success', async () => {
const native = { open: jest.fn((_opts, success) => success()) };
const { factory } = loadPlugin(native);
factory.enablePromise(true);
const db = await factory.openDatabase({ name: 't.db' });
expect(db).toBeTruthy();
expect(native.open).toHaveBeenCalledTimes(1);
});

test('causes openDatabase to reject on native error', async () => {
const native = { open: jest.fn((_opts, _s, error) => error('boom')) };
const { factory } = loadPlugin(native);
factory.enablePromise(true);
await expect(factory.openDatabase({ name: 't.db' })).rejects.toBeDefined();
});
});
Loading