You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/docs/docs/modules/skip-sql/index.md
+107-8Lines changed: 107 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -94,27 +94,59 @@ try sqlite.transaction {
94
94
95
95
### Schema Migration
96
96
97
-
There is no built-in support for schema migrations. Following is a part of a sample of how you might perform migrations in your own app.
97
+
SkipSQL provides built-in support for version-based schema migrations using SQLite's `userVersion` pragma. The `migrate()` method accepts an array of migration closures, each representing a schema version. Only migrations that haven't been applied yet will run, each within its own transaction:
98
+
99
+
```swift
100
+
try ctx.migrate(migrations: [
101
+
// Version 1: initial schema
102
+
{ ctx in
103
+
try ctx.exec(sql: "CREATE TABLE DATA_ITEM (ID INTEGER PRIMARY KEY AUTOINCREMENT)")
Each migration runs in a transaction and increments `userVersion` upon success. If a migration fails, it rolls back without affecting subsequent migrations. You can safely add new closures to the end of the array as your schema evolves — previously applied migrations are skipped.
117
+
118
+
#### Helper Methods
119
+
120
+
Additional schema utilities are available:
121
+
122
+
```swift
123
+
// Check if a table exists in the database
124
+
let exists =try ctx.tableExists("DATA_ITEM") // true
125
+
126
+
// Create a table from an SQLCodable type (safe if already exists)
127
+
try ctx.createTableIfNotExists(DemoTable.self)
128
+
129
+
// Add a column to an existing table (safe if already exists)
130
+
try ctx.addColumnIfNotExists(DemoTable.newColumn, to: DemoTable.table)
131
+
```
132
+
133
+
#### Manual Migration
134
+
135
+
For more control, you can implement migrations manually using the `userVersion` pragma directly:
98
136
99
137
```swift
100
-
// track the version of the schema with the `userVersion` pragma, which can be used for schema migration
Copy file name to clipboardExpand all lines: src/content/docs/docs/modules/skip-unit/index.md
+46-7Lines changed: 46 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -58,7 +58,11 @@ By default, Skip uses the simulated Robolectric Android environment to run your
58
58
59
59
## Writing Tests
60
60
61
-
A standard Skip test is just a plain XCTest:
61
+
Skip Lite supports both XCTest and a subset of Swift Testing for writing transpiled tests.
62
+
63
+
### XCTest
64
+
65
+
A standard Skip test using XCTest:
62
66
63
67
```swift
64
68
importXCTest
@@ -70,16 +74,51 @@ final class MyUnitTests: XCTestCase {
70
74
}
71
75
```
72
76
77
+
### Swift Testing
78
+
79
+
You can also write tests using Swift Testing's `@Test` and `@Suite` annotations. The `#expect` macro maps to assertion functions and `#require` maps to `requireNotNil`:
80
+
81
+
```swift
82
+
importTesting
83
+
84
+
@SuitestructMathTests {
85
+
@Testfuncaddition() {
86
+
#expect(1+1==2)
87
+
}
88
+
89
+
@Testfuncinequality() {
90
+
#expect(3!=5)
91
+
}
92
+
}
93
+
```
94
+
95
+
Freestanding `@Test` functions (not inside a struct or class) are also supported and are automatically wrapped in a generated test class for JUnit:
96
+
97
+
```swift
98
+
importTesting
99
+
100
+
@Testfuncaddition() {
101
+
#expect(1+2==3)
102
+
}
103
+
```
104
+
105
+
The following Swift Testing features are supported:
106
+
-`@Test` functions (both as members and freestanding)
107
+
-`@Suite` types
108
+
-`#expect` with equality (`==`), inequality (`!=`), comparisons (`>`, `<`, `>=`, `<=`), and boolean expressions
109
+
-`#require` for optional unwrapping
110
+
111
+
Not all Swift Testing features are currently transpiled. Parameterized tests, traits, and tags are not supported.
112
+
73
113
**Note**: The Skip transpiler currently does not have access to the internal API of the module being tested. If you take advantage of Swift's `@testable imports` to exercise internal API, the transpiler will not be able to perform its usual type inference when translating your test code. This just means that you might have to be more explicit about types and to fully-qualify values (e.g. `MyType.value` instead of just `.value`) when unit testing internal API.
74
114
75
115
## Running Tests
76
116
77
117
The transpiled unit tests are intended to be run as part of the standard Xcode and Swift Package Manager testing process.
78
118
79
-
This is done by adding one additional test class to the project's `Tests/ModuleNameTests/` folder named `XCSkipTests.swift`.
119
+
The tests are driven by a test harness file called `XCSkipTests.swift`. If your test target does not already contain a file with this name, the Skip build plugin will auto-generate one during the build. This means that for most projects, you do not need to create or maintain this file yourself — just run `swift test` and the harness is created for you.
80
120
81
-
This additional test class is added automatically when a library is created with the `skip init` command.
82
-
When adopting Skip into an existing process, add the test case manually:
121
+
If you need to customize the test harness (for example, to specify a device target or adjust the Gradle task), you can add your own `XCSkipTests.swift` to your test target and the build plugin will use it instead of generating one:
83
122
84
123
```
85
124
#if os(macOS) // Skip transpiled tests only run on macOS targets
@@ -90,14 +129,14 @@ import SkipTest
90
129
final class XCSkipTests: XCTestCase, XCGradleHarness {
91
130
public func testSkipModule() async throws {
92
131
try await runGradleTests(device: .none) // set device ID to run in Android emulator vs. Robolectric
93
-
}
94
-
}
132
+
}
133
+
}
95
134
#endif
96
135
```
97
136
98
137
### Running Tests from Xcode
99
138
100
-
Once the `XCSkipTests.swift` file has been added to a project, the transpiled test cases will automatically run whenever testing against the **macOS** run destination.
139
+
The transpiled test cases will automatically run whenever testing against the **macOS** run destination.
101
140
As such, you need to ensure that your Swift code compiles and runs the same on macOS and iOS.
102
141
This is a pre-requisite for Skip's parity testing, which runs the XCUnit test cases on macOS against the transpiled Kotlin tests in the Android testing environment. While many of the Foundation and SwiftUI APIs are identical on macOS and iOS, you may occasionally have to work around minor differences.
Copy file name to clipboardExpand all lines: src/content/docs/docs/modules/skip-web/index.md
+53-1Lines changed: 53 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ SkipWeb provides two ways to display web content in Skip Lite apps:
24
24
|**Browser chrome**| Provided by the OS (address bar, back/forward, share) | You build your own toolbar and controls |
25
25
|**JavaScript access**| None — the page runs in a sandboxed browser | Full `evaluateJavaScript` support |
26
26
|**Navigation control**| None — the user navigates freely within the browser | Programmatic back/forward, reload, URL changes |
27
-
|**Cookie/session sharing**| Shares the user's browser cookies and autofill |Isolated web engine per `WebView` instance|
27
+
|**Cookie/session sharing**| Shares the user's browser cookies and autofill |Uses the app's WebView cookie store (shared across WebViews by default; not the same store as Safari/Chrome)|
28
28
|**Customization**| Custom share-sheet actions | Full layout control, scroll delegates, snapshot API |
29
29
30
30
Use `openWebBrowser` when you want to send the user to a web page with minimal code and maximum platform-native UX. Use `WebView` when you need to embed web content as part of your app's UI with programmatic control.
@@ -488,6 +488,58 @@ extension View {
488
488
}
489
489
```
490
490
491
+
## Cookies, Storage, and Cache
492
+
493
+
`SkipWeb` exposes portable browser-data APIs through `WebEngine` and `WebViewNavigator`:
494
+
495
+
-`cookies(for:)`
496
+
-`cookieHeader(for:)`
497
+
-`setCookie(_:requestURL:)`
498
+
-`applySetCookieHeaders(_:for:)`
499
+
-`clearCookies()`
500
+
-`removeData(ofTypes:modifiedSince:)`
501
+
502
+
Supporting types:
503
+
504
+
-`WebCookie` (`name`, `value`, optional `domain`/`path`/`expires`, plus `isSecure`/`isHTTPOnly`)
- iOS uses the web view's `websiteDataStore.httpCookieStore`.
532
+
- On iOS, cookie scope follows the `WKWebsiteDataStore` attached to that `WKWebView`.
533
+
- In default SkipWeb usage, that is WebKit's shared default data store, so cookies are shared across SkipWeb web views in the app.
534
+
- On iOS, a custom `WKWebView` with a different data store (for example `WKWebsiteDataStore.nonPersistent()`) uses that store instead.
535
+
- Android uses `android.webkit.CookieManager`.
536
+
- On Android, `CookieManager` is a process-wide singleton store shared by all `WebView` instances (not per-`WebView` configurable).
537
+
-`cookies(for:)` returns URL-matching cookies; on Android this is best-effort because `CookieManager` reads as a cookie-header string (limited metadata).
538
+
-`setCookie(_:requestURL:)` requires either `cookie.domain` or a `requestURL` host; otherwise it throws `WebCookieError.missingCookieDomain`.
539
+
-`removeData(ofTypes:modifiedSince:)` maps to iOS `WKWebsiteDataStore.removeData`.
540
+
- On Android, `removeData` requires `modifiedSince == .distantPast` when `ofTypes` is non-empty; otherwise it throws `WebDataRemovalError.unsupportedModifiedSinceOnAndroid`.
541
+
- Android data removal is bucket-level (cookies/cache/storage), not timestamp-granular, and may clear a broader bucket than an individual requested data type.
542
+
491
543
## Contribution
492
544
493
545
Many delegates that are provided by `WKWebView` are not yet implemented in this project,
Copy file name to clipboardExpand all lines: src/content/docs/docs/testing.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,9 @@ Skip provides several ways to test your code on Android, depending on whether yo
15
15
16
16
Skip Lite transpiles your Swift source into Kotlin, and your XCTest test cases into JUnit tests. This means your tests run as standard JUnit on the Android side, which plugs into the well-established Gradle testing infrastructure.
17
17
18
-
When you create a Skip Lite package with `skip init`, an `XCSkipTests.swift` file is automatically added to your test target:
18
+
The transpiled tests are driven by a test harness file called `XCSkipTests.swift`. If your test target does not already contain a file with this name, the Skip build plugin will auto-generate one during the build. This means that for most projects, you do not need to create or maintain this file yourself — just run `swift test` and the harness is created for you.
19
+
20
+
If you need to customize the test harness (for example, to specify a device target or adjust the Gradle task), you can add your own `XCSkipTests.swift` to your test target and the build plugin will use it instead of generating one. A typical custom harness looks like this:
19
21
20
22
```swift
21
23
#ifos(macOS) // Skip transpiled tests only run on macOS targets
@@ -32,7 +34,10 @@ final class XCSkipTests: XCTestCase, XCGradleHarness {
32
34
33
35
This test harness is what connects Xcode to the Gradle test pipeline. When you run tests against the **macOS** destination in Xcode (or via `swift test` on the command line), `testSkipModule()` triggers the full transpilation and Gradle build, runs the JUnit tests, and reports the results back as XCTest outcomes. The net effect is that you get parity testing across both platforms from a single test run.
34
36
35
-
The limitation is that only XCTest-style tests are supported. Your Swift tests are transpiled into Kotlin JUnit, so they are subject to the same transpilation constraints as the rest of your Skip Lite code. Swift Testing (`@Test`) is not available in this mode.
37
+
Your Swift tests are transpiled into Kotlin JUnit, so they are subject to the same transpilation constraints as the rest of your Skip Lite code. Both XCTest and a subset of Swift Testing are supported:
38
+
39
+
-**XCTest**: Classes inheriting from `XCTestCase` with `test`-prefixed methods are transpiled into JUnit test classes with `@Test` annotations. Standard `XCTAssert*` functions map to JUnit assertions.
40
+
-**Swift Testing**: Functions annotated with `@Test` and types annotated with `@Suite` are also transpiled into JUnit tests. The `#expect` macro is mapped to assertion functions (`expectEqual`, `expectNotEqual`, `expectTrue`, `expectGreaterThan`, etc.) and `#require` is mapped to `requireNotNil`. Freestanding `@Test` functions (not inside a struct or class) are automatically wrapped in a generated test class. Not all Swift Testing features are supported — parameterized tests, traits, and tags are not currently transpiled.
|| Skip Lite (Robolectric) | Skip Lite (Instrumented) | Skip Fuse (CLI) | Skip Fuse (APK) |
111
116
|---|---|---|---|---|
112
117
|**Command**|`swift test`|`ANDROID_SERIAL=… swift test`|`skip android test`|`skip android test --apk`|
113
-
|**Test framework**| XCTest only (transpiled to JUnit) | XCTest only (transpiled to JUnit) | XCTest + Swift Testing | Swift Testing only |
118
+
|**Test framework**| XCTest + Swift Testing (transpiled to JUnit) | XCTest + Swift Testing (transpiled to JUnit) | XCTest + Swift Testing | Swift Testing only |
114
119
|**Runs on**| Host JVM (macOS/Linux) | Android emulator/device | Android emulator/device via `adb shell`| Android emulator/device as installed APK |
115
120
|**Android APIs**| Simulated via Robolectric | Full | Not available (no JVM/JNI) | Full (real app process with JNI) |
116
121
|**Resource bundles**| Managed by Gradle | Managed by Gradle | Yes (sidecar `.resources` dirs) | No (no Foundation APK bundle support) |
0 commit comments