also looking at this
feat(webkitgtk): add the GTK3 WebKit provider craft's Linux binary needs
#272
7 files
+425
-4
| @@ -0,0 +1,105 @@ | ||
| 1 | // craft-native.org's Linux artifact could not be published: its binary links | |
| 2 | // seven libraries the recipe never provided, and ELF normalization refused it. | |
| 3 | // Three of those sonames belong to a WebKit API that had no owner in the | |
| 4 | // catalog at all, so a dependency declaration alone could not have fixed it. | |
| 5 | // These tests pin the provider's identity and the closure that must exist. | |
| 6 | ||
| 7 | import { describe, expect, it } from 'bun:test' | |
| 8 | import { recipeDepsToSpecs } from '../src/dependency-spec' | |
| 9 | import { pantry } from '../src/packages' | |
| 10 | import { recipe as craft } from '../src/recipes/craft-native.org' | |
| 11 | import { recipe as webkitgtk } from '../src/recipes/webkitgtk.org' | |
| 12 | ||
| 13 | const cmakeArgs = (webkitgtk.build?.env?.CMAKE_ARGS ?? []) as string[] | |
| 14 | const byDomain = new Map(Object.values(pantry).map(entry => [(entry as any).domain, entry as any])) | |
| 15 | ||
| 16 | describe('the WebKitGTK provider owns the API craft actually links', () => { | |
| 17 | it('selects the GTK3 4.1 API rather than the GTK4 6.0 default', () => { | |
| 18 | // OptionsGTK.cmake defaults USE_GTK4 ON, which produces webkitgtk-6.0. | |
| 19 | // Only USE_GTK4=OFF yields WEBKITGTK_API_INFIX "2" and so the | |
| 20 | // libwebkit2gtk-4.1 / libjavascriptcoregtk-4.1 sonames craft needs. | |
| 21 | expect(cmakeArgs).toContain('-DUSE_GTK4=OFF') | |
| 22 | expect(cmakeArgs).toContain('-DPORT=GTK') | |
| 23 | }) | |
| 24 | ||
| 25 | it('is not a WPE or GTK4 substitute', () => { | |
| 26 | expect(webkitgtk.domain).toBe('webkitgtk.org') | |
| 27 | expect(webkitgtk.domain).not.toContain('wpewebkit') | |
| 28 | expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('wpewebkit') | |
| 29 | expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('gtk4') | |
| 30 | }) | |
| 31 | ||
| 32 | it('ships the helper processes and injected bundle its libraries spawn', () => { | |
| 33 | // libwebkit2gtk does not render in-process: it execs WebKitWebProcess and | |
| 34 | // WebKitNetworkProcess from PKGLIBEXECDIR and dlopens the injected bundle. | |
| 35 | // A consumer that bundles only the .so gets a library that fails on the | |
| 36 | // first page it creates. | |
| 37 | expect(webkitgtk.runtimeResources).toEqual([ | |
| 38 | 'libexec/webkit2gtk-4.1', | |
| 39 | 'lib/webkit2gtk-4.1/injected-bundle', | |
| 40 | ]) | |
| 41 | }) | |
| 42 | ||
| 43 | it('builds only where the GTK3 stack is published', () => { | |
| 44 | expect(webkitgtk.platforms).toEqual(['linux/x86-64']) | |
| 45 | }) | |
| 46 | }) | |
| 47 | ||
| 48 | describe('the provider only claims a closure the catalog can satisfy', () => { | |
| 49 | it('disables GStreamer itself, not merely video and web audio', () => { | |
| 50 | // GStreamerChecks.cmake guards on USE_GSTREAMER and then calls | |
| 51 | // find_package(GStreamer REQUIRED COMPONENTS app pbutils) with app and | |
| 52 | // pbutils listed unconditionally — ENABLE_VIDEO=OFF alone still fails | |
| 53 | // configure. Pantry publishes gstreamer.freedesktop.org/orc and no | |
| 54 | // GStreamer core, so the subsystem is off until those recipes exist. | |
| 55 | expect(cmakeArgs).toContain('-DUSE_GSTREAMER=OFF') | |
| 56 | expect(cmakeArgs).toContain('-DENABLE_VIDEO=OFF') | |
| 57 | expect(cmakeArgs).toContain('-DENABLE_WEB_AUDIO=OFF') | |
| 58 | expect(JSON.stringify(webkitgtk.dependencies)).not.toContain('gstreamer') | |
| 59 | }) | |
| 60 | ||
| 61 | it('turns off every feature whose provider the catalog lacks', () => { | |
| 62 | // Each has a find_package ... FATAL_ERROR in OptionsGTK.cmake and no | |
| 63 | // provider here: Enchant, libhyphen, libmanette, libdrm/GBM. | |
| 64 | for (const flag of ['-DENABLE_SPELLCHECK=OFF', '-DUSE_LIBHYPHEN=OFF', '-DENABLE_GAMEPAD=OFF', '-DUSE_LIBDRM=OFF', '-DUSE_GBM=OFF']) | |
| 65 | expect(cmakeArgs).toContain(flag) | |
| 66 | }) | |
| 67 | ||
| 68 | it('requires libsoup3, which is what the 4.1 API is', () => { | |
| 69 | // 2.54 calls find_package(Soup3 3.0.0 REQUIRED) unconditionally; the | |
| 70 | // libsoup2 API 4.0 variant is gone. | |
| 71 | expect((webkitgtk.dependencies as any)['libsoup.org']).toBe('^3') | |
| 72 | }) | |
| 73 | ||
| 74 | it('names only domains that exist in the catalog', () => { | |
| 75 | const declared = Object.keys(webkitgtk.dependencies ?? {}) | |
| 76 | expect(declared.length).toBeGreaterThan(0) | |
| 77 | expect(declared.filter(domain => !byDomain.has(domain))).toEqual([]) | |
| 78 | }) | |
| 79 | }) | |
| 80 | ||
| 81 | describe("craft declares its Linux runtime closure and nothing on Darwin", () => { | |
| 82 | const specs = recipeDepsToSpecs(craft.dependencies as any) | |
| 83 | ||
| 84 | it('covers each unresolved library through its owning provider', () => { | |
| 85 | // libgtk-3 / libgdk-3 → gtk3; libglib-2.0 / libgobject-2.0 / libgio-2.0 → | |
| 86 | // glib; libwebkit2gtk-4.1 / libjavascriptcoregtk-4.1 → webkitgtk. | |
| 87 | expect(specs).toEqual([ | |
| 88 | 'linux:gtk.org/gtk3^3.24', | |
| 89 | 'linux:gnome.org/glib^2', | |
| 90 | 'linux:webkitgtk.org^2.54', | |
| 91 | ]) | |
| 92 | }) | |
| 93 | ||
| 94 | it('adds nothing on Darwin, which uses the system WebKit framework', () => { | |
| 95 | expect(specs.every(spec => spec.startsWith('linux:'))).toBe(true) | |
| 96 | expect(specs.some(spec => spec.startsWith('darwin'))).toBe(false) | |
| 97 | }) | |
| 98 | ||
| 99 | it('points every declared provider at a real catalog entry', () => { | |
| 100 | for (const spec of specs) { | |
| 101 | const domain = spec.slice('linux:'.length).replace(/[@^~<>=].*$/, '') | |
| 102 | expect(byDomain.get(domain)).toBeDefined() | |
| 103 | } | |
| 104 | }) | |
| 105 | }) | |