-
Notifications
You must be signed in to change notification settings - Fork 0
18 sphinx #16
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
base: master
Are you sure you want to change the base?
Conversation
…inclusion to Capybara JS execution
| second_answer = create(:answer, question: question, user: user) | ||
| visit question_path(question) | ||
| within("#answer-#{second_answer.id}") { click_on 'Star' } | ||
| sleep 0.1 |
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.
Я не совсем понял, из-за чего точно, но таймаут капибары перестал успевать примерно на 100мс. Видимо, как раз в это время Сфинкс перестраивает дельта-индексы. Считаю, что костыль, но ничего умнее придумать не смог. И почему-то проявилось только в этом тесте.
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 элемента? Это уже не пользовательский сценарий, а кодерский. Надо проверять контент, используя have_content, который автоматически подождет до появления контента и избавить от костыля в виде sleep.
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.
Да, правда, можно было проще проверить. И, действительно, после переделки на have_content стало дожидаться. Не задумался, видимо, когда писал, что ждет именно он.
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.
Вот рано я обрадовался. Вызов have_content вообще не помогает, ну, точно Сфинкс перестраивает дельты и блокирует объект в транзакции, его надо еще ждать.
Получилось так: заметил, что CI показывает битые тесты. Посмотрел. API стало работать иначе -- порядок Answer-ов в ответе API поменялся на обратный. Так как явно он нигде не задавался, подумал, и поставил уж для большего педантизма default_scope во всех моделях, которые что-то отображают. Спеки API прошли. А этот тест снова стал заваливаться.
В итоге вернул sleep 0.1, так как единственный вариант получается -- делать флаг ожидания индексации Сфинкса или завершения транзакции, и все равно делать в спеке вызов ожидания. Так как готовность Сфинкса и так проверяется через 100мс, то пусть уж лучше тут будет sleep, медленнее от него точно не станет по сравнению с предложенным методом.
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.
have_content сам за тебя ждет, столько, сколько нужно. Ты как-то неправильно его используешь, значит. Ты, вероятно, оставил что-то вроде expect(page.first('div')).to have_content(...)?
Нужно так:
# сужаем область, в которой будет производится поиск элементов
within "#answers div:first-child" do # а лучше использовать имя класса "#answers .answer:first-child"
expect(page).to have_content(...)
endКогда ты делаешь page.first(...), то возвращается тот элемент, который был первым в момент вызова, и тут уже не помогает have_content.
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.
Вообще, я это понял, исключил даже within и для проверки сделал вот так:
# sleep 0.1
expect(page).to have_content second_answer.bodyИ без комментарием тест работает, с комментарием -- валится. Но с #answers div:first-child мне вариант больше нравится, переделаю на него. C #answers .answer хоть и лаконичнее, но хуже читается, менее понятно, что выделяется.
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.
Попробовал, не получается ни с #answers div:first-child, ни c #answers .answer (у меня в текущей ветке нет класса answer, но для эксперимента я его добавил). Всегда валится на Capybara::Ambiguous, например с: Ambiguous match, found 2 elements matching css "#answers .answer". Пробую из JS-консоли: один элемент. Странно.
В итоге sleep оставил, и have_content перед ним тоже, хотя, он не спасает совершенно. Думаю, варианты с селекторами, даже если он их смэтчит правильно, не пройдут тоже.
В итоге, это лучшее, что работает.
| end | ||
| end | ||
|
|
||
| shared_examples :sphinx_search_controller_with_params do |entity, attribute, search_type, validity = true| |
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.
Возможно, здесь с shared example-ом я немного "перехимичил", зато получилось весьма лаконичная сама спека
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.
"Перехимичил", разве что, с расположением примеров.
В данном случае лучше сами shared_examples объявить в файле-спеке самого контроллера. Сейчас спека контроллера – сплошная магия, ее нельзя взять и прочитать, как спецификацию.
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.
Самое смешное, что я так их и писал, потом выносил в отдельный файл. Именно, чтобы пока пишешь, не запутаться )). Понял, вернул в спеку.
app/models/search_service.rb
Outdated
| @@ -0,0 +1,28 @@ | |||
| class SearchService | |||
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.
Ну уверен, что правильнее: помещать сервисный объект в модели, или делать еще одну папку в /app и прописывать её в пути загрузки приложения? Пока объект всего один, положил в модели, чтобы не разветвлять дерево проекта.
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.
Делать еще одну папку, app/services.
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.
Ок, сделал, переместил.
app/models/search_service.rb
Outdated
| @@ -0,0 +1,28 @@ | |||
| class SearchService | |||
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.
Делать еще одну папку, app/services.
app/models/search_service.rb
Outdated
| private | ||
|
|
||
| def klass(type) | ||
| case type |
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.
Не очень мне нравится такой подход, у нас все-таки Ruby, можно применить что-нибудь из мета-программирования.
Например, получать с клиента не однобуквенные типы, а полные ("question", "answer"), и делать classify.constantize, предварительно фильтруя, конечно.
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.
Да, это я понимаю, даже хотел так и сделать сначала, но тут немного меня смущает, то, что "снаружи" будет видно, какой класс у нас внутри приложения. Пока в нашем примере, они очевидны, то это все же не очень страшно, но если они будут более заковыристыми, я бы не рискнул их пользователю показывать в GET-запросах. Ок, это переделаю, даже спеки попроще станут.
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.
Сделал, спеки лаконичнее сильно не стали, но зато вынес в константу сервис-объекта допустимые значения.
| second_answer = create(:answer, question: question, user: user) | ||
| visit question_path(question) | ||
| within("#answer-#{second_answer.id}") { click_on 'Star' } | ||
| sleep 0.1 |
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 элемента? Это уже не пользовательский сценарий, а кодерский. Надо проверять контент, используя have_content, который автоматически подождет до появления контента и избавить от костыля в виде sleep.
| end | ||
| end | ||
|
|
||
| shared_examples :sphinx_search_controller_with_params do |entity, attribute, search_type, validity = true| |
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.
"Перехимичил", разве что, с расположением примеров.
В данном случае лучше сами shared_examples объявить в файле-спеке самого контроллера. Сейчас спека контроллера – сплошная магия, ее нельзя взять и прочитать, как спецификацию.
|
Несмотря на проблему с тестом, в котором приходится спать 100мс, думаю, можно двигаться дальше, PR пока оставлю открытым, но в мастер зарибейжу. Если что надо будет поправить -- поправлю в следующих ветках или между ними. |
No description provided.