Skip to content

OP-SQLite async iterator tests #615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 8, 2025
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-simulators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
id: check
run: |
git fetch origin ${{ github.base_ref }}
if git diff --quiet origin/${{ github.base_ref }} -- packages/common packages/powersync-op-sqlite; then
if git diff --quiet origin/${{ github.base_ref }} -- packages/common packages/powersync-op-sqlite tools/powersynctests; then
echo "should_run=false" >> $GITHUB_OUTPUT
else
echo "should_run=true" >> $GITHUB_OUTPUT
Expand Down
1,510 changes: 935 additions & 575 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions tools/powersynctests/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
'@babel/plugin-transform-async-generator-functions',
'@babel/plugin-transform-class-static-block',
[
'module-resolver',
{
alias: {
stream: 'stream-browserify',
},
},
],
],
stream: 'stream-browserify'
}
}
]
]
};
108 changes: 54 additions & 54 deletions tools/powersynctests/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- powersync-op-sqlite (0.7.0):
- powersync-op-sqlite (0.7.2):
- DoubleConversion
- glog
- hermes-engine
Expand All @@ -55,7 +55,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- powersync-sqlite-core (0.4.0)
- powersync-sqlite-core (0.4.1)
- RCT-Folly (2024.11.18.00):
- boost
- DoubleConversion
Expand Down Expand Up @@ -1829,71 +1829,71 @@ SPEC CHECKSUMS:
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8
hermes-engine: b417d2b2aee3b89b58e63e23a51e02be91dc876d
op-sqlite: af963896bb0d5393f12e07189bb39b1eaa5f4ac3
powersync-op-sqlite: 1309903d34a7616296570447a77c215f8bc36eb5
powersync-sqlite-core: 3bfe9a3c210e130583496871b404f18d4cfbe366
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
op-sqlite: 27db77bc067129a35dccf00dad447e683318825d
powersync-op-sqlite: 185b0e0594ee3eb9d2a45cada51e861e812a3d65
powersync-sqlite-core: c60f33d82b2ca05afdb99fb39c3c76749635a6aa
RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809
RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35
RCTRequired: 78522de7dc73b81f3ed7890d145fa341f5bb32ea
RCTTypeSafety: c135dd2bf50402d87fd12884cbad5d5e64850edd
React: b229c49ed5898dab46d60f61ed5a0bfa2ee2fadb
React-callinvoker: 2ac508e92c8bd9cf834cc7d7787d94352e4af58f
React-Core: 325b4f6d9162ae8b9a6ff42fe78e260eb124180d
React-CoreModules: 558041e5258f70cd1092f82778d07b8b2ff01897
React-cxxreact: 8fff17cbe76e6a8f9991b59552e1235429f9c74b
React-Core: 13cdd1558d0b3f6d9d5a22e14d89150280e79f02
React-CoreModules: b07a6744f48305405e67c845ebf481b6551b712a
React-cxxreact: 1055a86c66ac35b4e80bd5fb766aed5f494dfff4
React-debug: 0a5fcdbacc6becba0521e910c1bcfdb20f32a3f6
React-defaultsnativemodule: 618dc50a0fad41b489997c3eb7aba3a74479fd14
React-domnativemodule: 7ba599afb6c2a7ec3eb6450153e2efe0b8747e9a
React-Fabric: 252112089d2c63308f4cbfade4010b6606db67d1
React-FabricComponents: 3c0f75321680d14d124438ab279c64ec2a3d13c4
React-FabricImage: 728b8061cdec2857ca885fd605ee03ad43ffca98
React-defaultsnativemodule: 4bb28fc97fee5be63a9ebf8f7a435cfe8ba69459
React-domnativemodule: b36a11c2597243d7563985028c51ece988d8ae33
React-Fabric: afc561718f25b2cd800b709d934101afe376a12c
React-FabricComponents: f4e0a4e18a27bf6d39cbf2a0b42f37a92fa4e37f
React-FabricImage: 37d8e8b672eda68a19d71143eb65148084efb325
React-featureflags: 19682e02ef5861d96b992af16a19109c3dfc1200
React-featureflagsnativemodule: 23528c7e7d50782b7ef0804168ba40bbaf1e86ab
React-graphics: fefe48f71bfe6f48fd037f59e8277b12e91b6be1
React-hermes: a9a0c8377627b5506ef9a7b6f60a805c306e3f51
React-idlecallbacksnativemodule: 7e2b6a3b70e042f89cd91dbd73c479bb39a72a7e
React-ImageManager: e3300996ac2e2914bf821f71e2f2c92ae6e62ae2
React-jserrorhandler: fa75876c662e5d7e79d6efc763fc9f4c88e26986
React-jsi: f3f51595cc4c089037b536368f016d4742bf9cf7
React-jsiexecutor: cca6c232db461e2fd213a11e9364cfa6fdaa20eb
React-jsinspector: 2bd4c9fddf189d6ec2abf4948461060502582bef
React-jsinspectortracing: a417d8a0ad481edaa415734b4dac81e3e5ee7dc6
React-jsitracing: 1ff7172c5b0522cbf6c98d82bdbb160e49b5804e
React-logger: 018826bfd51b9f18e87f67db1590bc510ad20664
React-Mapbuffer: 3c11cee7737609275c7b66bd0b1de475f094cedf
React-microtasksnativemodule: 843f352b32aacbe13a9c750190d34df44c3e6c2c
react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba
React-NativeModulesApple: 88433b6946778bea9c153e27b671de15411bf225
React-perflogger: 9e8d3c0dc0194eb932162812a168aa5dc662f418
React-performancetimeline: 5a2d6efef52bdcefac079c7baa30934978acd023
React-featureflagsnativemodule: d7cddf6d907b4e5ab84f9e744b7e88461656e48c
React-graphics: b0f78580cdaf5800d25437e3d41cc6c3d83b7aea
React-hermes: 71186f872c932e4574d5feb3ed754dda63a0b3bd
React-idlecallbacksnativemodule: dd2af19cdd3bc55149d17a2409ed72b694dfbe9c
React-ImageManager: a77dde8d5aa6a2b6962c702bf3a47695ef0aa32b
React-jserrorhandler: 9c14e89f12d5904257a79aaf84a70cd2e5ac07ba
React-jsi: 0775a66820496769ad83e629f0f5cce621a57fc7
React-jsiexecutor: 2cf5ba481386803f3c88b85c63fa102cba5d769e
React-jsinspector: 8052d532bb7a98b6e021755674659802fb140cc5
React-jsinspectortracing: bdd8fd0adcb4813663562e7874c5842449df6d8a
React-jsitracing: 2bab3bf55de3d04baf205def375fa6643c47c794
React-logger: 795cd5055782db394f187f9db0477d4b25b44291
React-Mapbuffer: 0502faf46cab8fb89cfc7bf3e6c6109b6ef9b5de
React-microtasksnativemodule: 663bc64e3a96c5fc91081923ae7481adc1359a78
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
React-NativeModulesApple: 16fbd5b040ff6c492dacc361d49e63cba7a6a7a1
React-perflogger: ab51b7592532a0ea45bf6eed7e6cae14a368b678
React-performancetimeline: bc2e48198ec814d578ac8401f65d78a574358203
React-RCTActionSheet: 592674cf61142497e0e820688f5a696e41bf16dd
React-RCTAnimation: e6d669872f9b3b4ab9527aab283b7c49283236b7
React-RCTAppDelegate: de2343fe08be4c945d57e0ecce44afcc7dd8fc03
React-RCTBlob: 3e2dce94c56218becc4b32b627fc2293149f798d
React-RCTFabric: cac2c033381d79a5956e08550b0220cb2d78ea93
React-RCTFBReactNativeSpec: d10ca5e0ccbfeac8c047361fedf8e4ac653887b6
React-RCTImage: dc04b176c022d12a8f55ae7a7279b1e091066ae0
React-RCTLinking: 88f5e37fe4f26fbc80791aa2a5f01baf9b9a3fd5
React-RCTNetwork: f213693565efbd698b8e9c18d700a514b49c0c8e
React-RCTSettings: a2d32a90c45a3575568cad850abc45924999b8a5
React-RCTText: 54cdcd1cbf6f6a91dc6317f5d2c2b7fc3f6bf7a0
React-RCTVibration: 11dae0e7f577b5807bb7d31e2e881eb46f854fd4
React-RCTAnimation: 8fbb8dba757b49c78f4db403133ab6399a4ce952
React-RCTAppDelegate: 7f88baa8cb4e5d6c38bb4d84339925c70c9ac864
React-RCTBlob: f89b162d0fe6b570a18e755eb16cbe356d3c6d17
React-RCTFabric: 8ad6d875abe6e87312cef90e4b15ef7f6bed72e6
React-RCTFBReactNativeSpec: 8c29630c2f379c729300e4c1e540f3d1b78d1936
React-RCTImage: ccac9969940f170503857733f9a5f63578e106e1
React-RCTLinking: d82427bbf18415a3732105383dff119131cadd90
React-RCTNetwork: 12ad4d0fbde939e00251ca5ca890da2e6825cc3c
React-RCTSettings: e7865bf9f455abf427da349c855f8644b5c39afa
React-RCTText: 2cdfd88745059ec3202a0842ea75a956c7d6f27d
React-RCTVibration: a3a1458e6230dfd64b3768ebc0a4aac430d9d508
React-rendererconsistency: 64e897e00d2568fd8dfe31e2496f80e85c0aaad1
React-rendererdebug: 41ce452460c44bba715d9e41d5493a96de277764
React-rendererdebug: a3f6d3ae7d2fa0035885026756281c07ee32479e
React-rncore: 58748c2aa445f56b99e5118dad0aedb51c40ce9f
React-RuntimeApple: 7785ed0d8ae54da65a88736bb63ca97608a6d933
React-RuntimeCore: 6029ea70bc77f98cfd43ebe69217f14e93ba1f12
React-RuntimeApple: f0fda7bacabd32daa099cfda8f07466c30acd149
React-RuntimeCore: 683ee0b6a76d4b4bf6fbf83a541895b4887cc636
React-runtimeexecutor: a188df372373baf5066e6e229177836488799f80
React-RuntimeHermes: a264609c28b796edfffc8ae4cb8fad1773ab948b
React-runtimescheduler: 23ec3a1e0fb1ec752d1a9c1fb15258c30bfc7222
React-RuntimeHermes: 907c8e9bec13ea6466b94828c088c24590d4d0b6
React-runtimescheduler: a2e2a39125dd6426b5d8b773f689d660cd7c5f60
React-timing: bb220a53a795ed57976a4855c521f3de2f298fe5
React-utils: 3b054aaebe658fc710a8d239d0e4b9fd3e0b78f9
ReactAppDependencyProvider: a1fb08dfdc7ebc387b2e54cfc9decd283ed821d8
ReactCodegen: 008c319179d681a6a00966edfc67fda68f9fbb2e
ReactCommon: 0c097b53f03d6bf166edbcd0915da32f3015dd90
RNVectorIcons: bd818296a51dc2bb8c3bd97a3ca399df1afe216d
React-utils: 300d8bbb6555dcffaca71e7a0663201b5c7edbbc
ReactAppDependencyProvider: f2e81d80afd71a8058589e19d8a134243fa53f17
ReactCodegen: a63a0ab6ae824aef2e8c744981edd718b16eb9f2
ReactCommon: 3d39389f8e2a2157d5c999f8fba57bd1c8f226f0
RNVectorIcons: 14a0c42f16a26bcc3e79a19bc1c5718284b1d469
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: afd04ff05ebe0121a00c468a8a3c8080221cb14c
Yoga: 9b7fb56e7b08cde60e2153344fa6afbd88e5d99f

PODFILE CHECKSUM: a15b54e8d191759ce7fcccb262b8753851ec9fde

Expand Down
2 changes: 2 additions & 0 deletions tools/powersynctests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"start": "react-native start"
},
"dependencies": {
"@azure/core-asynciterator-polyfill": "^1.0.2",
"@op-engineering/op-sqlite": "^14.0.2",
"@powersync/common": "workspace:*",
"@powersync/op-sqlite": "workspace:*",
Expand All @@ -30,6 +31,7 @@
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/plugin-transform-async-generator-functions": "^7.27.1",
"@babel/plugin-transform-class-static-block": "^7.26.0",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
Expand Down
6 changes: 3 additions & 3 deletions tools/powersynctests/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*
* @format
*/

import '@azure/core-asynciterator-polyfill';
import React from 'react';
import { SafeAreaView, ScrollView, StatusBar, useColorScheme } from 'react-native';

Expand All @@ -17,7 +17,7 @@ function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark';

const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter
};

const [] = React.useState(registerBaseTests());
Expand All @@ -40,7 +40,7 @@ function App(): React.JSX.Element {
/>
<ScrollView style={backgroundStyle}>
{/* <PowerSyncIndicator /> */}
{rootSuite.suites.map(suite => (
{rootSuite.suites.map((suite) => (
<SuitWidget key={suite.title} suit={suite} />
))}
</ScrollView>
Expand Down
43 changes: 43 additions & 0 deletions tools/powersynctests/src/tests/queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,49 @@ export function registerBaseTests() {
await watched;
});

it('Should reflect writeTransaction updates on read connections (iterator)', async () => {
const watched = new Promise<void>(async (resolve) => {
for await (const result of db.watch('SELECT COUNT(*) as count FROM users', [])) {
if (result.rows?.item(0).count == 1) {
resolve();
}
}
});

await db.writeTransaction(async (tx) => {
return createTestUser(tx);
});

// The watched query should have updated
await watched;
});

it('Should throw for async iterator watch errors', async () => {
let error: Error | undefined;
try {
// The table here does not exist, so it should throw an error
for await (const result of db.watch('SELECT COUNT(*) as count FROM faketable', [])) {
}
} catch (ex) {
error = ex as Error;
}

expect(error!.message).to.include('no such table: faketable');
});

it('Should throw for async iterator invalid query errors', async () => {
let error: Error | undefined;
try {
// Invalid SQL
for await (const result of db.watch('invalidsyntax', [])) {
}
} catch (ex) {
error = ex as Error;
}

expect(error!.message).to.include('sqlite query error');
});

it('Should reflect writeLock updates on read connections ', async () => {
const numberOfUsers = 1000;

Expand Down