Skip to content

Commit 2b2d9f9

Browse files
committed
test(firestore): cover pipeline exit frame and receiver expression lowering on Android
1 parent c933111 commit 2b2d9f9

2 files changed

Lines changed: 113 additions & 4 deletions

File tree

okf-bundle/packages/firestore/pipeline-coverage-work-queue.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ timestamp: 2026-06-25T12:00:00Z
88

99
# Pipeline coverage and parity — work queue
1010

11-
> **IN PROGRESS:** **M** `commit`. **L** landing now.
11+
> **IN PROGRESS:** **N** queued — iOS stage coercion (~293 missed).
1212
> **Goal/order:** platform parity first; then TS/native coverage toward intractable limits. Links: [parity](pipeline-platform-parity.md), [SDK audit](pipeline-sdk-support-audit.md), [coverage](../../testing/coverage-design.md), [e2e](../../testing/running-e2e.md), [architecture](pipelines.md).
1313
1414
---
@@ -76,12 +76,12 @@ Gate prerequisites before any `:test-cover` ([host rule](../../testing/change-au
7676

7777
## Current snapshot
7878

79-
**Label:** `lm-commit-pending`; **harness:** full test app (committed)
79+
**Label:** `n-queued`; **harness:** full test app (committed)
8080

8181
**Next item:** **N** — iOS stage coercion (~293 missed).
8282

8383
| **L** parsed-aggregate tail | `test(firestore): cover pipeline aggregate expression argument lowering on Android` | **closed** | **closed** | **closed** |||| `arrayAgg`/`arrayAggDistinct` expr args |
84-
| **M** exit/receiver/vector | `test(firestore): cover pipeline exit frame and receiver expression lowering on Android` | **closed** | **closed** | open | `commit` ||| review 141/141/136; NodeBuilder 75.03%; exit 73→44 missed |
84+
| **M** exit/receiver/vector | `test(firestore): cover pipeline exit frame and receiver expression lowering on Android` | **closed** | **closed** | **closed** | ||| 3 e2e; NodeBuilder 75.03%; exit 73→44 missed |
8585

8686
| **J2** P-005 `integerLiteral` | `fix(firestore, android): align pipeline integerLiteral constant lowering with iOS` | **closed** | **closed** | **closed** |||| P-005 → Resolved; CFBoolean deferral accepted |
8787
| **J3** P-010 stage option expressions | `fix(firestore, android): align pipeline stage option expression fields with iOS` | **closed** | **closed** | **closed** |||| P-010 → Resolved |
@@ -306,7 +306,7 @@ Per [SDK audit §6](pipeline-sdk-support-audit.md): one function/commit; remove
306306

307307
**Gate for Phase K+:** J0 complete + **J0b** committed + J1–J6 bridge commits + parity **Resolved** updated.
308308

309-
**Current gates:** **M** commit pending. **L** complete.
309+
**Current gates:** **N** queued. **L** and **M** complete.
310310

311311
---
312312

packages/firestore/e2e/Pipeline.e2e.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,6 +3188,115 @@ describe('FirestorePipeline', function () {
31883188
});
31893189
});
31903190

3191+
describe('exit frame and receiver expression lowering coverage', function () {
3192+
it('lowers vector distance receiver chains with expression vector operands', async function () {
3193+
const { execute, field, cosineDistance, dotProduct } = firestorePipelinesModular;
3194+
const { getFirestore, doc, setDoc, vector } = firestoreModular;
3195+
const db = getFirestore(DATABASE_ID);
3196+
const docPath = `${COLLECTION}/${Utils.randString(12, '#aA')}`;
3197+
3198+
await setDoc(doc(db, docPath), {
3199+
embedding: vector([1.0, 0.0, 0.0]),
3200+
query: vector([0.0, 1.0, 0.0]),
3201+
});
3202+
3203+
const snapshot = await execute(
3204+
db
3205+
.pipeline()
3206+
.documents([docPath])
3207+
.select(
3208+
cosineDistance(field('embedding'), field('query')).as('globalCosDist'),
3209+
field('embedding').dotProduct(field('query')).as('fluentDot'),
3210+
field('embedding').euclideanDistance(field('query')).as('fluentEuclid'),
3211+
dotProduct(field('embedding'), field('query')).as('globalDot'),
3212+
),
3213+
);
3214+
3215+
snapshot.results.should.have.length(1);
3216+
const data = snapshot.results[0].data();
3217+
should(data.globalCosDist).be.approximately(1, 0.0001);
3218+
should(data.fluentDot).be.approximately(0, 0.0001);
3219+
should(data.fluentEuclid).be.approximately(Math.sqrt(2), 0.0001);
3220+
should(data.globalDot).be.approximately(0, 0.0001);
3221+
});
3222+
3223+
it('lowers fluent receiver exit frames with expression map, array, and extrema operands', async function () {
3224+
const { execute, field, logicalMaximum, logicalMinimum } = firestorePipelinesModular;
3225+
const { getFirestore, doc, setDoc } = firestoreModular;
3226+
const db = getFirestore(DATABASE_ID);
3227+
const docPath = `${COLLECTION}/${Utils.randString(12, '#aA')}`;
3228+
3229+
await setDoc(doc(db, docPath), {
3230+
metadata: { theme: 'dark', locale: 'en' },
3231+
keyName: 'theme',
3232+
scores: [10, 25, 40],
3233+
idx: 1,
3234+
bidA: 100,
3235+
bidB: 150,
3236+
bidC: 120,
3237+
askA: 200,
3238+
askB: 175,
3239+
askC: 190,
3240+
});
3241+
3242+
const snapshot = await execute(
3243+
db
3244+
.pipeline()
3245+
.documents([docPath])
3246+
.select(
3247+
field('metadata').mapGet(field('keyName')).as('fluentMapGet'),
3248+
field('scores').arrayGet(field('idx')).as('fluentArrayGet'),
3249+
field('bidA').logicalMaximum(field('bidB'), field('bidC')).as('fluentMaxBid'),
3250+
field('askA').logicalMinimum(field('askB'), field('askC')).as('fluentMinAsk'),
3251+
logicalMaximum(field('bidA'), field('bidB'), field('bidC')).as('globalMaxBid'),
3252+
logicalMinimum(field('askA'), field('askB'), field('askC')).as('globalMinAsk'),
3253+
),
3254+
);
3255+
3256+
snapshot.results.should.have.length(1);
3257+
const data = snapshot.results[0].data();
3258+
data.fluentMapGet.should.equal('dark');
3259+
data.fluentArrayGet.should.equal(25);
3260+
data.fluentMaxBid.should.equal(150);
3261+
data.fluentMinAsk.should.equal(175);
3262+
data.globalMaxBid.should.equal(150);
3263+
data.globalMinAsk.should.equal(175);
3264+
});
3265+
3266+
it('lowers boolean receiver and logical exit frames with expression operands', async function () {
3267+
const { execute, field, or, and } = firestorePipelinesModular;
3268+
const { getFirestore, collection, doc, setDoc } = firestoreModular;
3269+
const db = getFirestore(DATABASE_ID);
3270+
const coll = collection(
3271+
db,
3272+
`${COLLECTION}/${Utils.randString(12, '#aA')}/boolean-receiver-exit-frames`,
3273+
);
3274+
3275+
await Promise.all([
3276+
setDoc(doc(coll, 'match-a'), { score: 12, threshold: 10, tier: 'gold', region: 'EU' }),
3277+
setDoc(doc(coll, 'match-b'), { score: 12, threshold: 10, tier: 'silver', region: 'US' }),
3278+
setDoc(doc(coll, 'skip'), { score: 3, threshold: 10, tier: 'bronze', region: 'APAC' }),
3279+
]);
3280+
3281+
const snapshot = await execute(
3282+
db
3283+
.pipeline()
3284+
.collection(coll)
3285+
.where(
3286+
and(
3287+
field('score').greaterThan(field('threshold')),
3288+
or(field('tier').equal('gold'), field('region').equal('US')),
3289+
),
3290+
)
3291+
.select('score', 'tier', 'region'),
3292+
);
3293+
3294+
snapshot.results.should.have.length(2);
3295+
const tiers = snapshot.results.map(row => row.data().tier).sort();
3296+
tiers.should.eql(['gold', 'silver']);
3297+
});
3298+
});
3299+
31913300
describe('operand mode rhs shape coverage', function () {
31923301
it('coerces string, array, and boolean rhs shapes in comparisons and arithmetic', async function () {
31933302
const { execute, field, constant, add, multiply, mod, equal, equalAny, greaterThan, and } =

0 commit comments

Comments
 (0)