Skip to content
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

Changes related to the next Meilisearch release (v0.27.0) #280

Merged
merged 7 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -719,8 +719,21 @@ search_parameter_guide_retrieve_1: |-
search_parameter_guide_crop_1: |-
let searchParameters = SearchParameters(
query: "shifu",
attributesToCrop: "overview",
cropLength: 10)
attributesToCrop: ["overview"],
cropLength: 5)
client.index("movies").search(searchParameters) { (result: Result<SearchResult<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
print(searchResult)
case .failure(let error):
print(error)
}
}
search_parameter_guide_crop_marker_1: |-
let searchParameters = SearchParameters(
query: "shifu",
attributesToCrop: ["overview"],
cropMarker: "[…]")
client.index("movies").search(searchParameters) { (result: Result<SearchResult<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
Expand All @@ -741,6 +754,20 @@ search_parameter_guide_highlight_1: |-
print(error)
}
}
search_parameter_guide_highlight_tag_1: |-
let searchParameters = SearchParameters(
query: "winter feast",
attributesToHighlight: ["overview"],
highlightPreTag: "<span class=\"highlight\">",
highlightPostTag: "</span>")
client.index("movies").search(searchParameters) { (result: Result<SearchResult<Movie>, Swift.Error>) in
switch result {
case .success(let searchResult):
print(searchResult)
case .failure(let error):
print(error)
}
}
search_parameter_guide_matches_1: |-
let searchParameters = SearchParameters(
query: "winter feast",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Since Meilisearch is typo-tolerant, the movie `philadelphia` is a valid search r

## 🤖 Compatibility with Meilisearch

This package only guarantees the compatibility with the [version v0.26.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.26.0).
This package only guarantees the compatibility with the [version v0.27.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.27.0).

## 💡 Learn More

Expand Down
2 changes: 1 addition & 1 deletion Scripts/run-test.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh
docker run -d --rm -p 7700:7700 getmeili/meilisearch:latest ./meilisearch --no-analytics --master-key=masterKey
docker run -d --rm -p 7700:7700 getmeili/meilisearch:latest meilisearch --no-analytics --master-key=masterKey
swift test
18 changes: 18 additions & 0 deletions Sources/MeiliSearch/Model/SearchParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,18 @@ public struct SearchParameters: Codable, Equatable {
/// Limit length at which to crop specified attributes.
public let cropLength: Int?

/// Marker in front and behind a cropped value.
public let cropMarker: String?

/// Which attributes to highlight.
public let attributesToHighlight: [String]?

/// Tag in front of highlighted term(s).
public let highlightPreTag: String?

/// Tag at the end of highlighted term(s).
public let highlightPostTag: String?

/// Filter on attributes values.
public let filter: String?

Expand All @@ -50,7 +59,10 @@ public struct SearchParameters: Codable, Equatable {
attributesToRetrieve: [String]? = nil,
attributesToCrop: [String]? = nil,
cropLength: Int? = nil,
cropMarker: String? = nil,
attributesToHighlight: [String]? = nil,
highlightPreTag: String? = nil,
highlightPostTag: String? = nil,
filter: String? = nil,
sort: [String]? = nil,
facetsDistribution: [String]? = nil,
Expand All @@ -61,7 +73,10 @@ public struct SearchParameters: Codable, Equatable {
self.attributesToRetrieve = attributesToRetrieve
self.attributesToCrop = attributesToCrop
self.cropLength = cropLength
self.cropMarker = cropMarker
self.attributesToHighlight = attributesToHighlight
self.highlightPreTag = highlightPreTag
self.highlightPostTag = highlightPostTag
self.filter = filter
self.sort = sort
self.facetsDistribution = facetsDistribution
Expand Down Expand Up @@ -89,7 +104,10 @@ public struct SearchParameters: Codable, Equatable {
case attributesToRetrieve
case attributesToCrop
case cropLength
case cropMarker
case attributesToHighlight
case highlightPreTag
case highlightPostTag
case filter
case sort
case facetsDistribution
Expand Down
4 changes: 2 additions & 2 deletions Tests/MeiliSearchIntegrationTests/DocumentsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ class DocumentsTests: XCTestCase {
case .success(let returnedMovies):
let returnedMovie = returnedMovies[0]
XCTAssertEqual(returnedMovies.count, 1)
XCTAssertEqual(returnedMovie.id, 123)
XCTAssertEqual(returnedMovie.title, "Pride and Prejudice")
XCTAssertEqual(returnedMovie.id, 456)
XCTAssertEqual(returnedMovie.title, "Le Petit Prince")
XCTAssertEqual(returnedMovie.comment, nil)
expectation.fulfill()
case .failure:
Expand Down
119 changes: 110 additions & 9 deletions Tests/MeiliSearchIntegrationTests/SearchTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
import XCTest
import Foundation

// swiftlint:disable force_unwrapping
// swiftlint:disable force_try
private let books: [Book] = [
Book(id: 123, title: "Pride and Prejudice", comment: "A great book", genres: ["Classic Regency nove"]),
Book(id: 456, title: "Le Petit Prince", comment: "A french book", genres: ["Novel"]),
Expand All @@ -15,20 +13,31 @@ private let books: [Book] = [
Book(id: 1844, title: "A Moreninha", comment: "A Book from Joaquim Manuel de Macedo", genres: ["Novel"])
]

// swiftlint:disable force_unwrapping
// swiftlint:disable force_try
private let nestedBooks: [NestedBook] = [
NestedBook(id: 123, title: "Pride and Prejudice", info: InfoNested(comment: "A great book", reviewNb: 100), genres: ["Classic Regency nove"]),
NestedBook(id: 456, title: "Le Petit Prince", info: InfoNested(comment: "A french book", reviewNb: 100), genres: ["Novel"]),
NestedBook(id: 2, title: "Le Rouge et le Noir", info: InfoNested(comment: "Another french book", reviewNb: 100), genres: ["Bildungsroman"])
]

class SearchTests: XCTestCase {
private var client: MeiliSearch!
private var index: Indexes!
private var nestedIndex: Indexes!
private var session: URLSessionProtocol!
private let uid: String = "books_test"
private let nested_uid: String = "nested_books_test"

// MARK: Setup

override func setUp() {
super.setUp()

session = URLSession(configuration: .ephemeral)
client = try! MeiliSearch(host: "http://localhost:7700", apiKey: "masterKey", session: session)
session = URLSession(configuration: .ephemeral)
client = try! MeiliSearch(host: "http://localhost:7700", apiKey: "masterKey", session: session)
index = self.client.index(self.uid)
nestedIndex = self.client.index(self.nested_uid)

let addDocExpectation = XCTestExpectation(description: "Add documents")

Expand All @@ -43,10 +52,21 @@ class SearchTests: XCTestCase {
}
}
self.wait(for: [addDocExpectation], timeout: TESTS_TIME_OUT)
let addNestedDocExpectation = XCTestExpectation(description: "Add documents")
addDocuments(client: self.client, uid: self.nested_uid, dataset: nestedBooks, primaryKey: nil) { result in
switch result {
case .success:
addNestedDocExpectation.fulfill()
case .failure(let error):
dump(error)
XCTFail("Failed to create index")
addNestedDocExpectation.fulfill()
}
}
self.wait(for: [addNestedDocExpectation], timeout: TESTS_TIME_OUT)
}

// MARK: Basic search

func testBasicSearch() {
let expectation = XCTestExpectation(description: "Search for Books with query")

Expand Down Expand Up @@ -76,6 +96,32 @@ class SearchTests: XCTestCase {
self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

// MARK: Nested search
func testNestedSearch() {
let expectation = XCTestExpectation(description: "Search in Nested Books")

typealias MeiliResult = Result<SearchResult<NestedBook>, Swift.Error>
let query = "A french book"

self.nestedIndex.search(SearchParameters(query: query)) { (result: MeiliResult) in
switch result {
case .success(let response):
if response.hits.count > 0 {
XCTAssertEqual("A french book", response.hits[0].info.comment)
} else {
XCTFail("Failed to find hits in the response")
}
expectation.fulfill()
case .failure(let error):
dump(error)
XCTFail("Failed to search in nested books")
expectation.fulfill()
}
}

self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

func testBasicSearchWithNoQuery() {
let expectation = XCTestExpectation(description: "Search for Books without query")

Expand All @@ -87,7 +133,7 @@ class SearchTests: XCTestCase {
XCTAssertEqual("", response.query)
XCTAssertEqual(20, response.limit)
XCTAssertEqual(books.count, response.hits.count)
XCTAssertEqual("Alice In Wonderland", response.hits[0].title)
XCTAssertEqual("Pride and Prejudice", response.hits[0].title)
expectation.fulfill()
case .failure(let error):
dump(error)
Expand Down Expand Up @@ -326,7 +372,7 @@ class SearchTests: XCTestCase {
XCTAssertEqual(documents.limit, limit)
XCTAssertEqual(documents.hits.count, 1)
let book: Book = documents.hits[0]
XCTAssertEqual("Manuel de Macedo", book.formatted!.comment!)
XCTAssertEqual("…Joaquim Manuel de Macedo", book.formatted!.comment!)
expectation.fulfill()
case .failure(let error):
print(error)
Expand All @@ -338,6 +384,34 @@ class SearchTests: XCTestCase {
self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

// MARK: Crop Marker

func testSearchCropMarker() {
let expectation = XCTestExpectation(description: "Search for Books with a custom crop marker")

typealias MeiliResult = Result<SearchResult<Book>, Swift.Error>
let query = "Manuel"
let attributesToCrop = ["comment"]
let cropLength = 2
let cropMarker = "(ꈍᴗꈍ)"
let searchParameters = SearchParameters(query: query, attributesToCrop: attributesToCrop, cropLength: cropLength, cropMarker: cropMarker)

self.index.search(searchParameters) { (result: MeiliResult) in
switch result {
case .success(let documents):
let book: Book = documents.hits[0]
XCTAssertEqual("(ꈍᴗꈍ)Joaquim Manuel(ꈍᴗꈍ)", book.formatted!.comment!)
expectation.fulfill()
case .failure(let error):
print(error)
XCTFail("Failed to search with a custom crop marker")
expectation.fulfill()
}
}

self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

// MARK: Crop length

func testSearchCropLength() {
Expand All @@ -357,7 +431,7 @@ class SearchTests: XCTestCase {
XCTAssertEqual(documents.hits.count, 2)

let moreninhaBook: Book = documents.hits.first(where: { book in book.id == 1844 })!
XCTAssertEqual("A Book from", moreninhaBook.formatted!.comment!)
XCTAssertEqual("A Book from Joaquim Manuel…", moreninhaBook.formatted!.comment!)
expectation.fulfill()
case .failure(let error):
dump(error)
Expand Down Expand Up @@ -438,6 +512,34 @@ class SearchTests: XCTestCase {
self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

// MARK: Attributes to highlight

func testSearchPrePostHighlightTags() {
let expectation = XCTestExpectation(description: "Search for Books using custom pre and post highlight tags")

typealias MeiliResult = Result<SearchResult<Book>, Swift.Error>
let query = "Joaquim Manuel de Macedo"
let attributesToHighlight = ["comment"]
let highlightPreTag = "(⊃。•́‿•̀。)⊃ "
let highlightPostTag = " ⊂(´• ω •`⊂)"
let parameters = SearchParameters(query: query, attributesToHighlight: attributesToHighlight, highlightPreTag: highlightPreTag, highlightPostTag: highlightPostTag)

self.index.search(parameters) { (result: MeiliResult) in
switch result {
case .success(let documents):
let book = documents.hits[0]
XCTAssertTrue(book.formatted!.comment!.contains("(⊃。•́‿•̀。)⊃ Joaquim ⊂(´• ω •`⊂) (⊃。•́‿•̀。)⊃ Manuel ⊂(´• ω •`⊂) (⊃。•́‿•̀。)⊃ de ⊂(´• ω •`⊂) (⊃。•́‿•̀。)⊃ Macedo ⊂(´• ω •`⊂)"))
expectation.fulfill()
case .failure(let error):
dump(error)
XCTFail("Failed to search using custom pre and post highlight tags")
expectation.fulfill()
}
}

self.wait(for: [expectation], timeout: TESTS_TIME_OUT)
}

// MARK: Attributes to retrieve

func testSearchAttributesToRetrieve() {
Expand Down Expand Up @@ -757,7 +859,6 @@ class SearchTests: XCTestCase {
XCTAssertEqual(documents.query, query)
XCTAssertEqual(documents.limit, limit)
XCTAssertEqual(documents.hits.count, 0)

let facetsDistribution = documents.facetsDistribution!
XCTAssertEqual(["genres": [:]], facetsDistribution)

Expand Down
40 changes: 40 additions & 0 deletions Tests/MeiliSearchIntegrationTests/Support/NestedBook.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
public struct NestedBook: Codable, Equatable {
let id: Int
let title: String
let info: InfoNested
let genres: [String]?
let formatted: FormattedNestedBook?

enum CodingKeys: String, CodingKey {
case id
case title
case info
case genres
case formatted = "_formatted"
}

init(id: Int, title: String, info: InfoNested, genres: [String] = [], formatted: FormattedNestedBook? = nil) {
self.id = id
self.title = title
self.info = info
self.genres = genres
self.formatted = formatted
}
}

public struct InfoNested: Codable, Equatable {
let comment: String
let reviewNb: Int
}

public struct FormattedNestedBook: Codable, Equatable {
let id: String
let title: String
let info: InfoNested

init(id: String, title: String, info: InfoNested) {
self.id = id
self.title = title
self.info = info
}
}