Skip to content

Commit

Permalink
fix: resolve FindOptionsOrder.nulls issue to accept FIRST/LAST in upp…
Browse files Browse the repository at this point in the history
…ercase

Closes #8970
  • Loading branch information
ahmedosama94 committed May 9, 2022
1 parent 78df84c commit 19cb8b3
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/query-builder/SelectQueryBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3890,9 +3890,9 @@ export class SelectQueryBuilder<Entity>
? (order[key] as any).nulls
: undefined
nulls =
nulls === "first"
nulls?.toLowerCase() === "first"
? "NULLS FIRST"
: nulls === "last"
: nulls?.toLowerCase() === "last"
? "NULLS LAST"
: undefined

Expand Down
16 changes: 16 additions & 0 deletions test/github-issues/8970/entities/TestEntity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {
Column,
Entity,
ObjectIdColumn,
PrimaryGeneratedColumn,
} from "../../../../src"

@Entity()
export class TestEntity {
@ObjectIdColumn()
@PrimaryGeneratedColumn()
id: number

@Column({ nullable: true })
testColumn: string
}
106 changes: 106 additions & 0 deletions test/github-issues/8970/issue-8970.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import "reflect-metadata"

import {
closeTestingConnections,
createTestingConnections,
} from "../../utils/test-utils"
import { DatabaseType, DataSource } from "../../../src"
import { TestEntity } from "./entities/TestEntity"
import { expect } from "chai"

describe("query builder order nulls first/last", async () => {
let dataSources: DataSource[]
const enabledDrivers: DatabaseType[] = [
"postgres",
"sqlite",
"better-sqlite3",
]

before(async () => {
dataSources = await createTestingConnections({
entities: [__dirname + "/entities/*{.js,.ts}"],
enabledDrivers,
schemaCreate: true,
dropSchema: false,
})

for (const dataSource of dataSources) {
const repository = dataSource.getRepository(TestEntity)

for (let i = 0; i < 5; i++) {
const entity = new TestEntity()
entity.testColumn = ""

await repository.save(entity)
}

for (let i = 0; i < 5; i++) {
const entity = new TestEntity()

await repository.save(entity)
}
}
})

after(async () => {
for (const dataSource of dataSources) {
await dataSource.dropDatabase()
}

await closeTestingConnections(dataSources)
})

const runTest = async (
dataSource: DataSource | undefined,
firstOrLastString: "first" | "FIRST" | "last" | "LAST",
) => {
if (!dataSource) return

const repository = dataSource.getRepository(TestEntity)
const testArray = await repository.find({
order: {
testColumn: { direction: "DESC", nulls: firstOrLastString },
},
})
const test =
["first", "FIRST"].indexOf(firstOrLastString) !== -1
? testArray.shift()
: testArray.pop()

expect(test?.testColumn).to.be.null
}

for (const enabledDriver of enabledDrivers) {
it(`first should work with lowercase (${enabledDriver})`, async () => {
const dataSource = dataSources.find(
(dataSource) => dataSource.options.type === enabledDriver,
)
expect(dataSource).to.exist
await runTest(dataSource, "first")
})

it(`FIRST should work with uppercase (${enabledDriver})`, async () => {
const dataSource = dataSources.find(
(dataSource) => dataSource.options.type === enabledDriver,
)
expect(dataSource).to.exist
await runTest(dataSource, "FIRST")
})

it(`last should work with lowercase (${enabledDriver})`, async () => {
const dataSource = dataSources.find(
(dataSource) => dataSource.options.type === enabledDriver,
)
expect(dataSource).to.exist
await runTest(dataSource, "last")
})

it(`LAST should work with uppercase (${enabledDriver})`, async () => {
const dataSource = dataSources.find(
(dataSource) => dataSource.options.type === enabledDriver,
)
expect(dataSource).to.exist
await runTest(dataSource, "LAST")
})
}
})

0 comments on commit 19cb8b3

Please sign in to comment.