-
Notifications
You must be signed in to change notification settings - Fork 39
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
feat: Specs For Searches #3199
feat: Specs For Searches #3199
Conversation
Matching the whole text entered exactly is boosted by 8. Matching all the words entered exactly is boosted by 4. Matching some words ebtered exactly is boosted by 2. Glob matching is applied for words with more than three characters is not boosted. To Do: Deal with @ and # symbols. To Do: Find a way to match unicode, e.g. kyrillic letters.
@Mogge this is just a rough guideline how to improve the quality of your tests. Of course it needs to be continued.
Test summaryRun details
View run in Cypress Dashboard ➡️ This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
Test summaryRun details
View run in Cypress Dashboard ➡️ This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard |
this was in the list of |
return `(${tmp})^${boost}` | ||
} | ||
|
||
const matchSomeWordsExactly = (str, boost = 2) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,61 @@
+export function queryString(str) {
+ const normalizedString = normalizeWhitespace(str)
+ const escapedString = escapeSpecialCharacters(normalizedString)
+ return `
+${matchWholeText(escapedString)}
+${matchEachWordExactly(escapedString)}
+${matchSomeWordsExactly(escapedString)}
+${matchBeginningOfWords(escapedString)}
+`
+}
+
+const matchWholeText = (str, boost = 8) => {
+ return `"${str}"^${boost}`
+}
+
+const matchEachWordExactly = (str, boost = 4) => {
+ if (str.includes(' ')) {
+ const tmp = str
+ .split(' ')
+ .map((s, i) => (i === 0 ? `"${s}"` : `AND "${s}"`))
+ .join(' ')
+ return `(${tmp})^${boost}`
+ } else {
+ return ''
+ }
if (!str.includes(' ')) return ''
const tmp = str
.split(' ')
.map((s, i) => (i === 0 ? `"${s}"` : `AND "${s}"`))
.join(' ')
return `(${tmp})^${boost}`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.split(' ') | ||
.map(s => `"${s}"^${boost}`) | ||
.join(' ') | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,61 @@
+export function queryString(str) {
+ const normalizedString = normalizeWhitespace(str)
+ const escapedString = escapeSpecialCharacters(normalizedString)
+ return `
+${matchWholeText(escapedString)}
+${matchEachWordExactly(escapedString)}
+${matchSomeWordsExactly(escapedString)}
+${matchBeginningOfWords(escapedString)}
+`
+}
+
+const matchWholeText = (str, boost = 8) => {
+ return `"${str}"^${boost}`
+}
+
+const matchEachWordExactly = (str, boost = 4) => {
+ if (str.includes(' ')) {
+ const tmp = str
+ .split(' ')
+ .map((s, i) => (i === 0 ? `"${s}"` : `AND "${s}"`))
+ .join(' ')
+ return `(${tmp})^${boost}`
+ } else {
+ return ''
+ }
+}
+
+const matchSomeWordsExactly = (str, boost = 2) => {
+ if (str.includes(' ')) {
+ return str
+ .split(' ')
+ .map(s => `"${s}"^${boost}`)
+ .join(' ')
+ } else {
+ return ''
+ }
+}
favor guard clauses... see 👆
.filter(s => s.length > 3) | ||
.map(s => s + '*') | ||
.join(' ') | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,61 @@
+export function queryString(str) {
+ const normalizedString = normalizeWhitespace(str)
+ const escapedString = escapeSpecialCharacters(normalizedString)
+ return `
+${matchWholeText(escapedString)}
+${matchEachWordExactly(escapedString)}
+${matchSomeWordsExactly(escapedString)}
+${matchBeginningOfWords(escapedString)}
+`
+}
+
+const matchWholeText = (str, boost = 8) => {
+ return `"${str}"^${boost}`
+}
+
+const matchEachWordExactly = (str, boost = 4) => {
+ if (str.includes(' ')) {
+ const tmp = str
+ .split(' ')
+ .map((s, i) => (i === 0 ? `"${s}"` : `AND "${s}"`))
+ .join(' ')
+ return `(${tmp})^${boost}`
+ } else {
+ return ''
+ }
+}
+
+const matchSomeWordsExactly = (str, boost = 2) => {
+ if (str.includes(' ')) {
+ return str
+ .split(' ')
+ .map(s => `"${s}"^${boost}`)
+ .join(' ')
+ } else {
+ return ''
+ }
+}
+
+const matchBeginningOfWords = str => {
+ return normalizeWhitespace(
+ str
+ .split(' ')
+ .map(s => {
+ if (s.length > 3) {
+ // at least 4 letters. So AND, OR and NOT are never used unquoted
+ return s + '*'
+ } else {
+ return ''
+ }
+ })
+ .join(' '),
+ )
+}
favor guard clauses... see 👆
describe('query contains title of post', () => { | ||
it('finds the post', async () => { | ||
variables = { query: 'beitrag' } | ||
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({ | |
{ author: user }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ | ||
id: 'g-post', | ||
title: 'Zusammengesetzte Wörter', | ||
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`, | |
{ author: user }, |
{ | ||
id: 'c-post', | ||
title: 'Die binomischen Formeln', | ||
content: `1. binomische Formel: (a + b)² = a² + 2ab + b² |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
content: `1. binomische Formel: (a + b)² = a² + 2ab + b² | |
{ author: user }, |
{ | ||
id: 'd-post', | ||
title: 'Der Panther', | ||
content: `Sein Blick ist vom Vorübergehn der Stäbe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
content: `Sein Blick ist vom Vorübergehn der Stäbe | |
{ author: user }, |
|
||
describe('a post which content contains the title of the first post', () => { | ||
describe('query contains the title of the first post', () => { | ||
it('finds both posts', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 16, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
it('finds both posts', async () => { | |
{ author: user }, |
describe('resolvers/searches', () => { | ||
let variables | ||
|
||
describe('given one user', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
why are there so many nested describe blocks? typically, I would see a nested describe block if they set up for those set of tests differs in some way from the others. it seems to me in this file that many of them are for the description only, is that right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by Mogge
Mar 17, 2020
Yes. This is the way @roschaefer wanted it. At least this is what I understood that he wanted
data: { | ||
findResources: [ | ||
{ | ||
id: 'a-user', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
here for example...
'post', | ||
{ | ||
id: 'b-post', | ||
title: 'Aufruf', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
this is a good use of a describe block, since the set up is different. Although, it's not immediately clear to me why these posts could be created in a up the stream describe block and then tested in it
blocks further down...
maybe you wanted to have the build
closer to the test to make it easier to see the specifics of each post?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by Mogge
Mar 17, 2020
I need async calls to the factory. describe cannot be used async. This would leed to a beforeAll call before each new test and therefore a even deeper nesting of describe blocks. So I decided to write all the data to the DB firsrt, and then explain each test case later.
data: { | ||
findResources: expect.arrayContaining([ | ||
{ | ||
__typename: 'Post', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
+ ),
+ ])
+ })
+
+ describe('a post which content contains the title of the first post', () => {
+ describe('query contains the title of the first post', () => {
same as 👆
}, | ||
}) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
+ ),
+ ])
+ })
+
+ describe('a post which content contains the title of the first post', () => {
+ describe('query contains the title of the first post', () => {
+ it('finds both posts', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: expect.arrayContaining([
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ {
+ __typename: 'Post',
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ ]),
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a hyphen between two words and German quotation marks', () => {
+ describe('hyphens in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: 'tee-ei' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('German quotation marks in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: '„teeei“' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+ })
I'm confused by these two test cases... is there some docs you can link to that explain why this was an issue in the past?
I went to the link you provided https://lucene.apache.org/core/8_3_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Escaping_Special_Characters , but I'm not sure where the German quotation marks fit into the equation.
Also looking at the tests, it's not clear. The first test searches for tee-ei
, which the content does contain, so I would expect it to appear in the list, but maybe it wasn't because of the German quotations, somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by Mogge
Mar 17, 2020
The quotation marks are a testcase for unicode chars. I will put that in the description.
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({ | ||
data: { | ||
findResources: [ | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
+ ),
+ ])
+ })
+
+ describe('a post which content contains the title of the first post', () => {
+ describe('query contains the title of the first post', () => {
+ it('finds both posts', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: expect.arrayContaining([
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ {
+ __typename: 'Post',
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ ]),
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a hyphen between two words and German quotation marks', () => {
+ describe('hyphens in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: 'tee-ei' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('German quotation marks in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: '„teeei“' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a simple mathematical exprssion and linebreaks', () => {
{ | |
describe('a post that contains a simple mathematical expression and line breaks', () => { |
data: { | ||
findResources: [ | ||
{ | ||
__typename: 'Post', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
+ ),
+ ])
+ })
+
+ describe('a post which content contains the title of the first post', () => {
+ describe('query contains the title of the first post', () => {
+ it('finds both posts', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: expect.arrayContaining([
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ {
+ __typename: 'Post',
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ ]),
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a hyphen between two words and German quotation marks', () => {
+ describe('hyphens in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: 'tee-ei' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('German quotation marks in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: '„teeei“' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a simple mathematical exprssion and linebreaks', () => {
+ describe('query a part of the mathematical expression', () => {
this is cool, and seeing the docs, I can see how this is possible. I wonder if this is an actual use case, but I guess it doesn't hurt to have a test case for it?
await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({ | ||
data: { | ||
findResources: [ | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,452 @@
+import Factory, { cleanDatabase } from '../../db/factories'
+import { gql } from '../../helpers/jest'
+import { getNeode, getDriver } from '../../db/neo4j'
+import createServer from '../../server'
+import { createTestClient } from 'apollo-server-testing'
+
+let query, authenticatedUser
+
+const driver = getDriver()
+const neode = getNeode()
+
+beforeAll(async () => {
+ await cleanDatabase()
+ const { server } = createServer({
+ context: () => {
+ return {
+ driver,
+ neode,
+ user: authenticatedUser,
+ }
+ },
+ })
+ query = createTestClient(server).query
+})
+
+afterAll(async () => {
+ await cleanDatabase()
+})
+
+const searchQuery = gql`
+ query($query: String!) {
+ findResources(query: $query, limit: 5) {
+ __typename
+ ... on Post {
+ id
+ title
+ content
+ }
+ ... on User {
+ id
+ slug
+ name
+ }
+ }
+ }
+`
+let user
+
+describe('resolvers', () => {
+ describe('searches', () => {
+ let variables
+
+ describe('given one user', () => {
+ beforeAll(async () => {
+ user = await Factory.build('user', {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ })
+ authenticatedUser = await user.toJson()
+ })
+
+ const factoryOptions = {
+ authorId: 'a-user',
+ }
+
+ describe('query contains first name of user', () => {
+ it('finds the user', async () => {
+ variables = { query: 'John' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ id: 'a-user',
+ name: 'John Doe',
+ slug: 'john-doe',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('adding one post', () => {
+ beforeAll(async () => {
+ await Factory.build(
+ 'post',
+ {
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ factoryOptions,
+ )
+ })
+
+ describe('query contains title of post', () => {
+ it('finds the post', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('casing', () => {
+ it('does not matter', async () => {
+ variables = { query: 'BEITRAG' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query consists of words not present in the corpus', () => {
+ it('returns empty search results', async () => {
+ await expect(
+ query({ query: searchQuery, variables: { query: 'Unfug' } }),
+ ).resolves.toMatchObject({ data: { findResources: [] } })
+ })
+ })
+
+ describe('testing different post content', () => {
+ beforeAll(async () => {
+ return Promise.all([
+ Factory.build(
+ 'post',
+ {
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²
+2. binomische Formel: (a - b)² = a² - 2ab + b²
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ factoryOptions,
+ ),
+ Factory.build(
+ 'post',
+ {
+ id: 'd-post',
+ title: 'Der Panther',
+ content: `Sein Blick ist vom Vorübergehn der Stäbe
+so müd geworden, daß er nichts mehr hält.
+Ihm ist, als ob es tausend Stäbe gäbe
+und hinter tausend Stäben keine Welt.`,
+ },
+ factoryOptions,
+ ),
+ ])
+ })
+
+ describe('a post which content contains the title of the first post', () => {
+ describe('query contains the title of the first post', () => {
+ it('finds both posts', async () => {
+ variables = { query: 'beitrag' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: expect.arrayContaining([
+ {
+ __typename: 'Post',
+ id: 'a-post',
+ title: 'Beitrag',
+ content: 'Ein erster Beitrag',
+ },
+ {
+ __typename: 'Post',
+ id: 'b-post',
+ title: 'Aufruf',
+ content: 'Jeder sollte seinen Beitrag leisten.',
+ },
+ ]),
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a hyphen between two words and German quotation marks', () => {
+ describe('hyphens in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: 'tee-ei' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('German quotation marks in query', () => {
+ it('will be treated as ordinary characters', async () => {
+ variables = { query: '„teeei“' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'g-post',
+ title: 'Zusammengesetzte Wörter',
+ content: `Ein Bindestrich kann zwischen zwei Substantiven auch dann gesetzt werden, wenn drei gleichlautende Buchstaben aufeinandertreffen. Das ist etwa bei einem „Teeei“ der Fall, das so korrekt geschrieben ist. Möglich ist hier auch die Schreibweise mit Bindestrich: Tee-Ei.`,
+ },
+ ],
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a simple mathematical exprssion and linebreaks', () => {
+ describe('query a part of the mathematical expression', () => {
+ it('finds that post', async () => {
+ variables = { query: '(a - b)²' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
+2. binomische Formel: (a - b)² = a² - 2ab + b²<br>
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query the same part of the mathematical expression without spaces', () => {
+ it('finds that post', async () => {
+ variables = { query: '(a-b)²' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
+2. binomische Formel: (a - b)² = a² - 2ab + b²<br>
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ ],
+ },
+ })
+ })
+ })
+
+ describe('query the mathematical expression over linebreak', () => {
+ it('finds that post', async () => {
+ variables = { query: '+ b² 2.' }
+ await expect(query({ query: searchQuery, variables })).resolves.toMatchObject({
+ data: {
+ findResources: [
+ {
+ __typename: 'Post',
+ id: 'c-post',
+ title: 'Die binomischen Formeln',
+ content: `1. binomische Formel: (a + b)² = a² + 2ab + b²<br>
+2. binomische Formel: (a - b)² = a² - 2ab + b²<br>
+3. binomische Formel: (a + b)(a - b) = a² - b²`,
+ },
+ ],
+ },
+ })
+ })
+ })
+ })
+
+ describe('a post that contains a poem', () => {
I don't understand where the poem
part makes a search different 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by Mogge
Mar 17, 2020
It is just for the beauty of the poem. Be happy, that I did not include the second and third verse.
} | ||
|
||
const matchWholeText = (str, boost = 8) => { | ||
return `"${str}"^${boost}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,53 @@
+export function queryString(str) {
+ const normalizedString = normalizeWhitespace(str)
+ const escapedString = escapeSpecialCharacters(normalizedString)
+ return `
+${matchWholeText(escapedString)}
+${matchEachWordExactly(escapedString)}
+${matchSomeWordsExactly(escapedString)}
+${matchBeginningOfWords(escapedString)}
+`
+}
+
+const matchWholeText = (str, boost = 8) => {
+ return `"${str}"^${boost}`
thank you for giving the docs so that your reviewers can understand how the boost works!
I didn't really understand how you came to the defaults. Maybe you could explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by Mogge
Mar 17, 2020
I thought: 1, 2, 4, 8
Next would be 16
Matching the whole query exactly -> 8
Matching all words exactly -> 4
Matching at least one word exactly -> 2
Match the beginning of some words -> 1
}) | ||
|
||
describe('whitespace', () => { | ||
it('normalizes correctly', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,43 @@
+import { queryString, escapeSpecialCharacters, normalizeWhitespace } from './queryString'
+
+describe('queryString', () => {
+ describe('special characters', () => {
+ it('does escaping correctly', () => {
+ expect(escapeSpecialCharacters('+ - && || ! ( ) { } [ ] ^ " ~ * ? : \\ / ')).toEqual(
+ '\\+ \\- \\&\\& \\|\\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\" \\~ \\* \\? \\: \\\\ \\/ ',
+ )
+ })
+ })
+
+ describe('whitespace', () => {
+ it('is normalized correctly', () => {
it('normalizes correctly', () => { | |
it('normalizes correctly', () => { |
it('boosts score by factor 2', () => { | ||
expect(queryString('a couple of words')).toContain('"a"^2 "couple"^2 "of"^2 "words"^2') | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Authored by mattwr18
Mar 17, 2020
Outdated (history rewrite) - original diff
@@ -0,0 +1,43 @@
+import { queryString, escapeSpecialCharacters, normalizeWhitespace } from './queryString'
+
+describe('queryString', () => {
+ describe('special characters', () => {
+ it('does escaping correctly', () => {
+ expect(escapeSpecialCharacters('+ - && || ! ( ) { } [ ] ^ " ~ * ? : \\ / ')).toEqual(
+ '\\+ \\- \\&\\& \\|\\| \\! \\( \\) \\{ \\} \\[ \\] \\^ \\" \\~ \\* \\? \\: \\\\ \\/ ',
+ )
+ })
+ })
+
+ describe('whitespace', () => {
+ it('is normalized correctly', () => {
+ expect(normalizeWhitespace(' a \t \n b \n ')).toEqual('a b')
+ })
+ })
+
+ describe('exact match', () => {
+ it('boosts score by factor 8', () => {
+ expect(queryString('a couple of words')).toContain('"a couple of words"^8')
+ })
+ })
+
+ describe('match all words exactly', () => {
+ it('boosts score by factor 4', () => {
+ expect(queryString('a couple of words')).toContain(
+ '("a" AND "couple" AND "of" AND "words")^4',
+ )
+ })
+ })
+
+ describe('match at least one word exactly', () => {
+ it('boosts score by factor 2', () => {
+ expect(queryString('a couple of words')).toContain('"a"^2 "couple"^2 "of"^2 "words"^2')
+ })
+ })
I guess these tests give a hint of how the boosting works... I would infer that 8 is the maximum and you can evenly distribute that amongst words?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍰 Pullrequest
This. Adding specs for searches in Backand and improve the search queries