diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a1c2eefb2..b63618fdf 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,14 +1,14 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2016-09-05 09:54:21 +0700 using RuboCop version 0.42.0. +# on 2016-09-06 12:08:00 +0700 using RuboCop version 0.42.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 42 +# Offense count: 41 Metrics/AbcSize: - Max: 49 + Max: 47 # Offense count: 4 # Configuration parameters: CountComments. @@ -19,11 +19,11 @@ Metrics/ClassLength: Metrics/CyclomaticComplexity: Max: 13 -# Offense count: 1435 +# Offense count: 1455 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes. # URISchemes: http, https Metrics/LineLength: - Max: 288 + Max: 290 # Offense count: 36 # Configuration parameters: CountComments. @@ -45,78 +45,12 @@ Performance/EndWith: Exclude: - 'lib/chewy/type/wrapper.rb' -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: outdent, indent -Style/AccessModifierIndentation: - Exclude: - - 'lib/chewy/journal.rb' - - 'lib/chewy/minitest/search_index_receiver.rb' - - 'lib/chewy/type/wrapper.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: prefer_alias, prefer_alias_method -Style/Alias: - Exclude: - - 'lib/chewy/query.rb' - - 'lib/chewy/rspec/update_index.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: with_first_parameter, with_fixed_indentation -Style/AlignParameters: - Exclude: - - 'spec/chewy/query_spec.rb' - # Offense count: 2 Style/AsciiComments: Exclude: - 'lib/chewy/type/mapping.rb' - 'spec/chewy_spec.rb' -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: percent_q, bare_percent -Style/BarePercentLiterals: - Exclude: - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 365 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. -# SupportedStyles: line_count_based, semantic, braces_for_chaining -# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object -# FunctionalMethods: let, let!, subject, watch -# IgnoredMethods: lambda, proc, it -Style/BlockDelimiters: - Enabled: false - -# Offense count: 292 -# Cop supports --auto-correct. -Style/BlockEndNewline: - Enabled: false - -# Offense count: 248 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: braces, no_braces, context_dependent -Style/BracesAroundHashParameters: - Enabled: false - -# Offense count: 6 -# Cop supports --auto-correct. -Style/CharacterLiteral: - Exclude: - - 'lib/chewy.rb' - - 'lib/chewy/index.rb' - - 'lib/chewy/query/nodes/field.rb' - - 'lib/tasks/chewy.rake' - # Offense count: 1 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: nested, compact @@ -128,85 +62,6 @@ Style/ClassAndModuleChildren: Style/Documentation: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: AllowAdjacentOneLineDefs. -Style/EmptyLineBetweenDefs: - Exclude: - - 'lib/chewy/strategy/base.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/EmptyLines: - Exclude: - - 'spec/chewy/fields/base_spec.rb' - - 'spec/chewy/query/nodes/has_child_spec.rb' - - 'spec/chewy/query/nodes/has_parent_spec.rb' - - 'spec/chewy/query/pagination/will_paginage_spec.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/EmptyLinesAroundAccessModifier: - Exclude: - - 'lib/chewy/minitest/search_index_receiver.rb' - - 'lib/chewy/query/nodes/has_child.rb' - - 'lib/chewy/query/nodes/has_parent.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: empty_lines, no_empty_lines -Style/EmptyLinesAroundBlockBody: - Exclude: - - 'lib/chewy/rspec/update_index.rb' - - 'spec/chewy/minitest/search_index_receiver_spec.rb' - - 'spec/chewy/query/pagination_spec.rb' - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: empty_lines, no_empty_lines -Style/EmptyLinesAroundClassBody: - Exclude: - - 'lib/chewy/index/settings.rb' - - 'lib/chewy/minitest/search_index_receiver.rb' - - 'lib/chewy/rake_helper.rb' - - 'lib/chewy/type/adapter/active_record.rb' - - 'lib/chewy/type/adapter/mongoid.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: empty_lines, no_empty_lines -Style/EmptyLinesAroundModuleBody: - Exclude: - - 'lib/chewy.rb' - - 'lib/chewy/minitest/helpers.rb' - - 'lib/chewy/query/compose.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. -Style/ExtraSpacing: - Exclude: - - 'Guardfile' - - 'lib/chewy/railtie.rb' - - 'spec/chewy/index_spec.rb' - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/rspec/update_index_spec.rb' - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Style/FirstParameterIndentation: - Exclude: - - 'spec/chewy/fields/base_spec.rb' - - 'spec/chewy/type/import_spec.rb' - # Offense count: 2 # Configuration parameters: MinBodyLength. Style/GuardClause: @@ -214,87 +69,16 @@ Style/GuardClause: - 'lib/chewy/fields/root.rb' - 'lib/chewy/query/nodes/has_relation.rb' -# Offense count: 8 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols. -# SupportedStyles: ruby19, ruby19_no_mixed_keys, hash_rockets -Style/HashSyntax: - Exclude: - - 'lib/chewy/query/nodes/range.rb' - - 'spec/chewy/query/criteria_spec.rb' - # Offense count: 2 Style/IfInsideElse: Exclude: - 'lib/chewy/rspec/update_index.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: MaxLineLength. -Style/IfUnlessModifier: - Exclude: - - 'lib/chewy/minitest/helpers.rb' - # Offense count: 2 Style/IfUnlessModifierOfIfUnless: Exclude: - 'lib/chewy/type/witchcraft.rb' -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Style/IndentArray: - Exclude: - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/type/adapter/object_spec.rb' - -# Offense count: 85 -# Cop supports --auto-correct. -# Configuration parameters: SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Style/IndentHash: - EnforcedStyle: consistent - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: normal, rails -Style/IndentationConsistency: - Exclude: - - 'lib/chewy/minitest/helpers.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: Width. -Style/IndentationWidth: - Exclude: - - 'lib/chewy/query.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: line_count_dependent, lambda, literal -Style/Lambda: - Exclude: - - 'lib/chewy/minitest/helpers.rb' - - 'lib/chewy/rake_helper.rb' - - 'spec/chewy/type/witchcraft_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/LeadingCommentSpace: - Exclude: - - 'lib/chewy/query/pagination/will_paginate.rb' - - 'spec/chewy/query/pagination/will_paginage_spec.rb' - -# Offense count: 199 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline -Style/MethodDefParentheses: - Enabled: false - # Offense count: 3 Style/MethodMissing: Exclude: @@ -309,71 +93,12 @@ Style/MethodName: Exclude: - 'spec/chewy/query/filters_spec.rb' -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineArrayBraceLayout: - Exclude: - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/object_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - # Offense count: 3 Style/MultilineBlockChain: Exclude: - 'lib/chewy/type/import.rb' - 'lib/chewy/type/observe.rb' -# Offense count: 326 -# Cop supports --auto-correct. -Style/MultilineBlockLayout: - Enabled: false - -# Offense count: 17 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineHashBraceLayout: - Exclude: - - 'spec/chewy/fields/base_spec.rb' - - 'spec/chewy/query/criteria_spec.rb' - - 'spec/chewy/query/nodes/bool_spec.rb' - - 'spec/chewy/query_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineMethodCallBraceLayout: - Exclude: - - 'lib/chewy/search.rb' - -# Offense count: 18 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: aligned, indented, indented_relative_to_receiver -Style/MultilineMethodCallIndentation: - Exclude: - - 'spec/chewy/query/filters_spec.rb' - - 'spec/chewy/query/nodes/has_child_spec.rb' - - 'spec/chewy/query/nodes/has_parent_spec.rb' - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/rspec/update_index_spec.rb' - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/object_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: aligned, indented -Style/MultilineOperationIndentation: - Exclude: - - 'lib/chewy/rspec/update_index.rb' - # Offense count: 7 Style/MultilineTernaryOperator: Exclude: @@ -384,46 +109,20 @@ Style/MultilineTernaryOperator: - 'lib/chewy/type/adapter/orm.rb' - 'lib/chewy/type/observe.rb' -# Offense count: 10 -# Cop supports --auto-correct. -Style/MutableConstant: - Exclude: - - 'lib/chewy/query/criteria.rb' - - 'lib/chewy/query/nodes/bool.rb' - - 'lib/chewy/query/nodes/equal.rb' - - 'lib/chewy/query/nodes/range.rb' - - 'lib/chewy/query/nodes/regexp.rb' - - 'lib/chewy/type.rb' - - 'lib/chewy/type/import.rb' - - 'lib/chewy/version.rb' - - 'spec/support/mongoid.rb' - -# Offense count: 13 -# Cop supports --auto-correct. -Style/NestedParenthesizedCalls: - Exclude: - - 'spec/chewy/minitest/search_index_receiver_spec.rb' - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/object_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - - 'spec/chewy/type/import_spec.rb' - # Offense count: 2 Style/NestedTernaryOperator: Exclude: - 'lib/chewy/fields/base.rb' - 'lib/chewy/type/adapter/orm.rb' -# Offense count: 5 +# Offense count: 3 # Cop supports --auto-correct. Style/NilComparison: Exclude: - 'spec/chewy/query/filters_spec.rb' - - 'spec/chewy/query/nodes/exists_spec.rb' - 'spec/chewy/query/nodes/missing_spec.rb' -# Offense count: 2 +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: IncludeSemanticChanges. Style/NonNilCheck: @@ -431,46 +130,11 @@ Style/NonNilCheck: - 'spec/chewy/query/filters_spec.rb' - 'spec/chewy/query/nodes/exists_spec.rb' -# Offense count: 4 -# Cop supports --auto-correct. -Style/NumericLiterals: - MinDigits: 6 - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: predicate, comparison -Style/NumericPredicate: - Exclude: - - 'lib/chewy/fields/base.rb' - - 'lib/chewy/fields/root.rb' - - 'lib/chewy/runtime/version.rb' - - 'lib/chewy/type/observe.rb' - - 'lib/chewy/type/witchcraft.rb' - # Offense count: 8 Style/OpMethod: Exclude: - 'lib/chewy/query/nodes/field.rb' -# Offense count: 5 -# Cop supports --auto-correct. -Style/ParallelAssignment: - Exclude: - - 'lib/chewy/fields/base.rb' - - 'lib/chewy/query/nodes/bool.rb' - - 'lib/chewy/query/nodes/prefix.rb' - - 'lib/chewy/type/crutch.rb' - - 'lib/chewy/type/mapping.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: PreferredDelimiters. -Style/PercentLiteralDelimiters: - Exclude: - - 'lib/chewy/journal.rb' - - 'spec/chewy/type/witchcraft_spec.rb' - # Offense count: 2 # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. # NamePrefix: is_, has_, have_ @@ -480,228 +144,3 @@ Style/PredicateName: Exclude: - 'spec/**/*' - 'lib/chewy/query/filters.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/PreferredHashMethods: - Exclude: - - 'lib/chewy/fields/base.rb' - - 'lib/chewy/type/import.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/Proc: - Exclude: - - 'lib/chewy/type/observe.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: compact, exploded -Style/RaiseArgs: - Exclude: - - 'lib/chewy.rb' - - 'lib/chewy/query.rb' - - 'lib/chewy/strategy/base.rb' - - 'lib/chewy/type/import.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/RedundantSelf: - Exclude: - - 'lib/chewy/config.rb' - - 'lib/chewy/repository.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. -# SupportedStyles: slashes, percent_r, mixed -Style/RegexpLiteral: - Exclude: - - 'spec/chewy_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/RescueModifier: - Exclude: - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 35 -# Cop supports --auto-correct. -# Configuration parameters: AllowAsExpressionSeparator. -Style/Semicolon: - Exclude: - - 'spec/chewy/query/criteria_spec.rb' - - 'spec/chewy/strategy/atomic_spec.rb' - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/object_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/SpaceAfterColon: - Exclude: - - 'spec/chewy/query/pagination/will_paginage_spec.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -Style/SpaceAfterComma: - Exclude: - - 'lib/chewy/minitest/search_index_receiver.rb' - - 'spec/chewy/minitest/helpers_spec.rb' - - 'spec/chewy/minitest/search_index_receiver_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceAroundEqualsInParameterDefault: - Exclude: - - 'lib/chewy/query/pagination/will_paginate.rb' - -# Offense count: 25 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Style/SpaceAroundOperators: - Exclude: - - 'lib/chewy/runtime/version.rb' - - 'spec/chewy/fields/base_spec.rb' - - 'spec/chewy/query/criteria_spec.rb' - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/search_spec.rb' - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - - 'spec/chewy/type/import_spec.rb' - -# Offense count: 91 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceBeforeBlockBraces: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/SpaceBeforeComment: - Exclude: - - 'spec/support/sequel.rb' - -# Offense count: 56 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -Style/SpaceInsideBlockBraces: - Exclude: - - 'lib/chewy/minitest/search_index_receiver.rb' - - 'spec/chewy/fields/time_fields_spec.rb' - - 'spec/chewy/minitest/helpers_spec.rb' - - 'spec/chewy/minitest/search_index_receiver_spec.rb' - - 'spec/chewy/query/filters_spec.rb' - - 'spec/chewy/query/nodes/has_child_spec.rb' - - 'spec/chewy/query/nodes/has_parent_spec.rb' - - 'spec/chewy/rspec/update_index_spec.rb' - - 'spec/chewy/search_spec.rb' - - 'spec/chewy/type/adapter/active_record_spec.rb' - - 'spec/chewy/type/adapter/mongoid_spec.rb' - - 'spec/chewy/type/adapter/sequel_spec.rb' - - 'spec/chewy/type/witchcraft_spec.rb' - - 'spec/chewy_spec.rb' - -# Offense count: 14 -# Cop supports --auto-correct. -Style/SpaceInsideBrackets: - Exclude: - - 'lib/chewy/rake_helper.rb' - - 'spec/chewy/query/criteria_spec.rb' - - 'spec/chewy/query_spec.rb' - -# Offense count: 2881 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. -# SupportedStyles: space, no_space, compact -Style/SpaceInsideHashLiteralBraces: - Enabled: false - -# Offense count: 24 -# Cop supports --auto-correct. -Style/SpaceInsideParens: - Exclude: - - 'spec/chewy/type/adapter/sequel_spec.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceInsideStringInterpolation: - Exclude: - - 'lib/chewy/rspec/update_index.rb' - -# Offense count: 55 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: IgnoredMethods. -# IgnoredMethods: respond_to, define_method -Style/SymbolProc: - Exclude: - - 'lib/chewy/backports/deep_dup.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: final_newline, final_blank_line -Style/TrailingBlankLines: - Exclude: - - 'lib/chewy/rspec.rb' - - 'lib/generators/chewy/install_generator.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'spec/chewy/fields/time_fields_spec.rb' - - 'spec/chewy/query/filters_spec.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma -Style/TrailingCommaInLiteral: - Exclude: - - 'lib/chewy/query/nodes/equal.rb' - - 'lib/chewy/query/nodes/range.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/WhileUntilDo: - Exclude: - - 'lib/chewy/type/import.rb' - -# Offense count: 86 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex. -# SupportedStyles: percent, brackets -Style/WordArray: - Exclude: - - 'lib/chewy/fields/base.rb' - - 'spec/chewy/fields/base_spec.rb' - - 'spec/chewy/index/actions_spec.rb' - - 'spec/chewy/index/aliases_spec.rb' - - 'spec/chewy/index/settings_spec.rb' - - 'spec/chewy/index_spec.rb' - - 'spec/chewy/query/criteria_spec.rb' - - 'spec/chewy/query/filters_spec.rb' - - 'spec/chewy/query/nodes/equal_spec.rb' - - 'spec/chewy/query_spec.rb' - - 'spec/chewy/rspec/update_index_spec.rb' - - 'spec/chewy/type/import_spec.rb' diff --git a/Guardfile b/Guardfile index 0b809aad4..67d4c153b 100644 --- a/Guardfile +++ b/Guardfile @@ -4,20 +4,20 @@ guard :rspec, cmd: 'rspec' do watch(%r{^spec/.+_spec\.rb$}) watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } - watch('spec/spec_helper.rb') { "spec" } + watch('spec/spec_helper.rb') { 'spec' } # Rails example watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] } - watch(%r{^spec/support/(.+)\.rb$}) { "spec" } - watch('config/routes.rb') { "spec/routing" } - watch('app/controllers/application_controller.rb') { "spec/controllers" } + watch(%r{^spec/support/(.+)\.rb$}) { 'spec' } + watch('config/routes.rb') { 'spec/routing' } + watch('app/controllers/application_controller.rb') { 'spec/controllers' } # Capybara features specs watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" } # Turnip features and steps watch(%r{^spec/acceptance/(.+)\.feature$}) - watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } + watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' } end diff --git a/lib/chewy.rb b/lib/chewy.rb index a0e6ce7a3..3af347c4b 100644 --- a/lib/chewy.rb +++ b/lib/chewy.rb @@ -73,7 +73,6 @@ module Mongoid::Document::ClassMethods end module Chewy - @adapters = [ Chewy::Type::Adapter::ActiveRecord, Chewy::Type::Adapter::Mongoid, @@ -94,25 +93,25 @@ class << self # # If index has more then one type - it raises Chewy::UnderivableType. # - def derive_type name + def derive_type(name) return name if name.is_a?(Class) && name < Chewy::Type index_name, type_name = name.split('#', 2) class_name = "#{index_name.camelize}Index" index = class_name.safe_constantize - raise Chewy::UnderivableType.new("Can not find index named `#{class_name}`") unless index && index < Chewy::Index + raise Chewy::UnderivableType, "Can not find index named `#{class_name}`" unless index && index < Chewy::Index if type_name.present? - index.type_hash[type_name] or raise Chewy::UnderivableType.new("Index `#{class_name}` doesn`t have type named `#{type_name}`") + index.type_hash[type_name] or raise Chewy::UnderivableType, "Index `#{class_name}` doesn`t have type named `#{type_name}`" elsif index.types.one? index.types.first else - raise Chewy::UnderivableType.new("Index `#{class_name}` has more than one type, please specify type via `#{index_name}#type_name`") + raise Chewy::UnderivableType, "Index `#{class_name}` has more than one type, please specify type via `#{index_name}#type_name`" end end # Creates Chewy::Type ancestor defining index and adapter methods. # - def create_type index, target, options = {}, &block + def create_type(index, target, options = {}, &block) type = Class.new(Chewy::Type) adapter = adapters.find { |klass| klass.accepts?(target) }.new(target, options) @@ -149,7 +148,7 @@ def wait_for_status # Be careful, if current prefix is blank, this will destroy all the indexes. # def massacre - Chewy.client.indices.delete(index: [Chewy.configuration[:prefix], '*'].delete_if(&:blank?).join(?_)) + Chewy.client.indices.delete(index: [Chewy.configuration[:prefix], '*'].delete_if(&:blank?).join('_')) Chewy.wait_for_status end alias_method :delete_all, :massacre @@ -177,7 +176,7 @@ def massacre # Chewy.strategy.pop # city3.do_update! # index updated again # - def strategy name = nil, &block + def strategy(name = nil, &block) Thread.current[:chewy_strategy] ||= Chewy::Strategy.new if name if block diff --git a/lib/chewy/backports/deep_dup.rb b/lib/chewy/backports/deep_dup.rb index 55190b3fd..dab2fbda2 100644 --- a/lib/chewy/backports/deep_dup.rb +++ b/lib/chewy/backports/deep_dup.rb @@ -25,7 +25,7 @@ class Array # array[1][2] # => nil # dup[1][2] # => 4 def deep_dup - map { |it| it.deep_dup } + map(&:deep_dup) end end diff --git a/lib/chewy/config.rb b/lib/chewy/config.rb index fa62db562..b47cc3161 100644 --- a/lib/chewy/config.rb +++ b/lib/chewy/config.rb @@ -43,7 +43,7 @@ class Config :indices_path def self.delegated - public_instance_methods - self.superclass.public_instance_methods - Singleton.public_instance_methods + public_instance_methods - superclass.public_instance_methods - Singleton.public_instance_methods end def initialize @@ -56,12 +56,12 @@ def initialize @indices_path = 'app/chewy' end - def transport_logger= logger + def transport_logger=(logger) Chewy.client.transport.logger = logger @transport_logger = logger end - def transport_tracer= tracer + def transport_tracer=(tracer) Chewy.client.transport.tracer = tracer @transport_tracer = tracer end @@ -116,7 +116,7 @@ def configuration end end - def configuration= options + def configuration=(options) ActiveSupport::Deprecation.warn("`Chewy.configuration = {foo: 'bar'}` method is deprecated and will be removed soon, use `Chewy.settings = {foo: 'bar'}` method instead") self.settings = options end diff --git a/lib/chewy/errors.rb b/lib/chewy/errors.rb index eb75b7269..07dc1cda0 100644 --- a/lib/chewy/errors.rb +++ b/lib/chewy/errors.rb @@ -12,7 +12,7 @@ class UnderivableType < Error end class UndefinedUpdateStrategy < Error - def initialize _type + def initialize(_type) super <<-MESSAGE Index update strategy is undefined in current context. Please wrap your code with `Chewy.strategy(:strategy_name) block.` @@ -24,7 +24,7 @@ class DocumentNotFound < Error end class ImportFailed < Error - def initialize type, import_errors + def initialize(type, import_errors) message = "Import failed for `#{type}` with:\n" import_errors.each do |action, action_errors| message << " #{action.to_s.humanize} errors:\n" diff --git a/lib/chewy/fields/base.rb b/lib/chewy/fields/base.rb index 97bdf52c4..c8a14af52 100644 --- a/lib/chewy/fields/base.rb +++ b/lib/chewy/fields/base.rb @@ -5,7 +5,8 @@ class Base attr_accessor :parent def initialize(name, options = {}) - @name, @options = name.to_sym, options.deep_symbolize_keys + @name = name.to_sym + @options = options.deep_symbolize_keys @value = @options.delete(:value) @children = [] end @@ -15,7 +16,7 @@ def multi_field? end def object_field? - (children.present? && options[:type].blank?) || ['object', 'nested'].include?(options[:type].to_s) + (children.present? && options[:type].blank?) || %w(object nested).include?(options[:type].to_s) end def mappings_hash @@ -24,14 +25,14 @@ def mappings_hash } : {} mapping.reverse_merge!(options) mapping.reverse_merge!(type: (children.present? ? 'object' : 'string')) - {name => mapping} + { name => mapping } end def compose(object, *parent_objects) objects = ([object] + parent_objects.flatten).uniq result = if value && value.is_a?(Proc) - if value.arity == 0 + if value.arity.zero? object.instance_exec(&value) elsif value.arity < 0 value.call(*object) @@ -39,7 +40,7 @@ def compose(object, *parent_objects) value.call(*objects.first(value.arity)) end elsif object.is_a?(Hash) - if object.has_key?(name) + if object.key?(name) object[name] else object[name.to_s] @@ -54,7 +55,7 @@ def compose(object, *parent_objects) compose_children(result, *objects) end if children.present? && !multi_field? - {name => result} + { name => result } end private diff --git a/lib/chewy/fields/root.rb b/lib/chewy/fields/root.rb index a2cf984e0..20eca405b 100644 --- a/lib/chewy/fields/root.rb +++ b/lib/chewy/fields/root.rb @@ -34,11 +34,11 @@ def mappings_hash mappings end - def dynamic_template *args + def dynamic_template(*args) options = args.extract_options!.deep_symbolize_keys if args.first template_name = :"template_#{dynamic_templates.count.next}" - template = {template_name => {mapping: options}} + template = { template_name => { mapping: options } } template[template_name][:match_mapping_type] = args.second.to_s if args.second.present? @@ -57,13 +57,13 @@ def dynamic_template *args def compose_parent(object) if parent_id - parent_id.arity == 0 ? object.instance_exec(&parent_id) : parent_id.call(object) + parent_id.arity.zero? ? object.instance_exec(&parent_id) : parent_id.call(object) end end def compose_id(object) if id - id.arity == 0 ? object.instance_exec(&id) : id.call(object) + id.arity.zero? ? object.instance_exec(&id) : id.call(object) end end end diff --git a/lib/chewy/index.rb b/lib/chewy/index.rb index ecb3c0cac..525aae101 100644 --- a/lib/chewy/index.rb +++ b/lib/chewy/index.rb @@ -107,7 +107,7 @@ def self.#{type_class.type_name} # UsersIndex.filters { name =~ 'ro' }.types(:admin, :manager) # UsersIndex.types(:admin, :manager).filters { name =~ 'ro' } # the same as the first example # - def self.types *args + def self.types(*args) if args.present? all.types(*args) else @@ -164,9 +164,9 @@ def self.journal? types.any?(&:journal?) end - def self.build_index_name *args + def self.build_index_name(*args) options = args.extract_options! - [options[:prefix], args.first || index_name, options[:suffix]].reject(&:blank?).join(?_) + [options[:prefix], args.first || index_name, options[:suffix]].reject(&:blank?).join('_') end def self.settings_hash @@ -175,7 +175,7 @@ def self.settings_hash def self.mappings_hash mappings = types.map(&:mappings_hash).inject(:merge) - mappings.present? ? {mappings: mappings} : {} + mappings.present? ? { mappings: mappings } : {} end def self.index_params diff --git a/lib/chewy/index/actions.rb b/lib/chewy/index/actions.rb index e6698dfbd..51d2be917 100644 --- a/lib/chewy/index/actions.rb +++ b/lib/chewy/index/actions.rb @@ -30,7 +30,7 @@ def exists? # Suffixed index names might be used for zero-downtime mapping change, for example. # Description: (http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/). # - def create *args + def create(*args) create!(*args) rescue Elasticsearch::Transport::Transport::Errors::BadRequest false @@ -52,13 +52,13 @@ def create *args # Suffixed index names might be used for zero-downtime mapping change, for example. # Description: (http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/). # - def create! *args + def create!(*args) options = args.extract_options!.reverse_merge!(alias: true) name = build_index_name(suffix: args.first) if Chewy::Runtime.version >= 1.1 body = index_params - body[:aliases] = {index_name => {}} if options[:alias] && name != index_name + body[:aliases] = { index_name => {} } if options[:alias] && name != index_name result = client.indices.create(index: name, body: body) else result = client.indices.create(index: name, body: index_params) @@ -77,7 +77,7 @@ def create! *args # # UsersIndex.delete '01-2014' # deletes `users_01-2014` index # - def delete suffix = nil + def delete(suffix = nil) result = client.indices.delete index: build_index_name(suffix: suffix) Chewy.wait_for_status if result result @@ -96,7 +96,7 @@ def delete suffix = nil # # UsersIndex.delete '01-2014' # deletes `users_01-2014` index # - def delete! suffix = nil + def delete!(suffix = nil) # es-ruby >= 1.0.10 handles Elasticsearch::Transport::Transport::Errors::NotFound # by itself, so it is raised here delete(suffix) or raise Elasticsearch::Transport::Transport::Errors::NotFound @@ -108,7 +108,7 @@ def delete! suffix = nil # UsersIndex.purge # deletes and creates `users` index # UsersIndex.purge '01-2014' # deletes `users` and `users_01-2014` indexes, creates `users_01-2014` # - def purge suffix = nil + def purge(suffix = nil) delete if suffix.present? delete suffix create suffix @@ -121,7 +121,7 @@ def purge suffix = nil # UsersIndex.purge! # deletes and creates `users` index # UsersIndex.purge! '01-2014' # deletes `users` and `users_01-2014` indexes, creates `users_01-2014` # - def purge! suffix = nil + def purge!(suffix = nil) delete if suffix.present? && exists? delete suffix create! suffix @@ -160,16 +160,16 @@ def #{method} options = {} # # UsersIndex.reset! Time.now.to_i, journal: true # - def reset! suffix = nil, journal: false + def reset!(suffix = nil, journal: false) if suffix.present? && (indexes = self.indexes).present? create! suffix, alias: false result = import suffix: suffix, journal: journal - client.indices.update_aliases body: {actions: [ + client.indices.update_aliases body: { actions: [ *indexes.map do |index| - {remove: {index: index, alias: index_name}} + { remove: { index: index, alias: index_name } } end, - {add: {index: build_index_name(suffix: suffix), alias: index_name}} - ]} + { add: { index: build_index_name(suffix: suffix), alias: index_name } } + ] } client.indices.delete index: indexes if indexes.present? result else diff --git a/lib/chewy/index/settings.rb b/lib/chewy/index/settings.rb index a2947367a..5ca08d7ab 100644 --- a/lib/chewy/index/settings.rb +++ b/lib/chewy/index/settings.rb @@ -1,6 +1,5 @@ module Chewy class Index - # Stores ElasticSearch index settings and resolves `analysis` # hash. At first, you need to store some analyzers or other # analysis options to the corresponding repository: @@ -37,7 +36,7 @@ def to_hash .deep_merge((settings[:index] || {}).deep_symbolize_keys) end - settings.present? ? {settings: settings} : {} + settings.present? ? { settings: settings } : {} end private @@ -67,7 +66,7 @@ def resolve(params, repository) else name_or_hash = name_or_hash.to_sym resolved = repository[name_or_hash] - resolved ? {name_or_hash => resolved} : {} + resolved ? { name_or_hash => resolved } : {} end result.merge!(options) end diff --git a/lib/chewy/journal.rb b/lib/chewy/journal.rb index 81898a372..e012eef9f 100644 --- a/lib/chewy/journal.rb +++ b/lib/chewy/journal.rb @@ -3,11 +3,11 @@ class Journal JOURNAL_MAPPING = { journal: { properties: { - index_name: {type: 'string', index: 'not_analyzed'}, - type_name: {type: 'string', index: 'not_analyzed'}, - action: {type: 'string', index: 'not_analyzed'}, - object_ids: {type: 'string', index: 'not_analyzed'}, - created_at: {type: 'date', format: 'basic_date_time'} + index_name: { type: 'string', index: 'not_analyzed' }, + type_name: { type: 'string', index: 'not_analyzed' }, + action: { type: 'string', index: 'not_analyzed' }, + object_ids: { type: 'string', index: 'not_analyzed' }, + created_at: { type: 'date', format: 'basic_date_time' } } } }.freeze @@ -46,7 +46,7 @@ def any_records? @records.any? end - private + private def identify(objects) @index.adapter.identify(objects) @@ -75,12 +75,12 @@ def entries_from(time) def create return if exists? - Chewy.client.indices.create index: index_name, body: {settings: {index: Chewy.configuration[:index]}, mappings: JOURNAL_MAPPING} + Chewy.client.indices.create index: index_name, body: { settings: { index: Chewy.configuration[:index] }, mappings: JOURNAL_MAPPING } Chewy.wait_for_status end def delete! - Chewy.client.delete_by_query index: index_name, body: {query: {match_all: {}}} + Chewy.client.delete_by_query index: index_name, body: { query: { match_all: {} } } Chewy.wait_for_status end @@ -122,7 +122,7 @@ def query(time, comparator, query_type = :filter) end class Entry - ATTRIBUTES = %w[index_name type_name action object_ids created_at].freeze + ATTRIBUTES = %w(index_name type_name action object_ids created_at).freeze attr_accessor(*ATTRIBUTES) diff --git a/lib/chewy/log_subscriber.rb b/lib/chewy/log_subscriber.rb index 11f9ccef0..c35d63fbf 100644 --- a/lib/chewy/log_subscriber.rb +++ b/lib/chewy/log_subscriber.rb @@ -16,7 +16,7 @@ def delete_query(event) render_action('Delete by Query', event) { |payload| payload[:request] } end - def render_action action, event + def render_action(action, event) payload = event.payload description = yield(payload) diff --git a/lib/chewy/minitest/helpers.rb b/lib/chewy/minitest/helpers.rb index 304d93f9d..a482ecd74 100644 --- a/lib/chewy/minitest/helpers.rb +++ b/lib/chewy/minitest/helpers.rb @@ -14,27 +14,25 @@ module Helpers # Should be set to true unless actually testing search functionality. # # @return (SearchIndexReceiver) for optional further assertions on the nature of the index changes. - def assert_indexes index, strategy: :atomic, bypass_actual_index: true + def assert_indexes(index, strategy: :atomic, bypass_actual_index: true) type = Chewy.derive_type index receiver = SearchIndexReceiver.new bulk_method = type.method :bulk # Manually mocking #bulk because we need to properly capture `self` - bulk_mock = -> (*bulk_args) do + bulk_mock = lambda do |*bulk_args| receiver.catch bulk_args, self - unless bypass_actual_index - bulk_method.call(*bulk_args) - end + bulk_method.call(*bulk_args) unless bypass_actual_index {} end type.define_singleton_method :bulk, bulk_mock - Chewy.strategy(strategy) do - yield - end + Chewy.strategy(strategy) do + yield + end type.define_singleton_method :bulk, bulk_method @@ -46,7 +44,7 @@ def assert_indexes index, strategy: :atomic, bypass_actual_index: true # Run indexing for the database changes during the block provided. # By default, indexing is run at the end of the block. # @param (Symbol) strategy the Chewy index update strategy see Chewy docs. - def run_indexing strategy: :atomic + def run_indexing(strategy: :atomic) Chewy.strategy strategy do yield end @@ -74,7 +72,6 @@ def index_everything! Chewy.massacre end end - end end end diff --git a/lib/chewy/minitest/search_index_receiver.rb b/lib/chewy/minitest/search_index_receiver.rb index 46c271d23..681586a9d 100644 --- a/lib/chewy/minitest/search_index_receiver.rb +++ b/lib/chewy/minitest/search_index_receiver.rb @@ -12,8 +12,8 @@ def initialize # @param bulk_params the bulk_params that should be sent to the Chewy::Type#bulk method. # @param (Chewy::Type) type the Index::Type executing this query. - def catch bulk_params, type - Array.wrap(bulk_params).map {|y| y[:body] }.flatten.each do |update| + def catch(bulk_params, type) + Array.wrap(bulk_params).map { |y| y[:body] }.flatten.each do |update| if update[:delete] mutation_for(type).deletes << update[:delete][:_id] elsif update[:index] @@ -24,12 +24,12 @@ def catch bulk_params, type # @param index return only index requests to the specified Chewy::Type index. # @return the index changes captured by the mock. - def indexes_for index = nil + def indexes_for(index = nil) if index mutation_for(index).indexes else Hash[ - @mutations.map { |a,b| [a, b.indexes] } + @mutations.map { |a, b| [a, b.indexes] } ] end end @@ -37,12 +37,12 @@ def indexes_for index = nil # @param index return only delete requests to the specified Chewy::Type index. # @return the index deletes captured by the mock. - def deletes_for index = nil + def deletes_for(index = nil) if index mutation_for(index).deletes else Hash[ - @mutations.map { |a,b| [a, b.deletes] } + @mutations.map { |a, b| [a, b.deletes] } ] end end @@ -52,15 +52,15 @@ def deletes_for index = nil # @param (#id) obj the object to look for. # @param Chewy::Type what type the object should be indexed as. # @return bool if the object was indexed. - def indexed? obj, type - indexes_for(type).map {|i| i[:_id]}.include? obj.id + def indexed?(obj, type) + indexes_for(type).map { |i| i[:_id] }.include? obj.id end # Check to see if a given object has been deleted. # @param (#id) obj the object to look for. # @param Chewy::Type what type the object should have been deleted from. # @return bool if the object was deleted. - def deleted? obj, type + def deleted?(obj, type) deletes_for(type).include? obj.id end @@ -69,12 +69,12 @@ def updated_indexes @mutations.keys end - private +private + # Get the mutation object for a given type. # @param (Chewy::Type) type the index type to fetch. # @return (#indexes, #deletes) an object with a list of indexes and a list of deletes. - def mutation_for type + def mutation_for(type) @mutations[type] ||= OpenStruct.new(indexes: [], deletes: []) end - end diff --git a/lib/chewy/query.rb b/lib/chewy/query.rb index 9776f9eef..f2d484983 100644 --- a/lib/chewy/query.rb +++ b/lib/chewy/query.rb @@ -23,7 +23,7 @@ class Query attr_reader :_indexes, :_types, :options, :criteria - def initialize *indexes_or_types_and_options + def initialize(*indexes_or_types_and_options) @options = indexes_or_types_and_options.extract_options! @_types = indexes_or_types_and_options.select { |klass| klass < Chewy::Type } @_indexes = indexes_or_types_and_options.select { |klass| klass < Chewy::Index } @@ -39,7 +39,7 @@ def initialize *indexes_or_types_and_options # UsersIndex.filter(term: {name: 'Johny'}) == UsersIndex.filter(term: {name: 'Johny'}).to_a # => true # UsersIndex.filter(term: {name: 'Johny'}) == UsersIndex.filter(term: {name: 'Winnie'}) # => false # - def == other + def ==(other) super || other.is_a?(self.class) ? other.criteria == criteria : other == to_a end @@ -55,7 +55,7 @@ def == other # # UsersIndex::User.filter(term: {name: 'Johny'}).explain.first._explanation # => {...} # - def explain value = nil + def explain(value = nil) chain { criteria.update_request_options explain: (value.nil? ? true : value) } end @@ -69,7 +69,7 @@ def explain value = nil # script: "doc['coordinates'].distanceInMiles(lat, lon)" # } # ) - def script_fields value + def script_fields(value) chain { criteria.update_script_fields(value) } end @@ -139,7 +139,7 @@ def script_fields value # Chewy.query_mode = :dis_max # Chewy.query_mode = '50%' # - def query_mode value + def query_mode(value) chain { criteria.update_options query_mode: value } end @@ -211,7 +211,7 @@ def query_mode value # Chewy.filter_mode = :should # Chewy.filter_mode = '50%' # - def filter_mode value + def filter_mode(value) chain { criteria.update_options filter_mode: value } end @@ -223,7 +223,7 @@ def filter_mode value # UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode(:should) # UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode('50%') # - def post_filter_mode value + def post_filter_mode(value) chain { criteria.update_options post_filter_mode: value } end @@ -272,7 +272,7 @@ def post_filter_mode value # Use the timeout because it is important to your SLA, not because you want # to abort the execution of long running queries. # - def timeout value + def timeout(value) chain { criteria.update_request_options timeout: value } end @@ -285,7 +285,7 @@ def timeout value # size: 100 # }} # - def limit value = nil, &block + def limit(value = nil, &block) chain { criteria.update_request_options size: block || Integer(value) } end @@ -297,7 +297,7 @@ def limit value = nil, &block # from: 300 # }} # - def offset value = nil, &block + def offset(value = nil, &block) chain { criteria.update_request_options from: block || Integer(value) } end @@ -305,7 +305,7 @@ def offset value = nil, &block # # UsersIndex.query(...).highlight(fields: { ... }) # - def highlight value + def highlight(value) chain { criteria.update_request_options highlight: value } end @@ -313,7 +313,7 @@ def highlight value # # UsersIndex.query(...).rescore(query: { ... }) # - def rescore value + def rescore(value) chain { criteria.update_request_options rescore: value } end @@ -321,7 +321,7 @@ def rescore value # # UsersIndex.query(...).min_score(0.5) # - def min_score value + def min_score(value) chain { criteria.update_request_options min_score: value } end @@ -338,7 +338,7 @@ def min_score value # If called parameterless - returns result facets from ES performing request. # Returns empty hash if no facets was requested or resulted. # - def facets params = nil + def facets(params = nil) raise RemovedFeature, 'removed in elasticsearch 2.0' if Runtime.version >= '2.0' if params chain { criteria.update_facets params } @@ -502,8 +502,8 @@ def field_value_factor(settings, options = {}) def decay(function, field, options = {}) field_options = options.extract!(:origin, :scale, :offset, :decay).delete_if { |_, v| v.nil? } scoring = options.merge(function => { - field => field_options - }) + field => field_options + }) chain { criteria.update_scores scoring } end @@ -519,7 +519,7 @@ def decay(function, field, options = {}) # } # }} # - def aggregations params = nil + def aggregations(params = nil) @_named_aggs ||= _build_named_aggs @_fully_qualified_named_aggs ||= _build_fqn_aggs if params @@ -530,7 +530,7 @@ def aggregations params = nil _response['aggregations'] || {} end end - alias :aggs :aggregations + alias_method :aggs, :aggregations # In this simplest of implementations each named aggregation must be uniquely named def _build_named_aggs @@ -580,7 +580,7 @@ def _get_fully_qualified_named_agg(str) # } # }} # - def suggest params = nil + def suggest(params = nil) if params chain { criteria.update_suggest params } else @@ -613,7 +613,7 @@ def none # } } # }} # - def strategy value = nil + def strategy(value = nil) chain { criteria.update_options strategy: value } end @@ -639,7 +639,7 @@ def strategy value = nil # query: {text: {name: 'Johny'}} # }} # - def query params + def query(params) chain { criteria.update_queries params } end @@ -671,7 +671,7 @@ def query params # filter: {term: {name: 'Johny'}} # }}}} # - def filter params = nil, &block + def filter(params = nil, &block) params = Filters.new(&block).__render__ if block chain { criteria.update_filters params } end @@ -702,7 +702,7 @@ def filter params = nil, &block # post_filter: {term: {name: 'Johny'}} # }} # - def post_filter params = nil, &block + def post_filter(params = nil, &block) params = Filters.new(&block).__render__ if block chain { criteria.update_post_filters params } end @@ -740,7 +740,7 @@ def post_filter params = nil, &block # # Default value for :boost_mode might be changed # with Chewy.score_mode config option. - def boost_mode value + def boost_mode(value) chain { criteria.update_options boost_mode: value } end @@ -780,7 +780,7 @@ def boost_mode value # # Chewy.score_mode = :first # - def score_mode value + def score_mode(value) chain { criteria.update_options score_mode: value } end @@ -792,7 +792,7 @@ def score_mode value # sort: ['first_name', 'last_name', {age: 'desc'}, {price: {order: 'asc', mode: 'avg'}}] # }} # - def order *params + def order(*params) chain { criteria.update_sort params } end @@ -804,7 +804,7 @@ def order *params # sort: [{price: {order: 'asc', mode: 'avg'}}] # }} # - def reorder *params + def reorder(*params) chain { criteria.update_sort params, purge: true } end @@ -816,7 +816,7 @@ def reorder *params # fields: ['first_name', 'last_name', 'age'] # }} # - def only *params + def only(*params) chain { criteria.update_fields params } end @@ -828,7 +828,7 @@ def only *params # fields: ['age'] # }} # - def only! *params + def only!(*params) chain { criteria.update_fields params, purge: true } end @@ -864,7 +864,7 @@ def only! *params # ]} # }}}} # - def types *params + def types(*params) chain { criteria.update_types params } end @@ -876,7 +876,7 @@ def types *params # filter: {type: {value: 'manager'}} # }}}} # - def types! *params + def types!(*params) chain { criteria.update_types params, purge: true } end @@ -890,7 +890,7 @@ def types! *params # scope = UsersIndex.aggs(max_age: { max: { field: 'age' } }).search_type(:count) # max_age = scope.aggs['max_age']['value'] # - def search_type value + def search_type(value) chain { criteria.update_search_options search_type: value } end @@ -903,7 +903,7 @@ def search_type value # # scope1.merge(scope2) == scope3 # => true # - def merge other + def merge(other) chain { criteria.merge!(other.criteria) } end @@ -916,15 +916,15 @@ def merge other # def delete_all if Runtime.version > '2.0' - plugins = Chewy.client.nodes.info(plugins: true)["nodes"].values.map { |item| item["plugins"] }.flatten - raise PluginMissing, "install delete-by-query plugin" unless plugins.find { |item| item["name"] == 'delete-by-query' } + plugins = Chewy.client.nodes.info(plugins: true)['nodes'].values.map { |item| item['plugins'] }.flatten + raise PluginMissing, 'install delete-by-query plugin' unless plugins.find { |item| item['name'] == 'delete-by-query' } end request = chain { criteria.update_options simple: true }.send(:_request) ActiveSupport::Notifications.instrument 'delete_query.chewy', request: request, indexes: _indexes, types: _types, index: _indexes.one? ? _indexes.first : _indexes, type: _types.one? ? _types.first : _types do - Chewy.client.delete_by_query(request) + Chewy.client.delete_by_query(request) end end @@ -942,10 +942,10 @@ def delete_all # UsersIndex::User.find([8, 13]) # array of objects with ids in [8, 13] # UsersIndex::User.find([42]) # array of the object with id == 42 # - def find *ids + def find(*ids) results = chain { criteria.update_options simple: true }.filter { _id == ids.flatten }.to_a - raise Chewy::DocumentNotFound.new("Could not find documents for ids #{ids.flatten}") if results.empty? + raise Chewy::DocumentNotFound, "Could not find documents for ids #{ids.flatten}" if results.empty? ids.one? && !ids.first.is_a?(Array) ? results.first : results end @@ -991,14 +991,14 @@ def timed_out protected - def initialize_clone other + def initialize_clone(other) @criteria = other.criteria.clone reset end private - def chain &block + def chain(&block) clone.tap { |q| q.instance_exec(&block) } end @@ -1020,12 +1020,12 @@ def _response request: _request, indexes: _indexes, types: _types, index: _indexes.one? ? _indexes.first : _indexes, type: _types.one? ? _types.first : _types do - begin - Chewy.client.search(_request) - rescue Elasticsearch::Transport::Transport::Errors::NotFound => e - raise e if e.message !~ /IndexMissingException/ && e.message !~ /index_not_found_exception/ - {} - end + begin + Chewy.client.search(_request) + rescue Elasticsearch::Transport::Transport::Errors::NotFound => e + raise e if e.message !~ /IndexMissingException/ && e.message !~ /index_not_found_exception/ + {} + end end end @@ -1050,7 +1050,7 @@ def _collection end end - def _derive_index index_name + def _derive_index(index_name) (@derive_index ||= {})[index_name] ||= _indexes_hash[index_name] || _indexes_hash[_indexes_hash.keys.sort_by(&:length).reverse.detect { |name| index_name.start_with?(name) }] end diff --git a/lib/chewy/query/compose.rb b/lib/chewy/query/compose.rb index 0c7548a5e..b8945721a 100644 --- a/lib/chewy/query/compose.rb +++ b/lib/chewy/query/compose.rb @@ -1,10 +1,9 @@ module Chewy class Query module Compose - protected - def _filtered_query query, filter, options = {} + def _filtered_query(query, filter, options = {}) query = { match_all: {} } if !query.present? && filter.present? if filter.present? @@ -23,11 +22,11 @@ def _filtered_query query, filter, options = {} elsif query.present? { query: query } else - { } + {} end end - def _queries_join queries, logic + def _queries_join(queries, logic) queries = queries.compact if queries.many? || (queries.present? && logic == :must_not) @@ -48,7 +47,7 @@ def _queries_join queries, logic end end - def _filters_join filters, logic + def _filters_join(filters, logic) filters = filters.compact if filters.many? || (filters.present? && logic == :must_not) diff --git a/lib/chewy/query/criteria.rb b/lib/chewy/query/criteria.rb index cefffc435..43e080329 100644 --- a/lib/chewy/query/criteria.rb +++ b/lib/chewy/query/criteria.rb @@ -4,11 +4,11 @@ module Chewy class Query class Criteria include Compose - ARRAY_STORAGES = [:queries, :filters, :post_filters, :sort, :fields, :types, :scores] - HASH_STORAGES = [:options, :search_options, :request_options, :facets, :aggregations, :suggest, :script_fields] + ARRAY_STORAGES = [:queries, :filters, :post_filters, :sort, :fields, :types, :scores].freeze + HASH_STORAGES = [:options, :search_options, :request_options, :facets, :aggregations, :suggest, :script_fields].freeze STORAGES = ARRAY_STORAGES + HASH_STORAGES - def initialize options = {} + def initialize(options = {}) @options = options.merge( query_mode: Chewy.query_mode, filter_mode: Chewy.filter_mode, @@ -16,7 +16,7 @@ def initialize options = {} ) end - def == other + def ==(other) other.is_a?(self.class) && storages == other.storages end @@ -83,7 +83,7 @@ def update_#{storage}(modifier) def update_sort(modifier, options = {}) @sort = nil if options[:purge] modifier = Array.wrap(modifier).flatten.map do |element| - element.is_a?(Hash) ? element.map { |k, v| {k => v} } : element + element.is_a?(Hash) ? element.map { |k, v| { k => v } } : element end.flatten @sort = sort + modifier end @@ -97,14 +97,14 @@ def update_sort(modifier, options = {}) end end - def merge! other + def merge!(other) STORAGES.each do |storage| send("update_#{storage}", other.send(storage)) end self end - def merge other + def merge(other) clone.merge!(other) end diff --git a/lib/chewy/query/filters.rb b/lib/chewy/query/filters.rb index 3e5c6b701..1dbb32192 100644 --- a/lib/chewy/query/filters.rb +++ b/lib/chewy/query/filters.rb @@ -28,7 +28,7 @@ class Query # # class Filters - def initialize outer = nil, &block + def initialize(outer = nil, &block) @block = block @outer = outer || eval('self', block.binding) end @@ -42,7 +42,7 @@ def initialize outer = nil, &block # # UsersIndex.filter{ name == o{ name } } # => {filter: {term: {name: 'Friend'}}} # - def o &block + def o(&block) @outer.instance_exec(&block) end @@ -62,7 +62,7 @@ def o &block # # UsersIndex.filter{ f{ field } == 'Name' } == UsersIndex.filter{ name == 'Name' } # => true # - def f name = nil, *args, &block + def f(name = nil, *args, &block) name = block ? o(&block) : name Nodes::Field.new name, *args end @@ -82,7 +82,7 @@ def f name = nil, *args, &block # UsersIndex.filter{ s{ script } } == UsersIndex.filter{ s('doc["num1"].value > 1') } # => true # UsersIndex.filter{ s(param1: 42) { script } } == UsersIndex.filter{ s('doc["num1"].value > 1', param1: 42) } # => true # - def s *args, &block + def s(*args, &block) params = args.extract_options! script = block ? o(&block) : args.first Nodes::Script.new script, params @@ -100,7 +100,7 @@ def s *args, &block # # UsersIndex.filter{ q{ query } } == UsersIndex.filter{ q(query_string: {query: 'name: hello'}) } # => true # - def q query = nil, &block + def q(query = nil, &block) Nodes::Query.new block ? o(&block) : query end @@ -119,7 +119,7 @@ def q query = nil, &block # UsersIndex.filter{ r{ filter } } == UsersIndex.filter{ r(term: {name: 'Name'}) } # => true # UsersIndex.filter{ r{ filter } } == UsersIndex.filter(term: {name: 'Name'}) # => true # - def r raw = nil, &block + def r(raw = nil, &block) Nodes::Raw.new block ? o(&block) : raw end @@ -155,7 +155,7 @@ def r raw = nil, &block # .filter_mode(:or) # end # - def has_child type + def has_child(type) Nodes::HasChild.new(type, @outer) end @@ -177,7 +177,7 @@ def has_child type # .filter_mode(:or) # end # - def has_parent type + def has_parent(type) Nodes::HasParent.new(type, @outer) end @@ -200,7 +200,7 @@ def match_all # UsersIndex.filter{ article.title =~ 'Hello' } # UsersIndex.filter{ article.tags? } # - def method_missing method, *args + def method_missing(method, *args) method = method.to_s if method =~ /\?\Z/ Nodes::Exists.new method.gsub(/\?\Z/, '') diff --git a/lib/chewy/query/nodes/and.rb b/lib/chewy/query/nodes/and.rb index cb3a98ac4..014fb9c42 100644 --- a/lib/chewy/query/nodes/and.rb +++ b/lib/chewy/query/nodes/and.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class And < Expr - def initialize *nodes + def initialize(*nodes) @options = nodes.extract_options! @nodes = nodes.flatten.map { |node| node.is_a?(self.class) ? node.__nodes__ : node }.flatten end @@ -14,9 +14,9 @@ def __nodes__ def __render__ nodes = @nodes.map(&:__render__) if @options.key?(:cache) - {and: {filters: nodes, _cache: !!@options[:cache]}} + { and: { filters: nodes, _cache: !!@options[:cache] } } else - {and: nodes} + { and: nodes } end end end diff --git a/lib/chewy/query/nodes/base.rb b/lib/chewy/query/nodes/base.rb index bde88e731..f5fb05cc3 100644 --- a/lib/chewy/query/nodes/base.rb +++ b/lib/chewy/query/nodes/base.rb @@ -6,7 +6,7 @@ def render raise NotImplementedError end - def eql? other + def eql?(other) other.is_a?(self.class) && instance_variables.all? do |ivar| instance_variable_get(ivar).eql? other.instance_variable_get(ivar) end diff --git a/lib/chewy/query/nodes/bool.rb b/lib/chewy/query/nodes/bool.rb index 601da0311..1a4eae47a 100644 --- a/lib/chewy/query/nodes/bool.rb +++ b/lib/chewy/query/nodes/bool.rb @@ -2,11 +2,13 @@ module Chewy class Query module Nodes class Bool < Expr - METHODS = %w(must must_not should) + METHODS = %w(must must_not should).freeze - def initialize options = {} + def initialize(options = {}) @options = options - @must, @must_not, @should = [], [], [] + @must = [] + @must_not = [] + @should = [] end METHODS.each do |method| diff --git a/lib/chewy/query/nodes/equal.rb b/lib/chewy/query/nodes/equal.rb index 1b0b468ea..0fba92f4a 100644 --- a/lib/chewy/query/nodes/equal.rb +++ b/lib/chewy/query/nodes/equal.rb @@ -10,10 +10,10 @@ class Equal < Expr :b => :bool, :bool => :bool, :f => :fielddata, - :fielddata => :fielddata, - } + :fielddata => :fielddata + }.freeze - def initialize name, value, *args + def initialize(name, value, *args) @name = name.to_s @value = value @options = args.extract_options! @@ -23,10 +23,10 @@ def initialize name, value, *args def __render__ filter = (@value.is_a?(Array) ? :terms : :term) - body = {@name => @value} + body = { @name => @value } body.merge!(@options.slice(:execution)) if filter == :terms body[:_cache] = !!@options[:cache] if @options.key?(:cache) - {filter => body} + { filter => body } end end end diff --git a/lib/chewy/query/nodes/exists.rb b/lib/chewy/query/nodes/exists.rb index 8b54ba38e..1d9918341 100644 --- a/lib/chewy/query/nodes/exists.rb +++ b/lib/chewy/query/nodes/exists.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Exists < Expr - def initialize name, options = {} + def initialize(name, options = {}) @name = name.to_s @options = options end @@ -12,7 +12,7 @@ def ! end def __render__ - {exists: {field: @name}} + { exists: { field: @name } } end end end diff --git a/lib/chewy/query/nodes/expr.rb b/lib/chewy/query/nodes/expr.rb index f95becf52..61b78ced6 100644 --- a/lib/chewy/query/nodes/expr.rb +++ b/lib/chewy/query/nodes/expr.rb @@ -2,11 +2,11 @@ module Chewy class Query module Nodes class Expr < Base - def & other + def &(other) Nodes::And.new self, other end - def | other + def |(other) Nodes::Or.new self, other end diff --git a/lib/chewy/query/nodes/field.rb b/lib/chewy/query/nodes/field.rb index c32a4ffbb..8cf4df068 100644 --- a/lib/chewy/query/nodes/field.rb +++ b/lib/chewy/query/nodes/field.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Field < Base - def initialize name, *args + def initialize(name, *args) @name = name.to_s @args = args end @@ -16,23 +16,23 @@ def ~ self end - def > value + def >(value) Nodes::Range.new @name, *__options_merge__(gt: value) end - def < value + def <(value) Nodes::Range.new @name, *__options_merge__(lt: value) end - def >= value + def >=(value) Nodes::Range.new @name, *__options_merge__(gt: value, left_closed: true) end - def <= value + def <=(value) Nodes::Range.new @name, *__options_merge__(lt: value, right_closed: true) end - def == value + def ==(value) case value when nil Nodes::Missing.new @name, existence: false, null_value: true @@ -52,7 +52,7 @@ def == value end end - def != value + def !=(value) case value when nil Nodes::Exists.new @name @@ -61,7 +61,7 @@ def != value end end - def =~ value + def =~(value) case value when ::Regexp Nodes::Regexp.new @name, value, *@args @@ -70,16 +70,16 @@ def =~ value end end - def !~ value + def !~(value) Not.new(self =~ value) end - def method_missing method, *args + def method_missing(method, *args) method = method.to_s if method =~ /\?\Z/ - Nodes::Exists.new [@name, method.gsub(/\?\Z/, '')].join(?.) + Nodes::Exists.new [@name, method.gsub(/\?\Z/, '')].join('.') else - self.class.new [@name, method].join(?.), *args + self.class.new [@name, method].join('.'), *args end end @@ -89,13 +89,13 @@ def to_ary private - def __options_merge__! additional = {} + def __options_merge__!(additional = {}) options = @args.extract_options! options = options.merge(additional) @args.push(options) end - def __options_merge__ additional = {} + def __options_merge__(additional = {}) options = @args.extract_options! options = options.merge(additional) @args + [options] diff --git a/lib/chewy/query/nodes/has_child.rb b/lib/chewy/query/nodes/has_child.rb index e509eee6d..89d4ad744 100644 --- a/lib/chewy/query/nodes/has_child.rb +++ b/lib/chewy/query/nodes/has_child.rb @@ -5,6 +5,7 @@ class Query module Nodes class HasChild < HasRelation private + def _relation :has_child end diff --git a/lib/chewy/query/nodes/has_parent.rb b/lib/chewy/query/nodes/has_parent.rb index a6cd7046d..dc7165c00 100644 --- a/lib/chewy/query/nodes/has_parent.rb +++ b/lib/chewy/query/nodes/has_parent.rb @@ -5,6 +5,7 @@ class Query module Nodes class HasParent < HasRelation private + def _relation :has_parent end diff --git a/lib/chewy/query/nodes/has_relation.rb b/lib/chewy/query/nodes/has_relation.rb index d31998b96..bc1e5750f 100644 --- a/lib/chewy/query/nodes/has_relation.rb +++ b/lib/chewy/query/nodes/has_relation.rb @@ -6,7 +6,7 @@ module Nodes class HasRelation < Expr include Compose - def initialize type, outer = nil + def initialize(type, outer = nil) @type = type.to_s @outer = outer @query_mode = :must @@ -15,17 +15,17 @@ def initialize type, outer = nil @filters = [] end - def query_mode mode + def query_mode(mode) @query_mode = mode self end - def filter_mode mode + def filter_mode(mode) @filter_mode = mode self end - def query params = nil, &block + def query(params = nil, &block) if block raise 'Query DLS is not supported yet' else @@ -34,7 +34,7 @@ def query params = nil, &block self end - def filter params = nil, &block + def filter(params = nil, &block) if block @filters.push(Chewy::Query::Filters.new(@outer, &block).__render__) else @@ -48,13 +48,13 @@ def __render__ filters = _filters_join @filters, @filter_mode body = if filters && !queries - {filter: filters} + { filter: filters } else _filtered_query(queries, filters) end body ||= {} - {_relation => body.merge(type: @type)} + { _relation => body.merge(type: @type) } end end end diff --git a/lib/chewy/query/nodes/match_all.rb b/lib/chewy/query/nodes/match_all.rb index c9d4073f4..56273d58f 100644 --- a/lib/chewy/query/nodes/match_all.rb +++ b/lib/chewy/query/nodes/match_all.rb @@ -3,7 +3,7 @@ class Query module Nodes class MatchAll < Expr def __render__ - {match_all: {}} + { match_all: {} } end end end diff --git a/lib/chewy/query/nodes/missing.rb b/lib/chewy/query/nodes/missing.rb index 38a55c142..af5479739 100644 --- a/lib/chewy/query/nodes/missing.rb +++ b/lib/chewy/query/nodes/missing.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Missing < Expr - def initialize name, options = {} + def initialize(name, options = {}) @name = name.to_s @options = options.reverse_merge(existence: true, null_value: false) end @@ -12,7 +12,7 @@ def ! end def __render__ - {missing: {field: @name}.merge(@options.slice(:existence, :null_value))} + { missing: { field: @name }.merge(@options.slice(:existence, :null_value)) } end end end diff --git a/lib/chewy/query/nodes/not.rb b/lib/chewy/query/nodes/not.rb index 49655bb56..46c2d360f 100644 --- a/lib/chewy/query/nodes/not.rb +++ b/lib/chewy/query/nodes/not.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Not < Expr - def initialize expr, options = {} + def initialize(expr, options = {}) @expr = expr @options = options end @@ -14,9 +14,9 @@ def ! def __render__ expr = @expr.__render__ if @options.key?(:cache) - {not: {filter: expr, _cache: !!@options[:cache]}} + { not: { filter: expr, _cache: !!@options[:cache] } } else - {not: expr} + { not: expr } end end end diff --git a/lib/chewy/query/nodes/or.rb b/lib/chewy/query/nodes/or.rb index 98c8d9e84..e73457b2d 100644 --- a/lib/chewy/query/nodes/or.rb +++ b/lib/chewy/query/nodes/or.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Or < Expr - def initialize *nodes + def initialize(*nodes) @options = nodes.extract_options! @nodes = nodes.flatten.map { |node| node.is_a?(self.class) ? node.__nodes__ : node }.flatten end @@ -14,9 +14,9 @@ def __nodes__ def __render__ nodes = @nodes.map(&:__render__) if @options.key?(:cache) - {or: {filters: nodes, _cache: !!@options[:cache]}} + { or: { filters: nodes, _cache: !!@options[:cache] } } else - {or: nodes} + { or: nodes } end end end diff --git a/lib/chewy/query/nodes/prefix.rb b/lib/chewy/query/nodes/prefix.rb index cac3da545..1f85d7bdc 100644 --- a/lib/chewy/query/nodes/prefix.rb +++ b/lib/chewy/query/nodes/prefix.rb @@ -2,13 +2,14 @@ module Chewy class Query module Nodes class Prefix < Expr - def initialize name, value, options = {} + def initialize(name, value, options = {}) @name = name.to_s - @value, @options = value, options + @value = value + @options = options end def __render__ - filter = {prefix: {@name => @value}} + filter = { prefix: { @name => @value } } filter[:prefix][:_cache] = !!@options[:cache] if @options.key?(:cache) filter end diff --git a/lib/chewy/query/nodes/query.rb b/lib/chewy/query/nodes/query.rb index fd76ed60d..1c5ecc42d 100644 --- a/lib/chewy/query/nodes/query.rb +++ b/lib/chewy/query/nodes/query.rb @@ -2,16 +2,16 @@ module Chewy class Query module Nodes class Query < Expr - def initialize query, options = {} + def initialize(query, options = {}) @query = query @options = options end def __render__ if @options.key?(:cache) - {fquery: {query: @query, _cache: !!@options[:cache]}} + { fquery: { query: @query, _cache: !!@options[:cache] } } else - {query: @query} + { query: @query } end end end diff --git a/lib/chewy/query/nodes/range.rb b/lib/chewy/query/nodes/range.rb index b6f463def..4f0ef37e5 100644 --- a/lib/chewy/query/nodes/range.rb +++ b/lib/chewy/query/nodes/range.rb @@ -3,13 +3,13 @@ class Query module Nodes class Range < Expr EXECUTION = { - :i => :index, - :index => :index, - :f => :fielddata, - :fielddata => :fielddata, - } + i: :index, + index: :index, + f: :fielddata, + fielddata: :fielddata + }.freeze - def initialize name, *args + def initialize(name, *args) @name = name.to_s @options = args.extract_options! @range = @options.reject { |k, _v| ![:gt, :lt].include?(k) } @@ -18,7 +18,7 @@ def initialize name, *args @options[:execution] = execution if execution end - def & other + def &(other) if other.is_a?(self.class) && other.__name__ == @name state = __state__.merge(other.__state__) @@ -51,11 +51,11 @@ def __render__ body[@bounds[:left_closed] ? :gte : :gt] = @range[:gt] if @range.key?(:gt) body[@bounds[:right_closed] ? :lte : :lt] = @range[:lt] if @range.key?(:lt) - filter = {@name => body} + filter = { @name => body } filter[:_cache] = !!@options[:cache] if @options.key?(:cache) filter.merge!(@options.slice(:execution)) - {range: filter} + { range: filter } end end end diff --git a/lib/chewy/query/nodes/raw.rb b/lib/chewy/query/nodes/raw.rb index f6b0a0f43..39cacff0e 100644 --- a/lib/chewy/query/nodes/raw.rb +++ b/lib/chewy/query/nodes/raw.rb @@ -2,7 +2,7 @@ module Chewy class Query module Nodes class Raw < Expr - def initialize raw + def initialize(raw) @raw = raw end diff --git a/lib/chewy/query/nodes/regexp.rb b/lib/chewy/query/nodes/regexp.rb index 46f3bf49b..cd3697873 100644 --- a/lib/chewy/query/nodes/regexp.rb +++ b/lib/chewy/query/nodes/regexp.rb @@ -2,9 +2,9 @@ module Chewy class Query module Nodes class Regexp < Expr - FLAGS = %w(all anystring automaton complement empty intersection interval none) + FLAGS = %w(all anystring automaton complement empty intersection interval none).freeze - def initialize name, regexp, *args + def initialize(name, regexp, *args) @name = name.to_s @regexp = regexp.respond_to?(:source) ? regexp.source : regexp.to_s @options = args.extract_options! @@ -14,15 +14,15 @@ def initialize name, regexp, *args def __render__ body = @options[:flags] ? - {value: @regexp, flags: @options[:flags].map(&:to_s).map(&:upcase).uniq.join('|')} : + { value: @regexp, flags: @options[:flags].map(&:to_s).map(&:upcase).uniq.join('|') } : @regexp - filter = {@name => body} + filter = { @name => body } if @options.key?(:cache) filter[:_cache] = !!@options[:cache] filter[:_cache_key] = @options[:cache].is_a?(TrueClass) || @options[:cache].is_a?(FalseClass) ? @regexp.underscore : @options[:cache] end - {regexp: filter} + { regexp: filter } end end end diff --git a/lib/chewy/query/nodes/script.rb b/lib/chewy/query/nodes/script.rb index a9d6a99c2..0aca4dc26 100644 --- a/lib/chewy/query/nodes/script.rb +++ b/lib/chewy/query/nodes/script.rb @@ -2,17 +2,17 @@ module Chewy class Query module Nodes class Script < Expr - def initialize script, params = {} + def initialize(script, params = {}) @script = script @params = params @options = params.reject { |k, _v| ![:cache].include?(k) } end def __render__ - script = {script: @script} + script = { script: @script } script[:params] = @params if @params.present? script[:_cache] = !!@options[:cache] if @options.key?(:cache) - {script: script} + { script: script } end end end diff --git a/lib/chewy/query/pagination/will_paginate.rb b/lib/chewy/query/pagination/will_paginate.rb index ff49052ee..13391438c 100644 --- a/lib/chewy/query/pagination/will_paginate.rb +++ b/lib/chewy/query/pagination/will_paginate.rb @@ -7,12 +7,12 @@ module WillPaginate attr_reader :current_page, :per_page - def paginate(options={}) + def paginate(options = {}) @current_page = ::WillPaginate::PageNumber(options[:page] || @current_page || 1) @page_multiplier = @current_page - 1 @per_page = (options[:per_page] || @per_page || ::WillPaginate.per_page).to_i - #call Chewy::Query methods to limit results + # call Chewy::Query methods to limit results limit(@per_page).offset(@page_multiplier * @per_page) end diff --git a/lib/chewy/railtie.rb b/lib/chewy/railtie.rb index d076e5adf..1d151f1e1 100644 --- a/lib/chewy/railtie.rb +++ b/lib/chewy/railtie.rb @@ -51,7 +51,7 @@ def migrate(*args) end initializer 'chewy.logger', after: 'active_record.logger' do - ActiveSupport.on_load(:active_record) { Chewy.logger ||= ActiveRecord::Base.logger } + ActiveSupport.on_load(:active_record) { Chewy.logger ||= ActiveRecord::Base.logger } end initializer 'chewy.migration_strategy' do diff --git a/lib/chewy/rake_helper.rb b/lib/chewy/rake_helper.rb index f72db8c44..b8576d4de 100644 --- a/lib/chewy/rake_helper.rb +++ b/lib/chewy/rake_helper.rb @@ -1,9 +1,8 @@ module Chewy module RakeHelper class << self - def subscribed_task_stats - callback = ->(_name, start, finish, _id, payload) do + callback = lambda do |_name, start, finish, _id, payload| duration = (finish - start).round(2) puts " Imported #{payload[:type]} for #{duration}s, documents total: #{payload[:import].try(:[], :index).to_i}" payload[:errors].each do |action, errors| @@ -20,7 +19,7 @@ def subscribed_task_stats end def eager_load_chewy! - dirs = Chewy::Railtie.all_engines.map { |engine| engine.paths[ Chewy.configuration[:indices_path] ] }.compact.map(&:existent).flatten.uniq + dirs = Chewy::Railtie.all_engines.map { |engine| engine.paths[Chewy.configuration[:indices_path]] }.compact.map(&:existent).flatten.uniq dirs.each do |dir| Dir.glob(File.join(dir, '**/*.rb')).each do |file| @@ -34,17 +33,17 @@ def all_indexes Chewy::Index.descendants end - def normalize_index index + def normalize_index(index) return index if index.is_a?(Chewy::Index) "#{index.to_s.gsub(/index\z/i, '').camelize}Index".constantize end - def normalize_indexes *indexes + def normalize_indexes(*indexes) indexes.flatten.map { |index| normalize_index(index) } end # Performs zero downtime reindexing of all documents in the specified index. - def reset_index *indexes + def reset_index(*indexes) normalize_indexes(indexes).each do |index| puts "Resetting #{index}" time = Time.now @@ -57,11 +56,11 @@ def reset_index *indexes end # Performs zero downtime reindexing of all documents across all indices. - def reset_all *except + def reset_all(*except) reset_index(all_indexes - normalize_indexes(except)) end - def update_index *indexes + def update_index(*indexes) normalize_indexes(indexes).each do |index| puts "Updating #{index}" if index.exists? @@ -72,7 +71,7 @@ def update_index *indexes end end - def update_all *except + def update_all(*except) update_index(all_indexes - normalize_indexes(except)) end end diff --git a/lib/chewy/repository.rb b/lib/chewy/repository.rb index ad299d532..29c75a38d 100644 --- a/lib/chewy/repository.rb +++ b/lib/chewy/repository.rb @@ -5,10 +5,10 @@ class Repository attr_reader :analyzers, :tokenizers, :filters, :char_filters def self.delegated - public_instance_methods - self.superclass.public_instance_methods - Singleton.public_instance_methods + public_instance_methods - superclass.public_instance_methods - Singleton.public_instance_methods end - def self.repository name + def self.repository(name) plural_name = name.to_s.pluralize class_eval <<-METHOD, __FILE__, __LINE__ + 1 diff --git a/lib/chewy/rspec.rb b/lib/chewy/rspec.rb index c491de3c6..998298104 100644 --- a/lib/chewy/rspec.rb +++ b/lib/chewy/rspec.rb @@ -1 +1 @@ -require 'chewy/rspec/update_index' \ No newline at end of file +require 'chewy/rspec/update_index' diff --git a/lib/chewy/rspec/update_index.rb b/lib/chewy/rspec/update_index.rb index 976f14341..f0a7cf797 100644 --- a/lib/chewy/rspec/update_index.rb +++ b/lib/chewy/rspec/update_index.rb @@ -21,10 +21,9 @@ # .to update_index(UsersIndex::User).and_reindex(user2).and_delete(user1) } # RSpec::Matchers.define :update_index do |type_name, options = {}| - if !respond_to?(:failure_message) && respond_to?(:failure_message_for_should) - alias :failure_message :failure_message_for_should - alias :failure_message_when_negated :failure_message_for_should_not + alias_method :failure_message, :failure_message_for_should + alias_method :failure_message_when_negated, :failure_message_for_should_not end # Specify indexed records by passing record itself or id. @@ -144,8 +143,8 @@ def supports_block_expectations? end @updated.present? && @missed_reindex.none? && @missed_delete.none? && - @reindex.all? { |_, document| document[:match_count] && document[:match_attributes] } && - @delete.all? { |_, document| document[:match_count] } + @reindex.all? { |_, document| document[:match_count] && document[:match_attributes] } && + @delete.all? { |_, document| document[:match_count] } end failure_message do @@ -176,7 +175,7 @@ def supports_block_expectations? result << "\n #{document[:expected_count]} times, but was reindexed #{document[:real_count]} times" if document[:expected_count] && !document[:match_count] result << "\n with #{document[:expected_attributes]}, but it was reindexed with #{document[:real_attributes]}" if document[:expected_attributes].present? && !document[:match_attributes] else - result << ", but it was not" + result << ', but it was not' end result << "\n" end @@ -188,7 +187,7 @@ def supports_block_expectations? result << if document[:real_count] > 0 && document[:expected_count] "\n #{document[:expected_count]} times, but was deleted #{document[:real_count]} times" else - ", but it was not" + ', but it was not' end result << "\n" end @@ -199,23 +198,21 @@ def supports_block_expectations? failure_message_when_negated do if @updated.present? - "Expected index `#{type_name}` not to be updated, but it was with #{ - @updated.map(&:values).flatten.group_by { |documents| documents[:_id] }.map do |id, documents| - "\n document id `#{id}` (#{documents.count} times)" - end.join - }\n" + "Expected index `#{type_name}` not to be updated, but it was with #{@updated.map(&:values).flatten.group_by { |documents| documents[:_id] }.map do |id, documents| + "\n document id `#{id}` (#{documents.count} times)" + end.join}\n" end end def agnostic_stub if defined?(Mocha) && RSpec.configuration.mock_framework.to_s == 'RSpec::Core::MockingAdapters::Mocha' - "type.stubs(:bulk).with" + 'type.stubs(:bulk).with' else - "allow(type).to receive(:bulk)" + 'allow(type).to receive(:bulk)' end end - def extract_documents *args + def extract_documents(*args) options = args.extract_options! expected_count = options[:times] || options[:count] @@ -233,7 +230,7 @@ def extract_documents *args end] end - def compare_attributes expected, real + def compare_attributes(expected, real) expected.inject(true) do |result, (key, value)| equal = if value.is_a?(Array) && real[key].is_a?(Array) array_difference(value, real[key]) && array_difference(real[key], value) @@ -246,7 +243,7 @@ def compare_attributes expected, real end end - def array_difference first, second + def array_difference(first, second) difference = first.to_ary.dup second.to_ary.each do |element| index = difference.index(element) diff --git a/lib/chewy/runtime/version.rb b/lib/chewy/runtime/version.rb index 43a153e6f..1154ec0dc 100644 --- a/lib/chewy/runtime/version.rb +++ b/lib/chewy/runtime/version.rb @@ -4,21 +4,21 @@ class Version include Comparable attr_reader :major, :minor, :patch - def initialize version - @major, @minor, @patch = *(version.to_s.split('.', 3) + [0]*3).first(3).map(&:to_i) + def initialize(version) + @major, @minor, @patch = *(version.to_s.split('.', 3) + [0] * 3).first(3).map(&:to_i) end def to_s [major, minor, patch].join('.') end - def <=> other + def <=>(other) other = self.class.new(other) unless other.is_a?(self.class) [ major <=> other.major, minor <=> other.minor, patch <=> other.patch - ].detect { |c| c != 0 } || 0 + ].detect(&:nonzero?) || 0 end end end diff --git a/lib/chewy/search.rb b/lib/chewy/search.rb index 1ff220dab..4d7ccbaa0 100644 --- a/lib/chewy/search.rb +++ b/lib/chewy/search.rb @@ -18,11 +18,12 @@ def all query_class.scopes.last || query_class.new(self) end - def search_string query, options = {} + def search_string(query, options = {}) options = options.merge( index: all._indexes.map(&:index_name), type: all._types.map(&:type_name), - q: query) + q: query + ) Chewy.client.search(options) end @@ -42,7 +43,7 @@ def query_class end end - def delegate_scoped source, destination, methods + def delegate_scoped(source, destination, methods) methods.each do |method| destination.class_eval do define_method method do |*args, &block| diff --git a/lib/chewy/strategy.rb b/lib/chewy/strategy.rb index 40b4a81c3..9c405c35c 100644 --- a/lib/chewy/strategy.rb +++ b/lib/chewy/strategy.rb @@ -45,7 +45,7 @@ def current @stack.last end - def push name + def push(name) result = @stack.push resolve(name).new debug "[#{@stack.size}] <- #{current.name}" result @@ -58,7 +58,7 @@ def pop result end - def wrap name + def wrap(name) stack = push(name) yield ensure @@ -67,13 +67,13 @@ def wrap name private - def debug string + def debug(string) return unless Chewy.logger && Chewy.logger.debug? line = caller.detect { |l| l !~ %r{lib/chewy/strategy.rb:|lib/chewy.rb:} } Chewy.logger.debug(["DEBUG: Chewy strategies stack: #{string}", line.sub(/:in\s.+$/, '')].join(' @ ')) end - def resolve name + def resolve(name) "Chewy::Strategy::#{name.to_s.camelize}".safe_constantize or raise "Can't find update strategy `#{name}`" rescue NameError => ex # WORKAROUND: Strange behavior of `safe_constantize` with mongoid gem diff --git a/lib/chewy/strategy/atomic.rb b/lib/chewy/strategy/atomic.rb index 6d6e85dbc..22e477d49 100644 --- a/lib/chewy/strategy/atomic.rb +++ b/lib/chewy/strategy/atomic.rb @@ -16,8 +16,8 @@ def initialize @stash = {} end - def update type, objects, options = {} - ActiveSupport::Deprecation.warn("`urgent: true` option is deprecated and is not effective inside `:atomic` strategy, use `Chewy.strategy(:urgent)` strategy instead") if options.key?(:urgent) + def update(type, objects, options = {}) + ActiveSupport::Deprecation.warn('`urgent: true` option is deprecated and is not effective inside `:atomic` strategy, use `Chewy.strategy(:urgent)` strategy instead') if options.key?(:urgent) @stash[type] ||= [] @stash[type] |= type.send(:build_root).id ? Array.wrap(objects) : type.adapter.identify(objects) diff --git a/lib/chewy/strategy/base.rb b/lib/chewy/strategy/base.rb index 9935021bd..dc58e0563 100644 --- a/lib/chewy/strategy/base.rb +++ b/lib/chewy/strategy/base.rb @@ -11,10 +11,11 @@ class Base def name self.class.name.demodulize.underscore.to_sym end + # This method called when some model tries to update index # - def update type, _objects, _options = {} - raise UndefinedUpdateStrategy.new(type) + def update(type, _objects, _options = {}) + raise UndefinedUpdateStrategy, type end # This method called when strategy pops from the diff --git a/lib/chewy/strategy/bypass.rb b/lib/chewy/strategy/bypass.rb index 112c3dfe0..b578d3270 100644 --- a/lib/chewy/strategy/bypass.rb +++ b/lib/chewy/strategy/bypass.rb @@ -8,7 +8,7 @@ class Strategy # end # class Bypass < Base - def update type, objects, options = {} + def update(type, objects, options = {}) end end end diff --git a/lib/chewy/strategy/urgent.rb b/lib/chewy/strategy/urgent.rb index eb81f2791..52658d53d 100644 --- a/lib/chewy/strategy/urgent.rb +++ b/lib/chewy/strategy/urgent.rb @@ -9,7 +9,7 @@ class Strategy # end # class Urgent < Base - def update type, objects, _options = {} + def update(type, objects, _options = {}) type.import!(Array.wrap(objects)) end end diff --git a/lib/chewy/type.rb b/lib/chewy/type.rb index 031fed48a..93726d800 100644 --- a/lib/chewy/type.rb +++ b/lib/chewy/type.rb @@ -13,7 +13,7 @@ module Chewy class Type - IMPORT_OPTIONS_KEYS = [:batch_size, :bulk_size, :refresh, :consistency, :replication, :raw_import, :journal] + IMPORT_OPTIONS_KEYS = [:batch_size, :bulk_size, :refresh, :consistency, :replication, :raw_import, :journal].freeze include Search include Mapping diff --git a/lib/chewy/type/adapter/active_record.rb b/lib/chewy/type/adapter/active_record.rb index 43c549918..5fff049a2 100644 --- a/lib/chewy/type/adapter/active_record.rb +++ b/lib/chewy/type/adapter/active_record.rb @@ -4,7 +4,6 @@ module Chewy class Type module Adapter class ActiveRecord < Orm - def self.accepts?(target) defined?(::ActiveRecord::Base) && ( target.is_a?(Class) && target < ::ActiveRecord::Base || diff --git a/lib/chewy/type/adapter/base.rb b/lib/chewy/type/adapter/base.rb index 4708721d7..a0f4c1a54 100644 --- a/lib/chewy/type/adapter/base.rb +++ b/lib/chewy/type/adapter/base.rb @@ -9,7 +9,7 @@ class Base # Returns `true` if this adapter is applicable for the given target. # - def self.accepts? _target + def self.accepts?(_target) true end @@ -32,7 +32,7 @@ def type_name # For ORM/ODM it will be an array of ids for simple objects - # just objects themselves # - def identify _collection + def identify(_collection) raise NotImplementedError end @@ -43,7 +43,7 @@ def identify _collection # # Returns true id all the block call returns true and false otherwise # - def import *_args + def import(*_args) raise NotImplementedError end @@ -53,7 +53,7 @@ def import *_args # load(double(id: 1), double(id: 2), double(id: 3)) #=> # # [, nil, ], assuming, #2 was not found # - def load *_args + def load(*_args) raise NotImplementedError end diff --git a/lib/chewy/type/adapter/mongoid.rb b/lib/chewy/type/adapter/mongoid.rb index be819e221..98cc896a3 100644 --- a/lib/chewy/type/adapter/mongoid.rb +++ b/lib/chewy/type/adapter/mongoid.rb @@ -4,14 +4,13 @@ module Chewy class Type module Adapter class Mongoid < Orm - def self.accepts?(target) defined?(::Mongoid::Document) && ( target.is_a?(Class) && target.ancestors.include?(::Mongoid::Document) || target.is_a?(::Mongoid::Criteria)) end - def identify collection + def identify(collection) super(collection).map { |id| id.is_a?(BSON::ObjectId) ? id.to_s : id } end diff --git a/lib/chewy/type/adapter/object.rb b/lib/chewy/type/adapter/object.rb index 3094c2dd8..0f5955541 100644 --- a/lib/chewy/type/adapter/object.rb +++ b/lib/chewy/type/adapter/object.rb @@ -4,7 +4,7 @@ module Chewy class Type module Adapter class Object < Base - def initialize *args + def initialize(*args) @options = args.extract_options! @target = args.first end @@ -13,7 +13,7 @@ def name @name ||= (options[:name] || @target).to_s.camelize.demodulize end - def identify collection + def identify(collection) Array.wrap(collection) end @@ -32,7 +32,7 @@ def identify collection # But to be destroyed objects need to respond to `id` method as well, so # ElasticSearch could know which one to delete. # - def import *args, &block + def import(*args, &block) options = args.extract_options! options[:batch_size] ||= BATCH_SIZE @@ -42,7 +42,7 @@ def import *args, &block import_objects(objects, options, &block) end - def load *args + def load(*args) args.extract_options! objects = args.flatten if target.respond_to?(load_all_method) diff --git a/lib/chewy/type/adapter/orm.rb b/lib/chewy/type/adapter/orm.rb index d5f235675..ef4551ccb 100644 --- a/lib/chewy/type/adapter/orm.rb +++ b/lib/chewy/type/adapter/orm.rb @@ -6,7 +6,7 @@ module Adapter class Orm < Base attr_reader :default_scope - def initialize *args + def initialize(*args) @options = args.extract_options! class_or_relation = args.first if class_or_relation.is_a?(relation_class) @@ -23,7 +23,7 @@ def name @name ||= (options[:name].presence || target.name).to_s.camelize.demodulize end - def identify collection + def identify(collection) if collection.is_a?(relation_class) pluck_ids(collection) else @@ -73,7 +73,7 @@ def identify collection # # or # UsersIndex::User.import users.map(&:id) # user ids will be deleted from index # - def import *args, &block + def import(*args, &block) options = args.extract_options! options[:batch_size] ||= BATCH_SIZE @@ -87,7 +87,7 @@ def import *args, &block end end - def load *args + def load(*args) load_options = args.extract_options! objects = args.flatten @@ -137,7 +137,7 @@ def all_scope target.where(nil) end - def model_of_relation relation + def model_of_relation(relation) relation.klass end diff --git a/lib/chewy/type/adapter/sequel.rb b/lib/chewy/type/adapter/sequel.rb index 1c8082ea1..971c3bbc8 100644 --- a/lib/chewy/type/adapter/sequel.rb +++ b/lib/chewy/type/adapter/sequel.rb @@ -58,7 +58,7 @@ def scope_where_ids_in(scope, ids) scope.where(primary_key_with_table_name => Array.wrap(ids)) end - def model_of_relation relation + def model_of_relation(relation) relation.model end diff --git a/lib/chewy/type/crutch.rb b/lib/chewy/type/crutch.rb index 02dfca7a4..80f620863 100644 --- a/lib/chewy/type/crutch.rb +++ b/lib/chewy/type/crutch.rb @@ -9,8 +9,9 @@ module Crutch end class Crutches - def initialize type, collection - @type, @collection = type, collection + def initialize(type, collection) + @type = type + @collection = collection @type._crutches.keys.each do |name| singleton_class.class_eval <<-METHOD, __FILE__, __LINE__ + 1 def #{name} @@ -22,7 +23,7 @@ def #{name} end module ClassMethods - def crutch name, &block + def crutch(name, &block) self._crutches = _crutches.merge(name.to_sym => block) end end diff --git a/lib/chewy/type/import.rb b/lib/chewy/type/import.rb index 3b2a8fbd1..9f2e04a4e 100644 --- a/lib/chewy/type/import.rb +++ b/lib/chewy/type/import.rb @@ -3,7 +3,7 @@ class Type module Import extend ActiveSupport::Concern - BULK_OPTIONS = [:suffix, :bulk_size, :refresh, :consistency, :replication] + BULK_OPTIONS = [:suffix, :bulk_size, :refresh, :consistency, :replication].freeze module ClassMethods # Perform import operation for specified documents. @@ -23,7 +23,7 @@ module ClassMethods # # See adapters documentation for more details. # - def import *args + def import(*args) import_options = args.extract_options! import_options.reverse_merge! _default_import_options bulk_options = import_options.reject { |k, _| !BULK_OPTIONS.include?(k) }.reverse_merge!(refresh: true) @@ -52,7 +52,7 @@ def import *args # Options are completely the same as for `import` method # See adapters documentation for more details. # - def import! *args + def import!(*args) errors = nil subscriber = ActiveSupport::Notifications.subscribe('import_objects.chewy') do |*notification_args| errors = notification_args.last[:errors] @@ -66,7 +66,7 @@ def import! *args # Wraps elasticsearch-ruby client indices bulk method. # Adds `:suffix` option to bulk import to index with specified suffix. - def bulk options = {} + def bulk(options = {}) suffix = options.delete(:suffix) bulk_size = options.delete(:bulk_size) body = options.delete(:body) @@ -75,14 +75,14 @@ def bulk options = {} bodies = if bulk_size bulk_size -= 1.kilobyte # 1 kilobyte for request header and newlines - raise ArgumentError.new('Import `:bulk_size` can\'t be less than 1 kilobyte') if bulk_size <= 0 + raise ArgumentError, 'Import `:bulk_size` can\'t be less than 1 kilobyte' if bulk_size <= 0 body.each_with_object(['']) do |entry, result| operation, meta = entry.to_a.first data = meta.delete(:data) entry = [{ operation => meta }, data].compact.map(&:to_json).join("\n") - raise ArgumentError.new('Import `:bulk_size` seems to be less than entry size') if entry.bytesize > bulk_size + raise ArgumentError, 'Import `:bulk_size` seems to be less than entry size' if entry.bytesize > bulk_size if result.last.bytesize + entry.bytesize > bulk_size result.push(entry) @@ -169,7 +169,7 @@ def index_bulk_entry(object, indexed_objects = nil, crutches = nil) end end - def fill_payload_import payload, action_objects + def fill_payload_import(payload, action_objects) imported = Hash[action_objects.map { |action, objects| [action, objects.count] }] imported.each do |action, count| payload[:import] ||= {} @@ -178,7 +178,7 @@ def fill_payload_import payload, action_objects end end - def fill_payload_errors payload, import_errors + def fill_payload_errors(payload, import_errors) import_errors.each do |action, action_errors| action_errors.each do |error, documents| payload[:errors] ||= {} @@ -189,7 +189,7 @@ def fill_payload_errors payload, import_errors end end - def object_data object, crutches = nil + def object_data(object, crutches = nil) if witchcraft? cauldron.brew(object, crutches) else @@ -197,7 +197,7 @@ def object_data object, crutches = nil end end - def extract_errors items + def extract_errors(items) items.each.with_object({}) do |item, memo| action = item.keys.first.to_sym data = item.values.first @@ -206,9 +206,9 @@ def extract_errors items end end.map do |action, action_items| errors = action_items.group_by { |item| item[:error] }.map do |error, error_items| - {error => error_items.map { |item| item[:id] }} + { error => error_items.map { |item| item[:id] } } end.reduce(&:merge) - {action => errors} + { action => errors } end.reduce(&:merge) || {} end @@ -223,11 +223,11 @@ def fetch_indexed_objects(objects) indexed_objects = {} - while (result = client.scroll(scroll_id: result['_scroll_id'], scroll: '1m')) do + while (result = client.scroll(scroll_id: result['_scroll_id'], scroll: '1m')) break if result['hits']['hits'].empty? result['hits']['hits'].map do |hit| - parent = hit.has_key?('_parent') ? hit['_parent'] : hit['fields']['_parent'] + parent = hit.key?('_parent') ? hit['_parent'] : hit['fields']['_parent'] indexed_objects[hit['_id']] = { parent: parent } end end diff --git a/lib/chewy/type/mapping.rb b/lib/chewy/type/mapping.rb index cddca4fd0..b95c0e02d 100644 --- a/lib/chewy/type/mapping.rb +++ b/lib/chewy/type/mapping.rb @@ -31,8 +31,8 @@ module ClassMethods # end # end # - def root options = {}, &block - raise "Root is already defined" if root_object + def root(options = {}, &block) + raise 'Root is already defined' if root_object build_root(options, &block) end @@ -109,7 +109,7 @@ def root options = {}, &block # field :sorted, analyzer: 'sorted' # end # - def field *args, &block + def field(*args, &block) options = args.extract_options! build_root @@ -136,7 +136,7 @@ def field *args, &block # end # end # end - def agg name, &block + def agg(name, &block) build_root self._agg_defs = _agg_defs.merge(name => block) end @@ -162,7 +162,7 @@ def agg name, &block # template /tit.+/, 'string', mapping_hash # "match_mapping_type" as the optionsl second argument # template template42: {match: 'hello*', mapping: {type: 'object'}} # or even pass a template as is # - def template *args + def template(*args) build_root.dynamic_template(*args) end alias_method :dynamic_template, :template @@ -175,7 +175,7 @@ def mappings_hash private - def expand_nested field, &block + def expand_nested(field, &block) if @_current_field field.parent = @_current_field @_current_field.children.push(field) @@ -183,12 +183,13 @@ def expand_nested field, &block return unless block - previous_field, @_current_field = @_current_field, field + previous_field = @_current_field + @_current_field = field yield @_current_field = previous_field end - def build_root options = {}, &block + def build_root(options = {}, &block) return root_object if root_object self.root_object = Chewy::Fields::Root.new(type_name, options) expand_nested(root_object, &block) diff --git a/lib/chewy/type/observe.rb b/lib/chewy/type/observe.rb index 2ac5b56d2..161e1732b 100644 --- a/lib/chewy/type/observe.rb +++ b/lib/chewy/type/observe.rb @@ -8,7 +8,7 @@ def update_proc(type_name, *args, &block) options = args.extract_options! method = args.first - Proc.new do + proc do backreference = if method && method.to_s == 'self' self elsif method @@ -18,7 +18,7 @@ def update_proc(type_name, *args, &block) end reference = if type_name.is_a?(Proc) - type_name.arity == 0 ? + type_name.arity.zero? ? instance_exec(&type_name) : type_name.call(self) else @@ -31,11 +31,11 @@ def update_proc(type_name, *args, &block) def extract_callback_options!(args) options = args.extract_options! - options.each_key.with_object({}) { |key, hash| + options.each_key.with_object({}) do |key, hash| hash[key] = options.delete(key) if [:if, :unless].include?(key) - }.tap { + end.tap do args.push(options) unless options.empty? - } + end end end diff --git a/lib/chewy/type/witchcraft.rb b/lib/chewy/type/witchcraft.rb index 96d993262..14b4e0897 100644 --- a/lib/chewy/type/witchcraft.rb +++ b/lib/chewy/type/witchcraft.rb @@ -112,7 +112,7 @@ def non_proc_values(field, nesting) end) RUBY else - "{}" + '{}' end end @@ -128,7 +128,7 @@ def proc_values(field, nesting) } RUBY else - "{}" + '{}' end end @@ -151,7 +151,7 @@ def source_for(proc, nesting) source = lambdas.first proc_params = proc.parameters.map(&:second) - if proc.arity == 0 + if proc.arity.zero? source = replace_self(source, :"object#{nesting}") source = replace_send(source, :"object#{nesting}") elsif proc.arity < 0 diff --git a/lib/chewy/type/wrapper.rb b/lib/chewy/type/wrapper.rb index 3cad86762..d4706a964 100644 --- a/lib/chewy/type/wrapper.rb +++ b/lib/chewy/type/wrapper.rb @@ -35,18 +35,18 @@ def respond_to_missing?(method_name, include_private = false) super end - private + private def attribute_defined?(attribute) self.class.root_object && self.class.root_object.children.find { |a| a.name.to_s == attribute }.present? end def highlight(attribute) - _data["highlight"][attribute].first + _data['highlight'][attribute].first end def highlight?(attribute) - _data.key?("highlight") && _data["highlight"].key?(attribute) + _data.key?('highlight') && _data['highlight'].key?(attribute) end end end diff --git a/lib/chewy/version.rb b/lib/chewy/version.rb index 0668ec891..dc96270c2 100644 --- a/lib/chewy/version.rb +++ b/lib/chewy/version.rb @@ -1,3 +1,3 @@ module Chewy - VERSION = '0.8.4' + VERSION = '0.8.4'.freeze end diff --git a/lib/generators/chewy/install_generator.rb b/lib/generators/chewy/install_generator.rb index 2040a745e..3c144f6de 100644 --- a/lib/generators/chewy/install_generator.rb +++ b/lib/generators/chewy/install_generator.rb @@ -1,11 +1,11 @@ module Chewy module Generators class InstallGenerator < Rails::Generators::Base - source_root File.expand_path("../../templates", __FILE__) + source_root File.expand_path('../../templates', __FILE__) def copy_configuration - template "chewy.yml", "config/chewy.yml" + template 'chewy.yml', 'config/chewy.yml' end end end -end \ No newline at end of file +end diff --git a/lib/tasks/chewy.rake b/lib/tasks/chewy.rake index 7e3abdc94..4986649e3 100644 --- a/lib/tasks/chewy.rake +++ b/lib/tasks/chewy.rake @@ -6,7 +6,7 @@ namespace :chewy do Chewy::RakeHelper.subscribed_task_stats do indexes = args.extras - if indexes.empty? || indexes.first.tr!(?-, '') + if indexes.empty? || indexes.first.tr!('-', '') Chewy::RakeHelper.reset_all(indexes) else Chewy::RakeHelper.reset_index(indexes) @@ -19,7 +19,7 @@ namespace :chewy do Chewy::RakeHelper.subscribed_task_stats do indexes = args.extras - if indexes.empty? || indexes.first.tr!(?-, '') + if indexes.empty? || indexes.first.tr!('-', '') Chewy::RakeHelper.update_all(indexes) else Chewy::RakeHelper.update_index(indexes) diff --git a/spec/chewy/config_spec.rb b/spec/chewy/config_spec.rb index 8d8b9b5c4..bba72267b 100644 --- a/spec/chewy/config_spec.rb +++ b/spec/chewy/config_spec.rb @@ -18,23 +18,35 @@ let(:logger) { Logger.new('/dev/null') } after { subject.transport_logger = nil } - specify { expect { subject.transport_logger = logger } - .to change { Chewy.client.transport.logger }.to(logger) } - specify { expect { subject.transport_logger = logger } - .to change { subject.transport_logger }.to(logger) } - specify { expect { subject.transport_logger = logger } - .to change { subject.configuration[:logger] }.from(nil).to(logger) } + specify do + expect { subject.transport_logger = logger } + .to change { Chewy.client.transport.logger }.to(logger) + end + specify do + expect { subject.transport_logger = logger } + .to change { subject.transport_logger }.to(logger) + end + specify do + expect { subject.transport_logger = logger } + .to change { subject.configuration[:logger] }.from(nil).to(logger) + end end describe '#transport_tracer=' do let(:tracer) { Logger.new('/dev/null') } after { subject.transport_tracer = nil } - specify { expect { subject.transport_tracer = tracer } - .to change { Chewy.client.transport.tracer }.to(tracer) } - specify { expect { subject.transport_tracer = tracer } - .to change { subject.transport_tracer }.to(tracer) } - specify { expect { subject.transport_tracer = tracer } - .to change { subject.configuration[:tracer] }.from(nil).to(tracer) } + specify do + expect { subject.transport_tracer = tracer } + .to change { Chewy.client.transport.tracer }.to(tracer) + end + specify do + expect { subject.transport_tracer = tracer } + .to change { subject.transport_tracer }.to(tracer) + end + specify do + expect { subject.transport_tracer = tracer } + .to change { subject.configuration[:tracer] }.from(nil).to(tracer) + end end end diff --git a/spec/chewy/fields/base_spec.rb b/spec/chewy/fields/base_spec.rb index ff7292adc..dfe060e76 100644 --- a/spec/chewy/fields/base_spec.rb +++ b/spec/chewy/fields/base_spec.rb @@ -5,37 +5,40 @@ specify { expect(described_class.new('name', type: 'integer').options[:type]).to eq('integer') } describe '#compose' do - let(:field) { described_class.new(:name, value: ->(o){ o.value }) } + let(:field) { described_class.new(:name, value: ->(o) { o.value }) } - specify { expect(field.compose(double(value: 'hello'))).to eq({name: 'hello'}) } - specify { expect(field.compose(double(value: ['hello', 'world']))).to eq({name: ['hello', 'world']}) } - - specify { expect(described_class.new(:name).compose(double(name: 'hello'))).to eq({name: 'hello'}) } - specify { expect(described_class.new(:false_value).compose({false_value: false})).to eq({false_value: false}) } - specify { expect(described_class.new(:true_value).compose({true_value: true})).to eq({true_value: true}) } - specify { expect(described_class.new(:nil_value).compose({nil_value: nil})).to eq({nil_value: nil}) } + specify { expect(field.compose(double(value: 'hello'))).to eq(name: 'hello') } + specify { expect(field.compose(double(value: %w(hello world)))).to eq(name: %w(hello world)) } + specify { expect(described_class.new(:name).compose(double(name: 'hello'))).to eq(name: 'hello') } + specify { expect(described_class.new(:false_value).compose(false_value: false)).to eq(false_value: false) } + specify { expect(described_class.new(:true_value).compose(true_value: true)).to eq(true_value: true) } + specify { expect(described_class.new(:nil_value).compose(nil_value: nil)).to eq(nil_value: nil) } context 'nested fields' do before do - field.children.push(described_class.new(:subname1, value: ->(o){ o.subvalue1 })) - field.children.push(described_class.new(:subname2, value: ->{ subvalue2 })) + field.children.push(described_class.new(:subname1, value: ->(o) { o.subvalue1 })) + field.children.push(described_class.new(:subname2, value: -> { subvalue2 })) field.children.push(described_class.new(:subname3)) end - specify { expect(field.compose(double(value: double(subvalue1: 'hello', subvalue2: 'value', subname3: 'world')))) - .to eq({name: {subname1: 'hello', subname2: 'value', subname3: 'world'}}) } - specify { expect(field.compose(double(value: [ - double(subvalue1: 'hello1', subvalue2: 'value1', subname3: 'world1'), - double(subvalue1: 'hello2', subvalue2: 'value2', subname3: 'world2') - ]))).to eq({name: [ - {subname1: 'hello1', subname2: 'value1', subname3: 'world1'}, - {subname1: 'hello2', subname2: 'value2', subname3: 'world2'} - ]}) } + specify do + expect(field.compose(double(value: double(subvalue1: 'hello', subvalue2: 'value', subname3: 'world')))) + .to eq(name: { subname1: 'hello', subname2: 'value', subname3: 'world' }) + end + specify do + expect(field.compose(double(value: [ + double(subvalue1: 'hello1', subvalue2: 'value1', subname3: 'world1'), + double(subvalue1: 'hello2', subvalue2: 'value2', subname3: 'world2') + ]))).to eq(name: [ + { subname1: 'hello1', subname2: 'value1', subname3: 'world1' }, + { subname1: 'hello2', subname2: 'value2', subname3: 'world2' } + ]) + end end context 'parent objects' do - let!(:country) { described_class.new(:name, value: ->(country){ country.cities }) } + let!(:country) { described_class.new(:name, value: ->(country) { country.cities }) } let!(:city) { described_class.new(:name, value: ->(city, country) { city.districts.map { |district| [district, country.name] } }) } let!(:district) { described_class.new(:name, value: ->(district, city, country) { [district, city.name, country.name] }) } @@ -44,14 +47,16 @@ city.children.push(district) end - specify { expect(country.compose(double(name: 'Thailand', cities: [ - double(name: 'Bangkok', districts: ['First', 'Second']) - ]))).to eq(name: [ - { name: [ - { name: [['First', 'Thailand'], 'Bangkok', 'Thailand'] }, - { name: [['Second', 'Thailand'], 'Bangkok', 'Thailand'] } - ] } - ]) } + specify do + expect(country.compose(double(name: 'Thailand', cities: [ + double(name: 'Bangkok', districts: %w(First Second)) + ]))).to eq(name: [ + { name: [ + { name: [%w(First Thailand), 'Bangkok', 'Thailand'] }, + { name: [%w(Second Thailand), 'Bangkok', 'Thailand'] } + ] } + ]) + end end context 'implicit values' do @@ -61,46 +66,50 @@ field.children.push(described_class.new(:untouched)) end - specify { expect(field.compose(double(name: 'Alex'))).to eq({name: 'Alex'}) } + specify { expect(field.compose(double(name: 'Alex'))).to eq(name: 'Alex') } end context 'hash values' do let(:field) { described_class.new(:name, type: 'object') } - let(:object) { double(name: { key1: 'value1', key2: 'value2'}) } + let(:object) { double(name: { key1: 'value1', key2: 'value2' }) } before do - field.children.push(described_class.new(:key1, value: ->(h){ h[:key1] })) - field.children.push(described_class.new(:key2, value: ->(h){ h[:key2] })) + field.children.push(described_class.new(:key1, value: ->(h) { h[:key1] })) + field.children.push(described_class.new(:key2, value: ->(h) { h[:key2] })) end - specify{ expect(field.compose(object)).to eq({ name: { key1: 'value1', key2: 'value2'} }) } + specify { expect(field.compose(object)).to eq(name: { key1: 'value1', key2: 'value2' }) } end end describe '#mappings_hash' do let(:field) { described_class.new(:name, type: :object) } - let(:fields1) { Array.new(2) { |i| described_class.new("name#{i+1}", type: "string#{i+1}") } } - let(:fields2) { Array.new(2) { |i| described_class.new("name#{i+3}", type: "string#{i+3}") } } + let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}", type: "string#{i + 1}") } } + let(:fields2) { Array.new(2) { |i| described_class.new("name#{i + 3}", type: "string#{i + 3}") } } before do fields1.each { |m| field.children.push(m) } fields2.each { |m| fields1[0].children.push(m) } end - specify { expect(field.mappings_hash).to eq({name: {type: :object, properties: { - name1: {type: 'string1', fields: { - name3: {type: 'string3'}, name4: {type: 'string4'} - }}, name2: {type: 'string2'} - }}}) } + specify do + expect(field.mappings_hash).to eq(name: { type: :object, properties: { + name1: { type: 'string1', fields: { + name3: { type: 'string3' }, name4: { type: 'string4' } + } }, name2: { type: 'string2' } + } }) + end context do let(:field) { described_class.new(:name, type: :string) } - let(:fields1) { Array.new(2) { |i| described_class.new("name#{i+1}") } } + let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}") } } - specify { expect(field.mappings_hash).to eq({name: {type: :string, fields: { - name1: {type: 'object', properties: { - name3: {type: 'string3'}, name4: {type: 'string4'} - }}, name2: {type: 'string'} - }}}) } + specify do + expect(field.mappings_hash).to eq(name: { type: :string, fields: { + name1: { type: 'object', properties: { + name3: { type: 'string3' }, name4: { type: 'string4' } + } }, name2: { type: 'string' } + } }) + end end end @@ -122,48 +131,48 @@ end specify do - expect(EventsIndex::Event.mappings_hash).to eq({ event: { - properties: { - id: { type: 'string' }, - category: { - type: 'object', - properties: { - id: { type: 'string' }, - licenses: { - type: 'object', - properties: { - id: { type: 'string' }, - name: { type: 'string' } } } } } } } }) + expect(EventsIndex::Event.mappings_hash).to eq(event: { + properties: { + id: { type: 'string' }, + category: { + type: 'object', + properties: { + id: { type: 'string' }, + licenses: { + type: 'object', + properties: { + id: { type: 'string' }, + name: { type: 'string' } + } + } + } + } + } + }) end specify do expect(EventsIndex::Event.root_object.compose( - id: 1, category: { id: 2, licenses: { id: 3, name: 'Name' } } - )).to eq({ - 'event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}}} - }) + id: 1, category: { id: 2, licenses: { id: 3, name: 'Name' } } + )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } }) end specify do expect(EventsIndex::Event.root_object.compose(id: 1, category: [ { id: 2, 'licenses' => { id: 3, name: 'Name1' } }, - { id: 4, licenses: nil} - ])).to eq({ - 'event' => { 'id' => 1, 'category' => [ - { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } }, - {'id' => 4, 'licenses' => nil.as_json } - ] } - }) + { id: 4, licenses: nil } + ])).to eq('event' => { 'id' => 1, 'category' => [ + { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } }, + { 'id' => 4, 'licenses' => nil.as_json } + ] }) end specify do expect(EventsIndex::Event.root_object.compose('id' => 1, category: { id: 2, licenses: [ { id: 3, name: 'Name1' }, { id: 4, name: 'Name2' } - ] })).to eq({ - 'event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [ - {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'} - ] } } - }) + ] })).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [ + { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } + ] } }) end specify do @@ -172,44 +181,36 @@ { id: 3, 'name' => 'Name1' }, { id: 4, name: 'Name2' } ] }, { id: 5, licenses: [] } - ])).to eq({ - 'event' => { 'id' => 1, 'category' => [ - { 'id' => 2, 'licenses' => [ - { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } - ] }, - {'id' => 5, 'licenses' => [] } - ] } - }) + ])).to eq('event' => { 'id' => 1, 'category' => [ + { 'id' => 2, 'licenses' => [ + { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } + ] }, + { 'id' => 5, 'licenses' => [] } + ] }) end specify do expect(EventsIndex::Event.root_object.compose( - double(id: 1, category: double(id: 2, licenses: double(id: 3, name: 'Name'))) - )).to eq({ - 'event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}}} - }) + double(id: 1, category: double(id: 2, licenses: double(id: 3, name: 'Name'))) + )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } }) end specify do expect(EventsIndex::Event.root_object.compose(double(id: 1, category: [ double(id: 2, licenses: double(id: 3, name: 'Name1')), double(id: 4, licenses: nil) - ]))).to eq({ - 'event' => { 'id' => 1, 'category' => [ - { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } }, - {'id' => 4, 'licenses' => nil.as_json } - ] } - }) + ]))).to eq('event' => { 'id' => 1, 'category' => [ + { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name1' } }, + { 'id' => 4, 'licenses' => nil.as_json } + ] }) end specify do expect(EventsIndex::Event.root_object.compose(double(id: 1, category: double(id: 2, licenses: [ double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2') - ])))).to eq({ - 'event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [ - {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'} - ] } } - }) + ])))).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => [ + { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } + ] } }) end specify do @@ -218,14 +219,12 @@ double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2') ]), double(id: 5, licenses: []) - ]))).to eq({ - 'event' => { 'id' => 1, 'category' => [ - { 'id' => 2, 'licenses' => [ - { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } - ] }, - {'id' => 5, 'licenses' => [] } - ] } - }) + ]))).to eq('event' => { 'id' => 1, 'category' => [ + { 'id' => 2, 'licenses' => [ + { 'id' => 3, 'name' => 'Name1' }, { 'id' => 4, 'name' => 'Name2' } + ] }, + { 'id' => 5, 'licenses' => [] } + ] }) end end @@ -234,9 +233,9 @@ stub_index(:events) do define_type :event do field :id - field :category, value: ->{ categories } do + field :category, value: -> { categories } do field :id - field :licenses, value: ->{ license } do + field :licenses, value: -> { license } do field :id field :name end @@ -247,10 +246,8 @@ specify do expect(EventsIndex::Event.root_object.compose( - double(id: 1, categories: double(id: 2, license: double(id: 3, name: 'Name'))) - )).to eq({ - 'event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}}} - }) + double(id: 1, categories: double(id: 2, license: double(id: 3, name: 'Name'))) + )).to eq('event' => { 'id' => 1, 'category' => { 'id' => 2, 'licenses' => { 'id' => 3, 'name' => 'Name' } } }) end end @@ -268,48 +265,44 @@ end specify do - expect(EventsIndex::Event.mappings_hash).to eq({ event: { - properties: { - id: { type: 'string' }, - name: { - type: 'string', - fields: { - raw: { analyzer: 'my_own', type: 'string' } - } - }, - category: { type: 'object' } - } - } }) + expect(EventsIndex::Event.mappings_hash).to eq(event: { + properties: { + id: { type: 'string' }, + name: { + type: 'string', + fields: { + raw: { analyzer: 'my_own', type: 'string' } + } + }, + category: { type: 'object' } + } + }) end specify do expect(EventsIndex::Event.root_object.compose( - double(id: 1, name: 'Jonny', category: double(id: 2, as_json: {'name' => 'Borogoves'})) - )).to eq({ - 'event' => { - 'id' => 1, - 'name' => 'Jonny', - 'category' => { 'name' => 'Borogoves' } - } - }) + double(id: 1, name: 'Jonny', category: double(id: 2, as_json: { 'name' => 'Borogoves' })) + )).to eq('event' => { + 'id' => 1, + 'name' => 'Jonny', + 'category' => { 'name' => 'Borogoves' } + }) end specify do expect(EventsIndex::Event.root_object.compose( - double(id: 1, name: 'Jonny', category: [ - double(id: 2, as_json: { 'name' => 'Borogoves1' }), - double(id: 3, as_json: { 'name' => 'Borogoves2' }) - ]) - )).to eq({ - 'event' => { - 'id' => 1, - 'name' => 'Jonny', - 'category' => [ - { 'name' => 'Borogoves1' }, - { 'name' => 'Borogoves2' } - ] - } - }) + double(id: 1, name: 'Jonny', category: [ + double(id: 2, as_json: { 'name' => 'Borogoves1' }), + double(id: 3, as_json: { 'name' => 'Borogoves2' }) + ]) + )).to eq('event' => { + 'id' => 1, + 'name' => 'Jonny', + 'category' => [ + { 'name' => 'Borogoves1' }, + { 'name' => 'Borogoves2' } + ] + }) end end @@ -358,11 +351,9 @@ end specify do - expect(CountriesIndex::Country.root_object.compose(country_with_cities)).to eq({ - 'country' => { 'id' => 1, 'cities' => [ - { 'id' => 1, 'name' => 'City1' }, { 'id' => 2, 'name' => 'City2' } - ] } - }) + expect(CountriesIndex::Country.root_object.compose(country_with_cities)).to eq('country' => { 'id' => 1, 'cities' => [ + { 'id' => 1, 'name' => 'City1' }, { 'id' => 2, 'name' => 'City2' } + ] }) end context 'nested object' do @@ -380,10 +371,8 @@ specify do expect(CitiesIndex::City.root_object.compose( - City.create!(id: 1, country: Country.create!(id: 1, name: 'Country')) - )).to eq({ - 'city' => { 'id' => 1, 'country' => { 'id' => 1, 'name' => 'Country' } } - }) + City.create!(id: 1, country: Country.create!(id: 1, name: 'Country')) + )).to eq('city' => { 'id' => 1, 'country' => { 'id' => 1, 'name' => 'Country' } }) end end end diff --git a/spec/chewy/fields/root_spec.rb b/spec/chewy/fields/root_spec.rb index 99daa6627..8f3ee3541 100644 --- a/spec/chewy/fields/root_spec.rb +++ b/spec/chewy/fields/root_spec.rb @@ -13,31 +13,33 @@ field.dynamic_template 'hello.*' field.dynamic_template(/hello/) field.dynamic_template(/hello.*/) - field.dynamic_template template_42: {mapping: {}, match: ''} + field.dynamic_template template_42: { mapping: {}, match: '' } field.dynamic_template(/hello\..*/) - expect(field.mappings_hash).to eq({product: {dynamic_templates: [ - {template_1: {mapping: {type: 'string'}, match: 'hello'}}, - {template_2: {mapping: {}, match_mapping_type: 'integer', match: 'hello*'}}, - {template_3: {mapping: {}, path_match: 'hello.*'}}, - {template_4: {mapping: {}, match: 'hello', match_pattern: 'regexp'}}, - {template_5: {mapping: {}, match: 'hello.*', match_pattern: 'regexp'}}, - {template_42: {mapping: {}, match: ''}}, - {template_7: {mapping: {}, path_match: 'hello\..*', match_pattern: 'regexp'}} - ]}}) + expect(field.mappings_hash).to eq(product: { dynamic_templates: [ + { template_1: { mapping: { type: 'string' }, match: 'hello' } }, + { template_2: { mapping: {}, match_mapping_type: 'integer', match: 'hello*' } }, + { template_3: { mapping: {}, path_match: 'hello.*' } }, + { template_4: { mapping: {}, match: 'hello', match_pattern: 'regexp' } }, + { template_5: { mapping: {}, match: 'hello.*', match_pattern: 'regexp' } }, + { template_42: { mapping: {}, match: '' } }, + { template_7: { mapping: {}, path_match: 'hello\..*', match_pattern: 'regexp' } } + ] }) end context do - subject(:field) { described_class.new('product', dynamic_templates: [ - {template_42: {mapping: {}, match: ''}} - ]) } + subject(:field) do + described_class.new('product', dynamic_templates: [ + { template_42: { mapping: {}, match: '' } } + ]) + end specify do field.dynamic_template 'hello', type: 'string' - expect(field.mappings_hash).to eq({product: {dynamic_templates: [ - {template_42: {mapping: {}, match: ''}}, - {template_1: {mapping: {type: 'string'}, match: 'hello'}} - ]}}) + expect(field.mappings_hash).to eq(product: { dynamic_templates: [ + { template_42: { mapping: {}, match: '' } }, + { template_1: { mapping: { type: 'string' }, match: 'hello' } } + ] }) end end end diff --git a/spec/chewy/fields/time_fields_spec.rb b/spec/chewy/fields/time_fields_spec.rb index 0cc1f2608..19459fcff 100644 --- a/spec/chewy/fields/time_fields_spec.rb +++ b/spec/chewy/fields/time_fields_spec.rb @@ -11,17 +11,19 @@ end end - before { PostsIndex::Post.import( - double(published_at: ActiveSupport::TimeZone[-28800].parse('2014/12/18 19:00')), - double(published_at: ActiveSupport::TimeZone[-21600].parse('2014/12/18 20:00')), - double(published_at: ActiveSupport::TimeZone[-21600].parse('2014/12/17 20:00')), - ) } + before do + PostsIndex::Post.import( + double(published_at: ActiveSupport::TimeZone[-28_800].parse('2014/12/18 19:00')), + double(published_at: ActiveSupport::TimeZone[-21_600].parse('2014/12/18 20:00')), + double(published_at: ActiveSupport::TimeZone[-21_600].parse('2014/12/17 20:00')) + ) + end - let(:time) { ActiveSupport::TimeZone[-14400].parse('2014/12/18 22:00') } + let(:time) { ActiveSupport::TimeZone[-14_400].parse('2014/12/18 22:00') } let(:range) { (time - 1.minute)..(time + 1.minute) } specify { expect(PostsIndex.total).to eq(3) } - specify { expect(PostsIndex.filter { published_at == o{range} }.count).to eq(1) } - specify { expect(PostsIndex.filter { published_at == o{range.min.utc..(range.max + 1.hour).utc} }.count).to eq(2) } - specify { expect(PostsIndex.filter { published_at == o{[range.min..range.max]} }.count).to eq(1) } + specify { expect(PostsIndex.filter { published_at == o { range } }.count).to eq(1) } + specify { expect(PostsIndex.filter { published_at == o { range.min.utc..(range.max + 1.hour).utc } }.count).to eq(2) } + specify { expect(PostsIndex.filter { published_at == o { [range.min..range.max] } }.count).to eq(1) } end diff --git a/spec/chewy/index/actions_spec.rb b/spec/chewy/index/actions_spec.rb index a027595f6..3c644f1cc 100644 --- a/spec/chewy/index/actions_spec.rb +++ b/spec/chewy/index/actions_spec.rb @@ -35,7 +35,7 @@ context do before { DummiesIndex.create '2014' } - specify { expect(DummiesIndex.indexes).to match_array(['dummies_2013', 'dummies_2014']) } + specify { expect(DummiesIndex.indexes).to match_array(%w(dummies_2013 dummies_2014)) } end end @@ -83,7 +83,7 @@ context do before { DummiesIndex.create! '2014' } - specify { expect(DummiesIndex.indexes).to match_array(['dummies_2013', 'dummies_2014']) } + specify { expect(DummiesIndex.indexes).to match_array(%w(dummies_2013 dummies_2014)) } end end diff --git a/spec/chewy/index/aliases_spec.rb b/spec/chewy/index/aliases_spec.rb index 3c17ca5a2..5d96eabc3 100644 --- a/spec/chewy/index/aliases_spec.rb +++ b/spec/chewy/index/aliases_spec.rb @@ -22,7 +22,7 @@ context do before { DummiesIndex.create! '2013' } before { DummiesIndex.create! '2014' } - specify { expect(DummiesIndex.indexes).to match_array(['dummies_2013', 'dummies_2014']) } + specify { expect(DummiesIndex.indexes).to match_array(%w(dummies_2013 dummies_2014)) } end end @@ -38,7 +38,7 @@ before { DummiesIndex.create! } before { Chewy.client.indices.put_alias index: 'dummies', name: 'dummies_2013' } before { Chewy.client.indices.put_alias index: 'dummies', name: 'dummies_2014' } - specify { expect(DummiesIndex.aliases).to match_array(['dummies_2013', 'dummies_2014']) } + specify { expect(DummiesIndex.aliases).to match_array(%w(dummies_2013 dummies_2014)) } end context do diff --git a/spec/chewy/index/settings_spec.rb b/spec/chewy/index/settings_spec.rb index a7c0f9db1..2ae86daf9 100644 --- a/spec/chewy/index/settings_spec.rb +++ b/spec/chewy/index/settings_spec.rb @@ -6,77 +6,99 @@ before { allow(Chewy).to receive_messages(repository: Chewy::Repository.send(:new)) } specify { expect(described_class.new.to_hash).to eq({}) } - specify { expect(described_class.new(number_of_nodes: 3).to_hash).to eq({settings: {number_of_nodes: 3}}) } - specify { expect(described_class.new(number_of_nodes: 3, analysis: {}).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: {}}}) } - specify { expect(described_class.new(number_of_nodes: 3, analysis: {filter: {filter1: {}}}).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: {filter: {filter1: {}}}}}) } - specify { expect(described_class.new(number_of_nodes: 3, analysis: {analyzer: {analyzer1: {}}}).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: {analyzer: {analyzer1: {}}}}}) } - specify { expect(described_class.new(number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}} - }).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}} - }}}) } - specify { expect(described_class.new(number_of_nodes: 3, analysis: {analyser: ['analyzer1']}).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: {}}}) } + specify { expect(described_class.new(number_of_nodes: 3).to_hash).to eq(settings: { number_of_nodes: 3 }) } + specify do + expect(described_class.new(number_of_nodes: 3, analysis: {}).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: {} }) + end + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { filter: { filter1: {} } }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { filter: { filter1: {} } } }) + end + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { analyzer: { analyzer1: {} } }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { analyzer: { analyzer1: {} } } }) + end + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } } + }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } } + } }) + end + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { analyser: ['analyzer1'] }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: {} }) + end context do - before { Chewy.tokenizer :tokenizer1, {options: 42} } + before { Chewy.tokenizer :tokenizer1, options: 42 } - specify { expect(described_class.new(number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}} - }).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}}, - tokenizer: {tokenizer1: {options: 42}} - }}}) } + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } } + }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } }, + tokenizer: { tokenizer1: { options: 42 } } + } }) + end end context do before do - Chewy.filter :filter2, {options: 42} - Chewy.filter :filter3, {options: 43} - Chewy.filter :filter5, {options: 44} + Chewy.filter :filter2, options: 42 + Chewy.filter :filter3, options: 43 + Chewy.filter :filter5, options: 44 end - specify { expect(described_class.new(number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}}, - filter: ['filter3', {filter4: {options: 45}}] - }).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {tokenizer: 'tokenizer1', filter: ['filter1', 'filter2']}}, - filter: {filter2: {options: 42}, filter3: {options: 43}, filter4: {options: 45}} - }}}) } + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } }, + filter: ['filter3', { filter4: { options: 45 } }] + }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { tokenizer: 'tokenizer1', filter: %w(filter1 filter2) } }, + filter: { filter2: { options: 42 }, filter3: { options: 43 }, filter4: { options: 45 } } + } }) + end end context do before do - Chewy.analyzer :analyzer1, {options: 42, tokenizer: 'tokenizer1'} - Chewy.tokenizer :tokenizer1, {options: 43} + Chewy.analyzer :analyzer1, options: 42, tokenizer: 'tokenizer1' + Chewy.tokenizer :tokenizer1, options: 43 end - specify { expect(described_class.new(number_of_nodes: 3, analysis: { - analyzer: ['analyzer1', {analyzer2: {options: 44}}] - }).to_hash) - .to eq({settings: {number_of_nodes: 3, analysis: { - analyzer: {analyzer1: {options: 42, tokenizer: 'tokenizer1'}, analyzer2: {options: 44}}, - tokenizer: {tokenizer1: {options: 43}} - }}}) } + specify do + expect(described_class.new(number_of_nodes: 3, analysis: { + analyzer: ['analyzer1', { analyzer2: { options: 44 } }] + }).to_hash) + .to eq(settings: { number_of_nodes: 3, analysis: { + analyzer: { analyzer1: { options: 42, tokenizer: 'tokenizer1' }, analyzer2: { options: 44 } }, + tokenizer: { tokenizer1: { options: 43 } } + } }) + end end context ':index' do - specify { expect(described_class.new(index: {number_of_shards: 3}).to_hash) - .to eq({settings: {index: {number_of_shards: 3}}}) } + specify do + expect(described_class.new(index: { number_of_shards: 3 }).to_hash) + .to eq(settings: { index: { number_of_shards: 3 } }) + end context do - before { allow(Chewy).to receive_messages(configuration: {index: {number_of_shards: 7, number_of_replicas: 2}}) } + before { allow(Chewy).to receive_messages(configuration: { index: { number_of_shards: 7, number_of_replicas: 2 } }) } - specify { expect(described_class.new.to_hash) - .to eq({settings: {index: {number_of_shards: 7, number_of_replicas: 2}}}) } - specify { expect(described_class.new(index: {number_of_shards: 3}).to_hash) - .to eq({settings: {index: {number_of_shards: 3, number_of_replicas: 2}}}) } + specify do + expect(described_class.new.to_hash) + .to eq(settings: { index: { number_of_shards: 7, number_of_replicas: 2 } }) + end + specify do + expect(described_class.new(index: { number_of_shards: 3 }).to_hash) + .to eq(settings: { index: { number_of_shards: 3, number_of_replicas: 2 } }) + end end end end diff --git a/spec/chewy/index_spec.rb b/spec/chewy/index_spec.rb index a367dbcbf..1726cda9a 100644 --- a/spec/chewy/index_spec.rb +++ b/spec/chewy/index_spec.rb @@ -62,14 +62,14 @@ specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name).to eq('developers') } context do - before { allow(Chewy).to receive_messages(configuration: {prefix: 'testing'}) } + before { allow(Chewy).to receive_messages(configuration: { prefix: 'testing' }) } specify { expect(DummiesIndex.index_name).to eq('testing_dummies') } specify { expect(stub_index(:dummies) { index_name :users }.index_name).to eq('testing_users') } end end describe '.default_prefix' do - before { allow(Chewy).to receive_messages(configuration: {prefix: 'testing'}) } + before { allow(Chewy).to receive_messages(configuration: { prefix: 'testing' }) } specify { expect(Class.new(Chewy::Index).default_prefix).to eq('testing') } end @@ -92,25 +92,25 @@ before { stub_class('City::District', City) } specify do - expect { + expect do Kernel.eval <<-DUMMY_CITY_INDEX class DummyCityIndex < Chewy::Index define_type City define_type City::District end DUMMY_CITY_INDEX - }.not_to raise_error + end.not_to raise_error end specify do - expect { + expect do Kernel.eval <<-DUMMY_CITY_INDEX class DummyCityIndex2 < Chewy::Index define_type City define_type City::Nothing end DUMMY_CITY_INDEX - }.to raise_error(NameError) + end.to raise_error(NameError) end end @@ -153,24 +153,26 @@ def self.city before do allow(Chewy).to receive_messages(config: Chewy::Config.send(:new)) - Chewy.analyzer :name, filter: ['lowercase', 'icu_folding', 'names_nysiis'] + Chewy.analyzer :name, filter: %w(lowercase icu_folding names_nysiis) Chewy.analyzer :phone, tokenizer: 'ngram', char_filter: ['phone'] Chewy.tokenizer :ngram, type: 'nGram', min_gram: 3, max_gram: 3 Chewy.char_filter :phone, type: 'pattern_replace', pattern: '[^\d]', replacement: '' Chewy.filter :names_nysiis, type: 'phonetic', encoder: 'nysiis', replace: false end - let(:documents) { stub_index(:documents) { settings analysis: {analyzer: [:name, :phone, {sorted: {option: :baz}}]} } } - - specify { expect { documents.settings_hash }.to_not change(documents._settings, :inspect) } - specify { expect(documents.settings_hash).to eq({settings: {analysis: { - analyzer: {name: {filter: ['lowercase', 'icu_folding', 'names_nysiis']}, - phone: {tokenizer: 'ngram', char_filter: ['phone']}, - sorted: {option: :baz}}, - tokenizer: {ngram: {type: 'nGram', min_gram: 3, max_gram: 3}}, - char_filter: {phone: {type: 'pattern_replace', pattern: '[^\d]', replacement: ''}}, - filter: {names_nysiis: {type: 'phonetic', encoder: 'nysiis', replace: false}} - }}}) } + let(:documents) { stub_index(:documents) { settings analysis: { analyzer: [:name, :phone, { sorted: { option: :baz } }] } } } + + specify { expect { documents.settings_hash }.to_not change(documents._settings, :inspect) } + specify do + expect(documents.settings_hash).to eq(settings: { analysis: { + analyzer: { name: { filter: %w(lowercase icu_folding names_nysiis) }, + phone: { tokenizer: 'ngram', char_filter: ['phone'] }, + sorted: { option: :baz } }, + tokenizer: { ngram: { type: 'nGram', min_gram: 3, max_gram: 3 } }, + char_filter: { phone: { type: 'pattern_replace', pattern: '[^\d]', replacement: '' } }, + filter: { names_nysiis: { type: 'phonetic', encoder: 'nysiis', replace: false } } + } }) + end end describe '.scopes' do @@ -205,25 +207,29 @@ def self.by_id before { allow(Chewy).to receive_messages(config: Chewy::Config.send(:new)) } specify { expect(stub_index(:documents).settings_hash).to eq({}) } - specify { expect(stub_index(:documents) { settings number_of_shards: 1 }.settings_hash).to eq({settings: {number_of_shards: 1}}) } + specify { expect(stub_index(:documents) { settings number_of_shards: 1 }.settings_hash).to eq(settings: { number_of_shards: 1 }) } end describe '.mappings_hash' do specify { expect(stub_index(:documents).mappings_hash).to eq({}) } specify { expect(stub_index(:documents) { define_type :document }.mappings_hash).to eq({}) } - specify { expect(stub_index(:documents) do - define_type :document do - field :name, type: 'string' - end - end.mappings_hash).to eq({mappings: {document: {properties: {name: {type: 'string'}}}}}) } - specify { expect(stub_index(:documents) do - define_type :document do - field :name, type: 'string' - end - define_type :document2 do - field :name, type: 'string' - end - end.mappings_hash[:mappings].keys).to match_array([:document, :document2]) } + specify do + expect(stub_index(:documents) do + define_type :document do + field :name, type: 'string' + end + end.mappings_hash).to eq(mappings: { document: { properties: { name: { type: 'string' } } } }) + end + specify do + expect(stub_index(:documents) do + define_type :document do + field :name, type: 'string' + end + define_type :document2 do + field :name, type: 'string' + end + end.mappings_hash[:mappings].keys).to match_array([:document, :document2]) + end end describe '.index_params' do @@ -231,24 +237,28 @@ def self.by_id specify { expect(stub_index(:documents).index_params).to eq({}) } specify { expect(stub_index(:documents) { settings number_of_shards: 1 }.index_params.keys).to eq([:settings]) } - specify { expect(stub_index(:documents) do - define_type :document do - field :name, type: 'string' - end - end.index_params.keys).to eq([:mappings]) } - specify { expect(stub_index(:documents) do - settings number_of_shards: 1 - define_type :document do - field :name, type: 'string' - end - end.index_params.keys).to match_array([:mappings, :settings]) } + specify do + expect(stub_index(:documents) do + define_type :document do + field :name, type: 'string' + end + end.index_params.keys).to eq([:mappings]) + end + specify do + expect(stub_index(:documents) do + settings number_of_shards: 1 + define_type :document do + field :name, type: 'string' + end + end.index_params.keys).to match_array([:mappings, :settings]) + end end describe '.journal?' do specify { expect(stub_index(:documents).journal?).to eq false } context do - before { allow(Chewy).to receive_messages(configuration: {journal: true}) } + before { allow(Chewy).to receive_messages(configuration: { journal: true }) } specify { expect(stub_index(:documents).journal?).to eq false } end @@ -263,7 +273,7 @@ def self.by_id specify { expect(index.journal?).to eq false } context do - before { allow(Chewy).to receive_messages(configuration: {journal: true}) } + before { allow(Chewy).to receive_messages(configuration: { journal: true }) } specify { expect(index.journal?).to eq true } end end diff --git a/spec/chewy/minitest/helpers_spec.rb b/spec/chewy/minitest/helpers_spec.rb index de09e8f38..6b91d4877 100644 --- a/spec/chewy/minitest/helpers_spec.rb +++ b/spec/chewy/minitest/helpers_spec.rb @@ -6,7 +6,7 @@ class << self alias_method :teardown, :after end - def assert_includes haystack, needle, _comment + def assert_includes(haystack, needle, _comment) expect(haystack).to include(needle) end @@ -19,45 +19,45 @@ def assert_includes haystack, needle, _comment before do stub_index(:dummies) do define_type :dummy do - root value: ->(_o){{}} + root value: ->(_o) { {} } end end end context 'assert_indexes' do specify 'doesn\'t fail when index updates correctly' do - expect { + expect do assert_indexes DummiesIndex::Dummy do - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] end - }.to_not raise_error + end.to_not raise_error end specify 'fails when index doesn\'t update' do - expect { + expect do assert_indexes DummiesIndex::Dummy do end - }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + end.to raise_error(RSpec::Expectations::ExpectationNotMetError) end specify 'SearchIndexReceiver catches the indexes' do receiver = assert_indexes DummiesIndex::Dummy do - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] end expect(receiver).to be_a(SearchIndexReceiver) expect( receiver.indexes_for(DummiesIndex::Dummy) - .map {|index| index[:_id]} - ).to match_array([41,42]) + .map { |index| index[:_id] } + ).to match_array([41, 42]) end specify 'Real index is bypassed when asserting' do expect(DummiesIndex::Dummy).not_to receive(:bulk) assert_indexes DummiesIndex::Dummy do - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] end end @@ -65,7 +65,7 @@ def assert_includes haystack, needle, _comment expect(DummiesIndex::Dummy).to receive(:bulk) assert_indexes DummiesIndex::Dummy, bypass_actual_index: false do - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] end end end diff --git a/spec/chewy/minitest/search_index_receiver_spec.rb b/spec/chewy/minitest/search_index_receiver_spec.rb index 94b941b22..c6b8f2088 100644 --- a/spec/chewy/minitest/search_index_receiver_spec.rb +++ b/spec/chewy/minitest/search_index_receiver_spec.rb @@ -2,10 +2,10 @@ require 'chewy/minitest' describe :search_index_receiver do - def search_request item_count = 2, verb: :index + def search_request(item_count = 2, verb: :index) items = Array.new(item_count) do |i| { - verb => {_id: i + 1, data: {}} + verb => { _id: i + 1, data: {} } } end @@ -16,8 +16,8 @@ def search_request item_count = 2, verb: :index ] end - def parse_request request - request.map {|r| r[:_id]} + def parse_request(request) + request.map { |r| r[:_id] } end let(:receiver) do @@ -27,11 +27,11 @@ def parse_request request before do stub_index(:dummies) do define_type :fizz do - root value: ->(_o){{}} + root value: ->(_o) { {} } end define_type :buzz do - root value: ->(_o){{}} + root value: ->(_o) { {} } end end end @@ -51,13 +51,13 @@ def parse_request request end specify 'returns indexes for a specific type' do - expect(parse_request receiver.indexes_for(DummiesIndex::Fizz)).to match_array([1,2]) + expect(parse_request(receiver.indexes_for(DummiesIndex::Fizz))).to match_array([1, 2]) end specify 'returns only indexes for all types' do index_responses = receiver.indexes expect(index_responses.keys).to match_array([DummiesIndex::Fizz, DummiesIndex::Buzz]) - expect(parse_request index_responses.values.flatten).to match_array([1, 2, 1, 2, 3]) + expect(parse_request(index_responses.values.flatten)).to match_array([1, 2, 1, 2, 3]) end end @@ -68,7 +68,7 @@ def parse_request request end specify 'returns deletes for a specific type' do - expect(receiver.deletes_for(DummiesIndex::Buzz)).to match_array([1,2,3]) + expect(receiver.deletes_for(DummiesIndex::Buzz)).to match_array([1, 2, 3]) end specify 'returns only deletes for all types' do @@ -85,12 +85,12 @@ def parse_request request specify 'validates that an object was indexed' do dummy = OpenStruct.new(id: 1) - expect(receiver.indexed? dummy, DummiesIndex::Fizz).to be(true) + expect(receiver.indexed?(dummy, DummiesIndex::Fizz)).to be(true) end specify 'doesn\'t validate than unindexed objects were indexed' do dummy = OpenStruct.new(id: 2) - expect(receiver.indexed? dummy, DummiesIndex::Fizz).to be(false) + expect(receiver.indexed?(dummy, DummiesIndex::Fizz)).to be(false) end end @@ -101,12 +101,12 @@ def parse_request request specify 'validates than an object was deleted' do dummy = OpenStruct.new(id: 1) - expect(receiver.deleted? dummy, DummiesIndex::Fizz).to be(true) + expect(receiver.deleted?(dummy, DummiesIndex::Fizz)).to be(true) end specify 'doesn\'t validate than undeleted objects were deleted' do dummy = OpenStruct.new(id: 2) - expect(receiver.deleted? dummy, DummiesIndex::Fizz).to be(false) + expect(receiver.deleted?(dummy, DummiesIndex::Fizz)).to be(false) end end @@ -117,5 +117,4 @@ def parse_request request expect(receiver.updated_indexes).to match_array([DummiesIndex::Fizz, DummiesIndex::Buzz]) end end - end diff --git a/spec/chewy/query/criteria_spec.rb b/spec/chewy/query/criteria_spec.rb index 2d3481870..b575eb198 100644 --- a/spec/chewy/query/criteria_spec.rb +++ b/spec/chewy/query/criteria_spec.rb @@ -28,7 +28,7 @@ its(:fields?) { should eq(false) } its(:types?) { should eq(false) } - its(:none?){ should eq(false) } + its(:none?) { should eq(false) } describe '#update_options' do specify { expect { subject.update_options(field: 'hello') }.to change { subject.options }.to(hash_including(field: 'hello')) } @@ -47,8 +47,10 @@ specify { expect { subject.update_scores(:score) }.to change { subject.scores? }.to(true) } specify { expect { subject.update_scores(:score) }.to change { subject.scores }.to([:score]) } specify { expect { subject.update_scores([:score, :score2]) }.to change { subject.scores }.to([:score, :score2]) } - specify { expect { subject.tap { |s| s.update_scores(:score1) }.update_scores([:score2, :score3]) } - .to change { subject.scores }.to([:score1, :score2, :score3]) } + specify do + expect { subject.tap { |s| s.update_scores(:score1) }.update_scores([:score2, :score3]) } + .to change { subject.scores }.to([:score1, :score2, :score3]) + end end describe '#update_aggregations' do @@ -57,35 +59,56 @@ end describe '#update_script_fields' do - specify { expect { subject.update_script_fields(distance: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}) }.to change { subject.script_fields? }.to(true) } - specify { expect { subject.update_script_fields(distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}) }.to change { subject.script_fields }.to(distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}) } + specify { expect { subject.update_script_fields(distance: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }) }.to change { subject.script_fields? }.to(true) } + specify { expect { subject.update_script_fields(distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) }.to change { subject.script_fields }.to(distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) } end describe '#update_queries' do specify { expect { subject.update_queries(field: 'hello') }.to change { subject.queries? }.to(true) } specify { expect { subject.update_queries(field: 'hello') }.to change { subject.queries }.to([field: 'hello']) } - specify { expect { subject.update_queries(field: 'hello'); subject.update_queries(field: 'world') } - .to change { subject.queries }.to([{field: 'hello'}, {field: 'world'}]) } - specify { expect { subject.update_queries([{field: 'hello'}, {field: 'world'}, nil]) } - .to change { subject.queries }.to([{field: 'hello'}, {field: 'world'}]) } + specify do + expect do + subject.update_queries(field: 'hello') + subject.update_queries(field: 'world') + end + .to change { subject.queries }.to([{ field: 'hello' }, { field: 'world' }]) + end + specify do + expect { subject.update_queries([{ field: 'hello' }, { field: 'world' }, nil]) } + .to change { subject.queries }.to([{ field: 'hello' }, { field: 'world' }]) + end end describe '#update_filters' do specify { expect { subject.update_filters(field: 'hello') }.to change { subject.filters? }.to(true) } - specify { expect { subject.update_filters(field: 'hello') }.to change { subject.filters }.to([{field: 'hello'}]) } - specify { expect { subject.update_filters(field: 'hello'); subject.update_filters(field: 'world') } - .to change { subject.filters }.to([{field: 'hello'}, {field: 'world'}]) } - specify { expect { subject.update_filters([{field: 'hello'}, {field: 'world'}, nil]) } - .to change { subject.filters }.to([{field: 'hello'}, {field: 'world'}]) } + specify { expect { subject.update_filters(field: 'hello') }.to change { subject.filters }.to([{ field: 'hello' }]) } + specify do + expect do + subject.update_filters(field: 'hello') + subject.update_filters(field: 'world') + end + .to change { subject.filters }.to([{ field: 'hello' }, { field: 'world' }]) + end + specify do + expect { subject.update_filters([{ field: 'hello' }, { field: 'world' }, nil]) } + .to change { subject.filters }.to([{ field: 'hello' }, { field: 'world' }]) + end end describe '#update_post_filters' do specify { expect { subject.update_post_filters(field: 'hello') }.to change { subject.post_filters? }.to(true) } - specify { expect { subject.update_post_filters(field: 'hello') }.to change { subject.post_filters }.to([{field: 'hello'}]) } - specify { expect { subject.update_post_filters(field: 'hello'); subject.update_post_filters(field: 'world') } - .to change { subject.post_filters }.to([{field: 'hello'}, {field: 'world'}]) } - specify { expect { subject.update_post_filters([{field: 'hello'}, {field: 'world'}, nil]) } - .to change { subject.post_filters }.to([{field: 'hello'}, {field: 'world'}]) } + specify { expect { subject.update_post_filters(field: 'hello') }.to change { subject.post_filters }.to([{ field: 'hello' }]) } + specify do + expect do + subject.update_post_filters(field: 'hello') + subject.update_post_filters(field: 'world') + end + .to change { subject.post_filters }.to([{ field: 'hello' }, { field: 'world' }]) + end + specify do + expect { subject.update_post_filters([{ field: 'hello' }, { field: 'world' }, nil]) } + .to change { subject.post_filters }.to([{ field: 'hello' }, { field: 'world' }]) + end end describe '#update_sort' do @@ -93,38 +116,46 @@ specify { expect { subject.update_sort([:field]) }.to change { subject.sort }.to([:field]) } specify { expect { subject.update_sort([:field1, :field2]) }.to change { subject.sort }.to([:field1, :field2]) } - specify { expect { subject.update_sort([{field: :asc}]) }.to change { subject.sort }.to([{field: :asc}]) } - specify { expect { subject.update_sort([:field1, field2: {order: :asc}]) }.to change { subject.sort }.to([:field1, {field2: {order: :asc}}]) } - specify { expect { subject.update_sort([{field1: {order: :asc}}, :field2]) }.to change { subject.sort }.to([{field1: {order: :asc}}, :field2]) } - specify { expect { subject.update_sort([field1: :asc, field2: {order: :asc}]) }.to change { subject.sort }.to([{field1: :asc}, {field2: {order: :asc}}]) } - specify { expect { subject.update_sort([{field1: {order: :asc}}, :field2, :field3]) }.to change { subject.sort }.to([{field1: {order: :asc}}, :field2, :field3]) } - specify { expect { subject.update_sort([{field1: {order: :asc}}, [:field2, :field3]]) }.to change { subject.sort }.to([{field1: {order: :asc}}, :field2, :field3]) } - specify { expect { subject.update_sort([{field1: {order: :asc}}, [:field2], :field3]) }.to change { subject.sort }.to([{field1: {order: :asc}}, :field2, :field3]) } - specify { expect { subject.update_sort([{field1: {order: :asc}, field2: :desc}, [:field3], :field4]) }.to change { subject.sort }.to([{field1: {order: :asc}}, {field2: :desc}, :field3, :field4]) } - specify { expect { subject.tap { |s| s.update_sort([field1: {order: :asc}, field2: :desc]) }.update_sort([[:field3], :field4]) }.to change { subject.sort }.to([{field1: {order: :asc}}, {field2: :desc}, :field3, :field4]) } - specify { expect { subject.tap { |s| s.update_sort([field1: {order: :asc}, field2: :desc]) }.update_sort([[:field3], :field4], purge: true) }.to change { subject.sort }.to([:field3, :field4]) } + specify { expect { subject.update_sort([{ field: :asc }]) }.to change { subject.sort }.to([{ field: :asc }]) } + specify { expect { subject.update_sort([:field1, field2: { order: :asc }]) }.to change { subject.sort }.to([:field1, { field2: { order: :asc } }]) } + specify { expect { subject.update_sort([{ field1: { order: :asc } }, :field2]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, :field2]) } + specify { expect { subject.update_sort([field1: :asc, field2: { order: :asc }]) }.to change { subject.sort }.to([{ field1: :asc }, { field2: { order: :asc } }]) } + specify { expect { subject.update_sort([{ field1: { order: :asc } }, :field2, :field3]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, :field2, :field3]) } + specify { expect { subject.update_sort([{ field1: { order: :asc } }, [:field2, :field3]]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, :field2, :field3]) } + specify { expect { subject.update_sort([{ field1: { order: :asc } }, [:field2], :field3]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, :field2, :field3]) } + specify { expect { subject.update_sort([{ field1: { order: :asc }, field2: :desc }, [:field3], :field4]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, { field2: :desc }, :field3, :field4]) } + specify { expect { subject.tap { |s| s.update_sort([field1: { order: :asc }, field2: :desc]) }.update_sort([[:field3], :field4]) }.to change { subject.sort }.to([{ field1: { order: :asc } }, { field2: :desc }, :field3, :field4]) } + specify { expect { subject.tap { |s| s.update_sort([field1: { order: :asc }, field2: :desc]) }.update_sort([[:field3], :field4], purge: true) }.to change { subject.sort }.to([:field3, :field4]) } end describe '#update_fields' do specify { expect { subject.update_fields(:field) }.to change { subject.fields? }.to(true) } specify { expect { subject.update_fields(:field) }.to change { subject.fields }.to(['field']) } specify { expect { subject.update_fields([:field, :field]) }.to change { subject.fields }.to(['field']) } - specify { expect { subject.update_fields([:field1, :field2]) }.to change { subject.fields }.to(['field1', 'field2']) } - specify { expect { subject.tap { |s| s.update_fields(:field1) }.update_fields([:field2, :field3]) } - .to change { subject.fields }.to(['field1', 'field2', 'field3']) } - specify { expect { subject.tap { |s| s.update_fields(:field1) }.update_fields([:field2, :field3], purge: true) } - .to change { subject.fields }.to(['field2', 'field3']) } + specify { expect { subject.update_fields([:field1, :field2]) }.to change { subject.fields }.to(%w(field1 field2)) } + specify do + expect { subject.tap { |s| s.update_fields(:field1) }.update_fields([:field2, :field3]) } + .to change { subject.fields }.to(%w(field1 field2 field3)) + end + specify do + expect { subject.tap { |s| s.update_fields(:field1) }.update_fields([:field2, :field3], purge: true) } + .to change { subject.fields }.to(%w(field2 field3)) + end end describe '#update_types' do specify { expect { subject.update_types(:type) }.to change { subject.types? }.to(true) } specify { expect { subject.update_types(:type) }.to change { subject.types }.to(['type']) } specify { expect { subject.update_types([:type, :type]) }.to change { subject.types }.to(['type']) } - specify { expect { subject.update_types([:type1, :type2]) }.to change { subject.types }.to(['type1', 'type2']) } - specify { expect { subject.tap { |s| s.update_types(:type1) }.update_types([:type2, :type3]) } - .to change { subject.types }.to(['type1', 'type2', 'type3']) } - specify { expect { subject.tap { |s| s.update_types(:type1) }.update_types([:type2, :type3], purge: true) } - .to change { subject.types }.to(['type2', 'type3']) } + specify { expect { subject.update_types([:type1, :type2]) }.to change { subject.types }.to(%w(type1 type2)) } + specify do + expect { subject.tap { |s| s.update_types(:type1) }.update_types([:type2, :type3]) } + .to change { subject.types }.to(%w(type1 type2 type3)) + end + specify do + expect { subject.tap { |s| s.update_types(:type1) }.update_types([:type2, :type3], purge: true) } + .to change { subject.types }.to(%w(type2 type3)) + end end describe '#merge' do @@ -133,30 +164,54 @@ specify { expect(subject.merge(criteria)).not_to be_equal subject } specify { expect(subject.merge(criteria)).not_to be_equal criteria } - specify { expect(subject.tap { |c| c.update_options(opt1: 'hello') } - .merge(criteria.tap { |c| c.update_options(opt2: 'hello') }).options).to include(opt1: 'hello', opt2: 'hello') } - specify { expect(subject.tap { |c| c.update_request_options(opt1: 'hello') } - .merge(criteria.tap { |c| c.update_request_options(opt2: 'hello') }).request_options).to include(opt1: 'hello', opt2: 'hello') } - specify { expect(subject.tap { |c| c.update_facets(field1: 'hello') } - .merge(criteria.tap { |c| c.update_facets(field1: 'hello') }).facets).to eq({field1: 'hello'}) } - specify { expect(subject.tap { |c| c.update_script_fields(distance_m: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}) } - .merge(criteria.tap { |c| c.update_script_fields(distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}) }).script_fields).to eq({distance_m: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}, distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}}) } - specify { expect(subject.tap { |c| c.update_scores(script: 'hello') } - .merge(criteria.tap { |c| c.update_scores(script: 'foobar') }).scores).to eq([{script: 'hello'}, { script: 'foobar' } ]) } - specify { expect(subject.tap { |c| c.update_aggregations(field1: 'hello') } - .merge(criteria.tap { |c| c.update_aggregations(field1: 'hello') }).aggregations).to eq({field1: 'hello'}) } - specify { expect(subject.tap { |c| c.update_queries(field1: 'hello') } - .merge(criteria.tap { |c| c.update_queries(field2: 'hello') }).queries).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_filters(field1: 'hello') } - .merge(criteria.tap { |c| c.update_filters(field2: 'hello') }).filters).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_post_filters(field1: 'hello') } - .merge(criteria.tap { |c| c.update_post_filters(field2: 'hello') }).post_filters).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_sort(:field1) } - .merge(criteria.tap { |c| c.update_sort(:field2) }).sort).to eq([:field1, :field2]) } - specify { expect(subject.tap { |c| c.update_fields(:field1) } - .merge(criteria.tap { |c| c.update_fields(:field2) }).fields).to eq(['field1', 'field2']) } - specify { expect(subject.tap { |c| c.update_types(:type1) } - .merge(criteria.tap { |c| c.update_types(:type2) }).types).to eq(['type1', 'type2']) } + specify do + expect(subject.tap { |c| c.update_options(opt1: 'hello') } + .merge(criteria.tap { |c| c.update_options(opt2: 'hello') }).options).to include(opt1: 'hello', opt2: 'hello') + end + specify do + expect(subject.tap { |c| c.update_request_options(opt1: 'hello') } + .merge(criteria.tap { |c| c.update_request_options(opt2: 'hello') }).request_options).to include(opt1: 'hello', opt2: 'hello') + end + specify do + expect(subject.tap { |c| c.update_facets(field1: 'hello') } + .merge(criteria.tap { |c| c.update_facets(field1: 'hello') }).facets).to eq(field1: 'hello') + end + specify do + expect(subject.tap { |c| c.update_script_fields(distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }) } + .merge(criteria.tap { |c| c.update_script_fields(distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) }).script_fields).to eq(distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }, distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) + end + specify do + expect(subject.tap { |c| c.update_scores(script: 'hello') } + .merge(criteria.tap { |c| c.update_scores(script: 'foobar') }).scores).to eq([{ script: 'hello' }, { script: 'foobar' }]) + end + specify do + expect(subject.tap { |c| c.update_aggregations(field1: 'hello') } + .merge(criteria.tap { |c| c.update_aggregations(field1: 'hello') }).aggregations).to eq(field1: 'hello') + end + specify do + expect(subject.tap { |c| c.update_queries(field1: 'hello') } + .merge(criteria.tap { |c| c.update_queries(field2: 'hello') }).queries).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_filters(field1: 'hello') } + .merge(criteria.tap { |c| c.update_filters(field2: 'hello') }).filters).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_post_filters(field1: 'hello') } + .merge(criteria.tap { |c| c.update_post_filters(field2: 'hello') }).post_filters).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_sort(:field1) } + .merge(criteria.tap { |c| c.update_sort(:field2) }).sort).to eq([:field1, :field2]) + end + specify do + expect(subject.tap { |c| c.update_fields(:field1) } + .merge(criteria.tap { |c| c.update_fields(:field2) }).fields).to eq(%w(field1 field2)) + end + specify do + expect(subject.tap { |c| c.update_types(:type1) } + .merge(criteria.tap { |c| c.update_types(:type2) }).types).to eq(%w(type1 type2)) + end end describe '#merge!' do @@ -165,268 +220,404 @@ specify { expect(subject.merge!(criteria)).to be_equal subject } specify { expect(subject.merge!(criteria)).not_to be_equal criteria } - specify { expect(subject.tap { |c| c.update_options(opt1: 'hello') } - .merge!(criteria.tap { |c| c.update_options(opt2: 'hello') }).options).to include(opt1: 'hello', opt2: 'hello') } - specify { expect(subject.tap { |c| c.update_request_options(opt1: 'hello') } - .merge!(criteria.tap { |c| c.update_request_options(opt2: 'hello') }).request_options).to include(opt1: 'hello', opt2: 'hello') } - specify { expect(subject.tap { |c| c.update_facets(field1: 'hello') } - .merge!(criteria.tap { |c| c.update_facets(field1: 'hello') }).facets).to eq({field1: 'hello'}) } - specify { expect(subject.tap { |c| c.update_script_fields(distance_m: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}) } - .merge(criteria.tap { |c| c.update_script_fields(distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}) }).script_fields).to eq({distance_m: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}, distance_km: {script: "doc['coordinates'].distanceInKm(lat, lon)"}}) } - specify { expect(subject.tap { |c| c.update_aggregations(field1: 'hello') } - .merge!(criteria.tap { |c| c.update_aggregations(field1: 'hello') }).aggregations).to eq({field1: 'hello'}) } - specify { expect(subject.tap { |c| c.update_queries(field1: 'hello') } - .merge!(criteria.tap { |c| c.update_queries(field2: 'hello') }).queries).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_filters(field1: 'hello') } - .merge!(criteria.tap { |c| c.update_filters(field2: 'hello') }).filters).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_post_filters(field1: 'hello') } - .merge!(criteria.tap { |c| c.update_post_filters(field2: 'hello') }).post_filters).to eq([{field1: 'hello'}, {field2: 'hello'}]) } - specify { expect(subject.tap { |c| c.update_sort(:field1) } - .merge!(criteria.tap { |c| c.update_sort(:field2) }).sort).to eq([:field1, :field2]) } - specify { expect(subject.tap { |c| c.update_fields(:field1) } - .merge!(criteria.tap { |c| c.update_fields(:field2) }).fields).to eq(['field1', 'field2']) } - specify { expect(subject.tap { |c| c.update_types(:type1) } - .merge!(criteria.tap { |c| c.update_types(:type2) }).types).to eq(['type1', 'type2']) } + specify do + expect(subject.tap { |c| c.update_options(opt1: 'hello') } + .merge!(criteria.tap { |c| c.update_options(opt2: 'hello') }).options).to include(opt1: 'hello', opt2: 'hello') + end + specify do + expect(subject.tap { |c| c.update_request_options(opt1: 'hello') } + .merge!(criteria.tap { |c| c.update_request_options(opt2: 'hello') }).request_options).to include(opt1: 'hello', opt2: 'hello') + end + specify do + expect(subject.tap { |c| c.update_facets(field1: 'hello') } + .merge!(criteria.tap { |c| c.update_facets(field1: 'hello') }).facets).to eq(field1: 'hello') + end + specify do + expect(subject.tap { |c| c.update_script_fields(distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }) } + .merge(criteria.tap { |c| c.update_script_fields(distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) }).script_fields).to eq(distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }, distance_km: { script: "doc['coordinates'].distanceInKm(lat, lon)" }) + end + specify do + expect(subject.tap { |c| c.update_aggregations(field1: 'hello') } + .merge!(criteria.tap { |c| c.update_aggregations(field1: 'hello') }).aggregations).to eq(field1: 'hello') + end + specify do + expect(subject.tap { |c| c.update_queries(field1: 'hello') } + .merge!(criteria.tap { |c| c.update_queries(field2: 'hello') }).queries).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_filters(field1: 'hello') } + .merge!(criteria.tap { |c| c.update_filters(field2: 'hello') }).filters).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_post_filters(field1: 'hello') } + .merge!(criteria.tap { |c| c.update_post_filters(field2: 'hello') }).post_filters).to eq([{ field1: 'hello' }, { field2: 'hello' }]) + end + specify do + expect(subject.tap { |c| c.update_sort(:field1) } + .merge!(criteria.tap { |c| c.update_sort(:field2) }).sort).to eq([:field1, :field2]) + end + specify do + expect(subject.tap { |c| c.update_fields(:field1) } + .merge!(criteria.tap { |c| c.update_fields(:field2) }).fields).to eq(%w(field1 field2)) + end + specify do + expect(subject.tap { |c| c.update_types(:type1) } + .merge!(criteria.tap { |c| c.update_types(:type2) }).types).to eq(%w(type1 type2)) + end end describe '#request_body' do - def request_body &block + def request_body(&block) subject.instance_exec(&block) if block subject.request_body end - specify { expect(request_body).to eq({body: {}}) } - specify { expect(request_body { update_request_options(size: 10) }).to eq({body: {size: 10}}) } - specify { expect(request_body { update_request_options(from: 10) }).to eq({body: {from: 10}}) } - specify { expect(request_body { update_request_options(explain: true) }).to eq({body: {explain: true}}) } - specify { expect(request_body { update_queries(:query) }).to eq({body: {query: :query}}) } - specify { expect(request_body { - update_scores(script_score: { script: '_score'}) - }).to eq({body: {query: { function_score: { functions: [{ script_score: {script: '_score' }}] }}}}) } - specify { expect(request_body { - update_scores(script_score: { script: "boost_me" }) - update_queries(:query) - update_options(boost_mode: :add) - update_options(score_mode: :avg) - }).to eq({body: {query: { - function_score: { - functions: [{ - script_score: {script: 'boost_me' } - }], - query: :query, - boost_mode: :add, - score_mode: :avg - }}}}) - } - specify { expect(request_body { - update_request_options(from: 10); update_sort(:field); update_fields(:field); update_queries(:query) - }).to eq({body: {query: :query, from: 10, sort: [:field], _source: ['field']}}) } - - specify { expect(request_body { - update_queries(:query); update_filters(:filters); - }).to eq({body: {query: {filtered: {query: :query, filter: :filters}}}}) } - specify { expect(request_body { - update_queries(:query); update_post_filters(:post_filter); - }).to eq({body: {query: :query, post_filter: :post_filter}}) } - specify { expect(request_body { - update_script_fields(distance_m: {script: "doc['coordinates'].distanceInMiles(lat, lon)"}) - }).to eq({:body=>{:script_fields=>{:distance_m=>{:script=>"doc['coordinates'].distanceInMiles(lat, lon)"}}}}) } + specify { expect(request_body).to eq(body: {}) } + specify { expect(request_body { update_request_options(size: 10) }).to eq(body: { size: 10 }) } + specify { expect(request_body { update_request_options(from: 10) }).to eq(body: { from: 10 }) } + specify { expect(request_body { update_request_options(explain: true) }).to eq(body: { explain: true }) } + specify { expect(request_body { update_queries(:query) }).to eq(body: { query: :query }) } + specify do + expect(request_body do + update_scores(script_score: { script: '_score' }) + end).to eq(body: { query: { function_score: { functions: [{ script_score: { script: '_score' } }] } } }) end + specify do + expect(request_body do + update_scores(script_score: { script: 'boost_me' }) + update_queries(:query) + update_options(boost_mode: :add) + update_options(score_mode: :avg) + end).to eq(body: { query: { + function_score: { + functions: [{ + script_score: { script: 'boost_me' } + }], + query: :query, + boost_mode: :add, + score_mode: :avg + } + } }) + end + specify do + expect(request_body do + update_request_options(from: 10) + update_sort(:field) + update_fields(:field) + update_queries(:query) + end).to eq(body: { query: :query, from: 10, sort: [:field], _source: ['field'] }) end + + specify do + expect(request_body do + update_queries(:query) + update_filters(:filters) + end).to eq(body: { query: { filtered: { query: :query, filter: :filters } } }) end + specify do + expect(request_body do + update_queries(:query) + update_post_filters(:post_filter) + end).to eq(body: { query: :query, post_filter: :post_filter }) end + specify do + expect(request_body do + update_script_fields(distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" }) + end).to eq(body: { script_fields: { distance_m: { script: "doc['coordinates'].distanceInMiles(lat, lon)" } } }) end end describe '#_filtered_query' do - def _filtered_query options = {}, &block + def _filtered_query(options = {}, &block) subject.instance_exec(&block) if block subject.send(:_filtered_query, subject.send(:_request_query), subject.send(:_request_filter), options) end specify { expect(_filtered_query).to eq({}) } - specify { expect(_filtered_query { update_queries(:query) }).to eq({query: :query}) } - specify { expect(_filtered_query(strategy: 'query_first') { update_queries(:query) }).to eq({query: :query}) } - specify { expect(_filtered_query { update_queries([:query1, :query2]) }) - .to eq({query: {bool: {must: [:query1, :query2]}}}) } - specify { expect(_filtered_query { update_options(query_mode: :should); update_queries([:query1, :query2]) }) - .to eq({query: {bool: {should: [:query1, :query2]}}}) } - specify { expect(_filtered_query { update_options(query_mode: :dis_max); update_queries([:query1, :query2]) }) - .to eq({query: {dis_max: {queries: [:query1, :query2]}}}) } - - specify { expect(_filtered_query(strategy: 'query_first') { update_filters([:filter1, :filter2]) }) - .to eq({query: {filtered: {query: {match_all: {}}, filter: {and: [:filter1, :filter2]}, strategy: 'query_first'}}}) } - specify { expect(_filtered_query { update_filters([:filter1, :filter2]) }) - .to eq({query: {filtered: {query: {match_all: {}}, filter: {and: [:filter1, :filter2]}}}}) } - - specify { expect(_filtered_query { update_filters([:filter1, :filter2]); update_queries([:query1, :query2]) }) - .to eq({query: {filtered: { - query: {bool: {must: [:query1, :query2]}}, - filter: {and: [:filter1, :filter2]} - }}}) - } - specify { expect(_filtered_query(strategy: 'query_first') { update_filters([:filter1, :filter2]); update_queries([:query1, :query2]) }) - .to eq({query: {filtered: { - query: {bool: {must: [:query1, :query2]}}, - filter: {and: [:filter1, :filter2]}, - strategy: 'query_first' - }}}) - } - specify { expect(_filtered_query { - update_options(query_mode: :should); update_options(filter_mode: :or); - update_filters([:filter1, :filter2]); update_queries([:query1, :query2]) - }).to eq({query: {filtered: { - query: {bool: {should: [:query1, :query2]}}, - filter: {or: [:filter1, :filter2]} - }}}) } + specify { expect(_filtered_query { update_queries(:query) }).to eq(query: :query) } + specify { expect(_filtered_query(strategy: 'query_first') { update_queries(:query) }).to eq(query: :query) } + specify do + expect(_filtered_query { update_queries([:query1, :query2]) }) + .to eq(query: { bool: { must: [:query1, :query2] } }) + end + specify do + expect(_filtered_query do + update_options(query_mode: :should) + update_queries([:query1, :query2]) + end) + .to eq(query: { bool: { should: [:query1, :query2] } }) + end + specify do + expect(_filtered_query do + update_options(query_mode: :dis_max) + update_queries([:query1, :query2]) + end) + .to eq(query: { dis_max: { queries: [:query1, :query2] } }) + end + + specify do + expect(_filtered_query(strategy: 'query_first') { update_filters([:filter1, :filter2]) }) + .to eq(query: { filtered: { query: { match_all: {} }, filter: { and: [:filter1, :filter2] }, strategy: 'query_first' } }) + end + specify do + expect(_filtered_query { update_filters([:filter1, :filter2]) }) + .to eq(query: { filtered: { query: { match_all: {} }, filter: { and: [:filter1, :filter2] } } }) + end + + specify do + expect(_filtered_query do + update_filters([:filter1, :filter2]) + update_queries([:query1, :query2]) + end) + .to eq(query: { filtered: { + query: { bool: { must: [:query1, :query2] } }, + filter: { and: [:filter1, :filter2] } + } }) + end + specify do + expect(_filtered_query(strategy: 'query_first') do + update_filters([:filter1, :filter2]) + update_queries([:query1, :query2]) + end) + .to eq(query: { filtered: { + query: { bool: { must: [:query1, :query2] } }, + filter: { and: [:filter1, :filter2] }, + strategy: 'query_first' + } }) + end + specify do + expect(_filtered_query do + update_options(query_mode: :should) + update_options(filter_mode: :or) + update_filters([:filter1, :filter2]) + update_queries([:query1, :query2]) + end).to eq(query: { filtered: { + query: { bool: { should: [:query1, :query2] } }, + filter: { or: [:filter1, :filter2] } + } }) + end end - describe "#_boost_query" do + describe '#_boost_query' do specify { expect(subject.send(:_boost_query, query: :query)).to eq(query: :query) } - specify { - subject.update_scores({ boost_factor: 5 }) + specify do + subject.update_scores(boost_factor: 5) expect(subject.send(:_boost_query, query: :query)).to eq(query: { function_score: { functions: [{ boost_factor: 5 }], query: :query } }) - } - specify { - subject.update_scores({ boost_factor: 5 }) + end + specify do + subject.update_scores(boost_factor: 5) subject.update_options(boost_mode: :multiply) subject.update_options(score_mode: :add) expect(subject.send(:_boost_query, query: :query)).to eq(query: { function_score: { functions: [{ boost_factor: 5 }], query: :query, boost_mode: :multiply, score_mode: :add } }) - } - specify { - subject.update_scores({ boost_factor: 5 }) + end + specify do + subject.update_scores(boost_factor: 5) expect(subject.send(:_boost_query, query: :query, filter: :filter)).to eq(query: { function_score: { functions: [{ boost_factor: 5 }], query: { filtered: { query: :query, filter: :filter } } } }) - } + end end describe '#_request_filter' do - def _request_filter &block + def _request_filter(&block) subject.instance_exec(&block) if block subject.send(:_request_filter) end specify { expect(_request_filter).to be_nil } - specify { expect(_request_filter { update_types(:type) }).to eq({type: {value: 'type'}}) } - specify { expect(_request_filter { update_types([:type1, :type2]) }) - .to eq({or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}) } - - specify { expect(_request_filter { update_filters([:filter1, :filter2]) }) - .to eq({and: [:filter1, :filter2]}) } - specify { expect(_request_filter { update_options(filter_mode: :or); update_filters([:filter1, :filter2]) }) - .to eq({or: [:filter1, :filter2]}) } - specify { expect(_request_filter { update_options(filter_mode: :must); update_filters([:filter1, :filter2]) }) - .to eq({bool: {must: [:filter1, :filter2]}}) } - specify { expect(_request_filter { update_options(filter_mode: :should); update_filters([:filter1, :filter2]) }) - .to eq({bool: {should: [:filter1, :filter2]}}) } - specify { expect(_request_filter { update_options(filter_mode: :must_not); update_filters([:filter1, :filter2]) }) - .to eq({bool: {must_not: [:filter1, :filter2]}}) } - - specify { expect(_request_filter { update_types([:type1, :type2]); update_filters([:filter1, :filter2]) }) - .to eq({and: [{or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}, :filter1, :filter2]}) } - specify { expect(_request_filter { update_options(filter_mode: :or); update_types([:type1, :type2]); update_filters([:filter1, :filter2]) }) - .to eq({and: [{or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}, {or: [:filter1, :filter2]}]}) } - specify { expect(_request_filter { update_options(filter_mode: :must); update_types([:type1, :type2]); update_filters([:filter1, :filter2]) }) - .to eq({and: [{or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}, {bool: {must: [:filter1, :filter2]}}]}) } - specify { expect(_request_filter { update_options(filter_mode: :should); update_types([:type1, :type2]); update_filters([:filter1, :filter2]) }) - .to eq({and: [{or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}, {bool: {should: [:filter1, :filter2]}}]}) } - specify { expect(_request_filter { update_options(filter_mode: :must_not); update_types([:type1, :type2]); update_filters([:filter1, :filter2]) }) - .to eq({and: [{or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}, {bool: {must_not: [:filter1, :filter2]}}]}) } + specify { expect(_request_filter { update_types(:type) }).to eq(type: { value: 'type' }) } + specify do + expect(_request_filter { update_types([:type1, :type2]) }) + .to eq(or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }]) + end + + specify do + expect(_request_filter { update_filters([:filter1, :filter2]) }) + .to eq(and: [:filter1, :filter2]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :or) + update_filters([:filter1, :filter2]) + end) + .to eq(or: [:filter1, :filter2]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :must) + update_filters([:filter1, :filter2]) + end) + .to eq(bool: { must: [:filter1, :filter2] }) + end + specify do + expect(_request_filter do + update_options(filter_mode: :should) + update_filters([:filter1, :filter2]) + end) + .to eq(bool: { should: [:filter1, :filter2] }) + end + specify do + expect(_request_filter do + update_options(filter_mode: :must_not) + update_filters([:filter1, :filter2]) + end) + .to eq(bool: { must_not: [:filter1, :filter2] }) + end + + specify do + expect(_request_filter do + update_types([:type1, :type2]) + update_filters([:filter1, :filter2]) + end) + .to eq(and: [{ or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }] }, :filter1, :filter2]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :or) + update_types([:type1, :type2]) + update_filters([:filter1, :filter2]) + end) + .to eq(and: [{ or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }] }, { or: [:filter1, :filter2] }]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :must) + update_types([:type1, :type2]) + update_filters([:filter1, :filter2]) + end) + .to eq(and: [{ or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }] }, { bool: { must: [:filter1, :filter2] } }]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :should) + update_types([:type1, :type2]) + update_filters([:filter1, :filter2]) + end) + .to eq(and: [{ or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }] }, { bool: { should: [:filter1, :filter2] } }]) + end + specify do + expect(_request_filter do + update_options(filter_mode: :must_not) + update_types([:type1, :type2]) + update_filters([:filter1, :filter2]) + end) + .to eq(and: [{ or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }] }, { bool: { must_not: [:filter1, :filter2] } }]) + end end describe '#_request_post_filter' do - def _request_post_filter &block + def _request_post_filter(&block) subject.instance_exec(&block) if block subject.send(:_request_post_filter) end specify { expect(_request_post_filter).to be_nil } - specify { expect(_request_post_filter { update_post_filters([:post_filter1, :post_filter2]) }) - .to eq({and: [:post_filter1, :post_filter2]}) } - specify { expect(_request_post_filter { update_options(post_filter_mode: :or); update_post_filters([:post_filter1, :post_filter2]) }) - .to eq({or: [:post_filter1, :post_filter2]}) } - specify { expect(_request_post_filter { update_options(post_filter_mode: :must); update_post_filters([:post_filter1, :post_filter2]) }) - .to eq({bool: {must: [:post_filter1, :post_filter2]}}) } - specify { expect(_request_post_filter { update_options(post_filter_mode: :should); update_post_filters([:post_filter1, :post_filter2]) }) - .to eq({bool: {should: [:post_filter1, :post_filter2]}}) } + specify do + expect(_request_post_filter { update_post_filters([:post_filter1, :post_filter2]) }) + .to eq(and: [:post_filter1, :post_filter2]) + end + specify do + expect(_request_post_filter do + update_options(post_filter_mode: :or) + update_post_filters([:post_filter1, :post_filter2]) + end) + .to eq(or: [:post_filter1, :post_filter2]) + end + specify do + expect(_request_post_filter do + update_options(post_filter_mode: :must) + update_post_filters([:post_filter1, :post_filter2]) + end) + .to eq(bool: { must: [:post_filter1, :post_filter2] }) + end + specify do + expect(_request_post_filter do + update_options(post_filter_mode: :should) + update_post_filters([:post_filter1, :post_filter2]) + end) + .to eq(bool: { should: [:post_filter1, :post_filter2] }) + end context do before { allow(Chewy).to receive_messages(filter_mode: :or) } - specify { expect(_request_post_filter { update_post_filters([:post_filter1, :post_filter2]) }) - .to eq({or: [:post_filter1, :post_filter2]}) } + specify do + expect(_request_post_filter { update_post_filters([:post_filter1, :post_filter2]) }) + .to eq(or: [:post_filter1, :post_filter2]) + end end end describe '#_request_types' do - def _request_types &block + def _request_types(&block) subject.instance_exec(&block) if block subject.send(:_request_types) end specify { expect(_request_types).to be_nil } - specify { expect(_request_types { update_types(:type1) }).to eq({type: {value: 'type1'}}) } - specify { expect(_request_types { update_types([:type1, :type2]) }) - .to eq({or: [{type: {value: 'type1'}}, {type: {value: 'type2'}}]}) } + specify { expect(_request_types { update_types(:type1) }).to eq(type: { value: 'type1' }) } + specify do + expect(_request_types { update_types([:type1, :type2]) }) + .to eq(or: [{ type: { value: 'type1' } }, { type: { value: 'type2' } }]) + end end describe '#_queries_join' do - def _queries_join *args + def _queries_join(*args) subject.send(:_queries_join, *args) end - let(:query) { {term: {field: 'value'}} } + let(:query) { { term: { field: 'value' } } } specify { expect(_queries_join([], :dis_max)).to be_nil } specify { expect(_queries_join([query], :dis_max)).to eq(query) } - specify { expect(_queries_join([query, query], :dis_max)).to eq({dis_max: {queries: [query, query]}}) } + specify { expect(_queries_join([query, query], :dis_max)).to eq(dis_max: { queries: [query, query] }) } specify { expect(_queries_join([], 0.7)).to be_nil } specify { expect(_queries_join([query], 0.7)).to eq(query) } - specify { expect(_queries_join([query, query], 0.7)).to eq({dis_max: {queries: [query, query], tie_breaker: 0.7}}) } + specify { expect(_queries_join([query, query], 0.7)).to eq(dis_max: { queries: [query, query], tie_breaker: 0.7 }) } specify { expect(_queries_join([], :must)).to be_nil } specify { expect(_queries_join([query], :must)).to eq(query) } - specify { expect(_queries_join([query, query], :must)).to eq({bool: {must: [query, query]}}) } + specify { expect(_queries_join([query, query], :must)).to eq(bool: { must: [query, query] }) } specify { expect(_queries_join([], :should)).to be_nil } specify { expect(_queries_join([query], :should)).to eq(query) } - specify { expect(_queries_join([query, query], :should)).to eq({bool: {should: [query, query]}}) } + specify { expect(_queries_join([query, query], :should)).to eq(bool: { should: [query, query] }) } specify { expect(_queries_join([], :must_not)).to be_nil } - specify { expect(_queries_join([query], :must_not)).to eq({bool: {must_not: [query]}}) } - specify { expect(_queries_join([query, query], :must_not)).to eq({bool: {must_not: [query, query]}}) } + specify { expect(_queries_join([query], :must_not)).to eq(bool: { must_not: [query] }) } + specify { expect(_queries_join([query, query], :must_not)).to eq(bool: { must_not: [query, query] }) } specify { expect(_queries_join([], '25%')).to be_nil } specify { expect(_queries_join([query], '25%')).to eq(query) } - specify { expect(_queries_join([query, query], '25%')).to eq({bool: {should: [query, query], minimum_should_match: '25%'}}) } + specify { expect(_queries_join([query, query], '25%')).to eq(bool: { should: [query, query], minimum_should_match: '25%' }) } end describe '#_filters_join' do - def _filters_join *args + def _filters_join(*args) subject.send(:_filters_join, *args) end - let(:filter) { {term: {field: 'value'}} } + let(:filter) { { term: { field: 'value' } } } specify { expect(_filters_join([], :and)).to be_nil } specify { expect(_filters_join([filter], :and)).to eq(filter) } - specify { expect(_filters_join([filter, filter], :and)).to eq({and: [filter, filter]}) } + specify { expect(_filters_join([filter, filter], :and)).to eq(and: [filter, filter]) } specify { expect(_filters_join([], :or)).to be_nil } specify { expect(_filters_join([filter], :or)).to eq(filter) } - specify { expect(_filters_join([filter, filter], :or)).to eq({or: [filter, filter]}) } + specify { expect(_filters_join([filter, filter], :or)).to eq(or: [filter, filter]) } specify { expect(_filters_join([], :must)).to be_nil } specify { expect(_filters_join([filter], :must)).to eq(filter) } - specify { expect(_filters_join([filter, filter], :must)).to eq({bool: {must: [filter, filter]}}) } + specify { expect(_filters_join([filter, filter], :must)).to eq(bool: { must: [filter, filter] }) } specify { expect(_filters_join([], :should)).to be_nil } specify { expect(_filters_join([filter], :should)).to eq(filter) } - specify { expect(_filters_join([filter, filter], :should)).to eq({bool: {should: [filter, filter]}}) } + specify { expect(_filters_join([filter, filter], :should)).to eq(bool: { should: [filter, filter] }) } specify { expect(_filters_join([], :must_not)).to be_nil } - specify { expect(_filters_join([filter], :must_not)).to eq({bool: {must_not: [filter]}}) } - specify { expect(_filters_join([filter, filter], :must_not)).to eq({bool: {must_not: [filter, filter]}}) } + specify { expect(_filters_join([filter], :must_not)).to eq(bool: { must_not: [filter] }) } + specify { expect(_filters_join([filter, filter], :must_not)).to eq(bool: { must_not: [filter, filter] }) } specify { expect(_filters_join([], '25%')).to be_nil } specify { expect(_filters_join([filter], '25%')).to eq(filter) } - specify { expect(_filters_join([filter, filter], '25%')).to eq({bool: {should: [filter, filter], minimum_should_match: '25%'}}) } + specify { expect(_filters_join([filter, filter], '25%')).to eq(bool: { should: [filter, filter], minimum_should_match: '25%' }) } end end diff --git a/spec/chewy/query/filters_spec.rb b/spec/chewy/query/filters_spec.rb index abde121a4..9a659606f 100644 --- a/spec/chewy/query/filters_spec.rb +++ b/spec/chewy/query/filters_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Chewy::Query::Filters do - def Bool options + def Bool(options) Chewy::Query::Nodes::Bool.new.tap do |bool| bool.must(*options[:must]) if options[:must].present? bool.must_not(*options[:must_not]) if options[:must_not].present? @@ -15,21 +15,21 @@ def Bool options end end - def query &block + def query(&block) Chewy::Query::Filters.new(&block).__result__ end context 'outer scope' do let(:email) { 'email' } specify { expect(query { email }).to be_eql Field(:email) } - specify { expect(query { o{email} }).to eq('email') } + specify { expect(query { o { email } }).to eq('email') } end context 'field' do let(:email) { 'email' } specify { expect(query { f(:email) }).to be_eql Field(:email) } - specify { expect(query { f{ :email } }).to be_eql Field(:email) } - specify { expect(query { f{ email } }).to be_eql Field(:email) } + specify { expect(query { f { :email } }).to be_eql Field(:email) } + specify { expect(query { f { email } }).to be_eql Field(:email) } specify { expect(query { email }).to be_eql Field(:email) } specify { expect(query { emails.first }).to be_eql Field('emails.first') } specify { expect(query { emails.first.second }).to be_eql Field('emails.first.second') } @@ -38,28 +38,36 @@ def query &block context 'term' do specify { expect(query { email == 'email' }).to be_eql Equal(:email, 'email') } specify { expect(query { name != 'name' }).to be_eql Not(Equal(:name, 'name')) } - specify { expect(query { email == ['email1', 'email2'] }).to be_eql Equal(:email, ['email1', 'email2']) } - specify { expect(query { email != ['email1', 'email2'] }).to be_eql Not(Equal(:email, ['email1', 'email2'])) } - specify { expect(query { email(execution: :bool) == ['email1', 'email2'] }) - .to be_eql Equal(:email, ['email1', 'email2'], execution: :bool) } - specify { expect(query { email(:bool) == ['email1', 'email2'] }) - .to be_eql Equal(:email, ['email1', 'email2'], execution: :bool) } - specify { expect(query { email(:b) == ['email1', 'email2'] }) - .to be_eql Equal(:email, ['email1', 'email2'], execution: :bool) } + specify { expect(query { email == %w(email1 email2) }).to be_eql Equal(:email, %w(email1 email2)) } + specify { expect(query { email != %w(email1 email2) }).to be_eql Not(Equal(:email, %w(email1 email2))) } + specify do + expect(query { email(execution: :bool) == %w(email1 email2) }) + .to be_eql Equal(:email, %w(email1 email2), execution: :bool) + end + specify do + expect(query { email(:bool) == %w(email1 email2) }) + .to be_eql Equal(:email, %w(email1 email2), execution: :bool) + end + specify do + expect(query { email(:b) == %w(email1 email2) }) + .to be_eql Equal(:email, %w(email1 email2), execution: :bool) + end end context 'bool' do specify { query { must(email == 'email') }.should be_eql Bool(must: [Equal(:email, 'email')]) } specify { query { must_not(email == 'email') }.should be_eql Bool(must_not: [Equal(:email, 'email')]) } specify { query { should(email == 'email') }.should be_eql Bool(should: [Equal(:email, 'email')]) } - specify { query { - must(email == 'email').should(address != 'address', age == 42) - .must_not(sex == 'm').must(name == 'name') - }.should be_eql Bool( - must: [Equal(:email, 'email'), Equal(:name, 'name')], - must_not: [Equal(:sex, 'm')], - should: [Not(Equal(:address, 'address')), Equal(:age, 42)] - ) } + specify do + query do + must(email == 'email').should(address != 'address', age == 42) + .must_not(sex == 'm').must(name == 'name') + end.should be_eql Bool( + must: [Equal(:email, 'email'), Equal(:name, 'name')], + must_not: [Equal(:sex, 'm')], + should: [Not(Equal(:address, 'address')), Equal(:age, 42)] + ) + end end context 'exists' do @@ -68,7 +76,7 @@ def query &block specify { expect(query { emails.first? }).to be_eql Exists('emails.first') } specify { expect(query { !!emails.first? }).to be_eql Exists('emails.first') } specify { expect(query { emails != nil }).to be_eql Exists('emails') } - specify { expect(query { !(emails == nil) }).to be_eql Exists('emails') } + specify { expect(query { emails != nil }).to be_eql Exists('emails') } end context 'missing' do @@ -111,63 +119,79 @@ def query &block context 'query' do let(:some_query) { 'some query' } specify { expect(query { q('some query') }).to be_eql Query('some query') } - specify { expect(query { q{'some query'} }).to be_eql Query('some query') } - specify { expect(query { q{ some_query } }).to be_eql Query('some query') } + specify { expect(query { q { 'some query' } }).to be_eql Query('some query') } + specify { expect(query { q { some_query } }).to be_eql Query('some query') } end context 'raw' do - let(:raw_query) { {term: {name: 'name'}} } - specify { expect(query { r(term: {name: 'name'}) }).to be_eql Raw(term: {name: 'name'}) } - specify { expect(query { r{ {term: {name: 'name'}} } }).to be_eql Raw(term: {name: 'name'}) } - specify { expect(query { r{ raw_query } }).to be_eql Raw(term: {name: 'name'}) } + let(:raw_query) { { term: { name: 'name' } } } + specify { expect(query { r(term: { name: 'name' }) }).to be_eql Raw(term: { name: 'name' }) } + specify { expect(query { r { { term: { name: 'name' } } } }).to be_eql Raw(term: { name: 'name' }) } + specify { expect(query { r { raw_query } }).to be_eql Raw(term: { name: 'name' }) } end context 'script' do let(:some_script) { 'some script' } specify { expect(query { s('some script') }).to be_eql Script('some script') } specify { expect(query { s('some script', param1: 42) }).to be_eql Script('some script', param1: 42) } - specify { expect(query { s{'some script'} }).to be_eql Script('some script') } + specify { expect(query { s { 'some script' } }).to be_eql Script('some script') } specify { expect(query { s(param1: 42) { some_script } }).to be_eql Script('some script', param1: 42) } end context 'and or not' do - specify { expect(query { (email == 'email') & (name == 'name') }) - .to be_eql And(Equal(:email, 'email'), Equal(:name, 'name')) } - specify { expect(query { (email == 'email') | (name == 'name') }) - .to be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) } + specify do + expect(query { (email == 'email') & (name == 'name') }) + .to be_eql And(Equal(:email, 'email'), Equal(:name, 'name')) + end + specify do + expect(query { (email == 'email') | (name == 'name') }) + .to be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) + end specify { expect(query { !(email == 'email') }).to be_eql Not(Equal(:email, 'email')) } - specify { expect(query { (email == 'email') & (name == 'name') | (address != 'address') }) - .to be_eql Or( - And( + specify do + expect(query { (email == 'email') & (name == 'name') | (address != 'address') }) + .to be_eql Or( + And( + Equal(:email, 'email'), + Equal(:name, 'name') + ), + Not(Equal(:address, 'address')) + ) + end + specify do + expect(query { (email == 'email') & ((name == 'name') | (address != 'address')) }) + .to be_eql And( + Equal(:email, 'email'), + Or( + Equal(:name, 'name'), + Not(Equal(:address, 'address')) + ) + ) + end + specify do + expect(query { (email == 'email') & ((name == 'name') & (address != 'address')) }) + .to be_eql And( Equal(:email, 'email'), - Equal(:name, 'name') - ), - Not(Equal(:address, 'address')) - ) } - specify { expect(query { (email == 'email') & ((name == 'name') | (address != 'address')) }) - .to be_eql And( - Equal(:email, 'email'), - Or( Equal(:name, 'name'), - Not(Equal(:address, 'address')), + Not(Equal(:address, 'address')) ) - ) } - specify { expect(query { (email == 'email') & ((name == 'name') & (address != 'address')) }) - .to be_eql And( - Equal(:email, 'email'), - Equal(:name, 'name'), - Not(Equal(:address, 'address')), - ) } - specify { expect(query { ((email == 'email') | (name == 'name')) | (address != 'address') }) - .to be_eql Or( - Equal(:email, 'email'), - Equal(:name, 'name'), - Not(Equal(:address, 'address')), - ) } - specify { expect(query { !((email == 'email') | (name == 'name')) }) - .to be_eql Not(Or(Equal(:email, 'email'), Equal(:name, 'name'))) } - specify { expect(query { !!((email == 'email') | (name == 'name')) }) - .to be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) } + end + specify do + expect(query { ((email == 'email') | (name == 'name')) | (address != 'address') }) + .to be_eql Or( + Equal(:email, 'email'), + Equal(:name, 'name'), + Not(Equal(:address, 'address')) + ) + end + specify do + expect(query { !((email == 'email') | (name == 'name')) }) + .to be_eql Not(Or(Equal(:email, 'email'), Equal(:name, 'name'))) + end + specify do + expect(query { !!((email == 'email') | (name == 'name')) }) + .to be_eql Or(Equal(:email, 'email'), Equal(:name, 'name')) + end end end diff --git a/spec/chewy/query/loading_spec.rb b/spec/chewy/query/loading_spec.rb index ae98b391f..49b58e133 100644 --- a/spec/chewy/query/loading_spec.rb +++ b/spec/chewy/query/loading_spec.rb @@ -15,11 +15,11 @@ before do stub_index(:places) do define_type City do - field :rating, type: 'integer', value: ->(o){ o.rating } + field :rating, type: 'integer', value: ->(o) { o.rating } end define_type Country do - field :rating, type: 'integer', value: ->(o){ o.rating } + field :rating, type: 'integer', value: ->(o) { o.rating } end end end @@ -31,55 +31,91 @@ specify { expect(PlacesIndex.order(:rating).limit(6).load).to match_array(cities.first(3) + countries.first(3)) } context 'mongoid', :mongoid do - specify { expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: ->{ where(:rating.lt => 2) } })) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } - specify { expect(PlacesIndex.limit(6).load(city: { scope: ->{ where(:rating.lt => 2) } }).order(:rating)) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } - specify { expect(PlacesIndex.order(:rating).limit(6).load(scope: ->{ where(:rating.lt => 2) })) - .to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } - specify { expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: City.where(:rating.lt => 2) })) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } + specify do + expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: -> { where(:rating.lt => 2) } })) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end + specify do + expect(PlacesIndex.limit(6).load(city: { scope: -> { where(:rating.lt => 2) } }).order(:rating)) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).load(scope: -> { where(:rating.lt => 2) })) + .to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: City.where(:rating.lt => 2) })) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end end context 'active record', :active_record do - specify { expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: ->{ where('rating < 2') } })) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } - specify { expect(PlacesIndex.limit(6).load(city: { scope: ->{ where('rating < 2') } }).order(:rating)) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } - specify { expect(PlacesIndex.order(:rating).limit(6).load(scope: ->{ where('rating < 2') })) - .to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } - specify { expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: City.where('rating < 2') })) - .to match_array(cities.first(2) + countries.first(3) + [nil]) } + specify do + expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: -> { where('rating < 2') } })) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end + specify do + expect(PlacesIndex.limit(6).load(city: { scope: -> { where('rating < 2') } }).order(:rating)) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).load(scope: -> { where('rating < 2') })) + .to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).load(city: { scope: City.where('rating < 2') })) + .to match_array(cities.first(2) + countries.first(3) + [nil]) + end end end describe '#preload' do context 'mongoid', :mongoid do - specify { expect(PlacesIndex.order(:rating).limit(6).preload(scope: ->{ where(:rating.lt => 2) }) - .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } - specify { expect(PlacesIndex.limit(6).preload(scope: ->{ where(:rating.lt => 2) }).order(:rating) - .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(scope: -> { where(:rating.lt => 2) }) + .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end + specify do + expect(PlacesIndex.limit(6).preload(scope: -> { where(:rating.lt => 2) }).order(:rating) + .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end - specify { expect(PlacesIndex.order(:rating).limit(6).preload(only: :city, scope: ->{ where(:rating.lt => 2) }) - .map(&:_object)).to match_array(cities.first(2) + [nil] * 4) } - specify { expect(PlacesIndex.order(:rating).limit(6).preload(except: [:city], scope: ->{ where(:rating.lt => 2) }) - .map(&:_object)).to match_array(countries.first(2) + [nil] * 4) } - specify { expect(PlacesIndex.order(:rating).limit(6).preload(only: [:city], except: :city, scope: ->{ where(:rating.lt => 2) }) - .map(&:_object)).to match_array([nil] * 6) } + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(only: :city, scope: -> { where(:rating.lt => 2) }) + .map(&:_object)).to match_array(cities.first(2) + [nil] * 4) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(except: [:city], scope: -> { where(:rating.lt => 2) }) + .map(&:_object)).to match_array(countries.first(2) + [nil] * 4) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(only: [:city], except: :city, scope: -> { where(:rating.lt => 2) }) + .map(&:_object)).to match_array([nil] * 6) + end end context 'active record', :active_record do - specify { expect(PlacesIndex.order(:rating).limit(6).preload(scope: ->{ where('rating < 2') }) - .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } - specify { expect(PlacesIndex.limit(6).preload(scope: ->{ where('rating < 2') }).order(:rating) - .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) } + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(scope: -> { where('rating < 2') }) + .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end + specify do + expect(PlacesIndex.limit(6).preload(scope: -> { where('rating < 2') }).order(:rating) + .map(&:_object)).to match_array(cities.first(2) + countries.first(2) + [nil] * 2) + end - specify { expect(PlacesIndex.order(:rating).limit(6).preload(only: :city, scope: ->{ where('rating < 2') }) - .map(&:_object)).to match_array(cities.first(2) + [nil] * 4) } - specify { expect(PlacesIndex.order(:rating).limit(6).preload(except: [:city], scope: ->{ where('rating < 2') }) - .map(&:_object)).to match_array(countries.first(2) + [nil] * 4) } - specify { expect(PlacesIndex.order(:rating).limit(6).preload(only: [:city], except: :city, scope: ->{ where('rating < 2') }) - .map(&:_object)).to match_array([nil] * 6) } + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(only: :city, scope: -> { where('rating < 2') }) + .map(&:_object)).to match_array(cities.first(2) + [nil] * 4) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(except: [:city], scope: -> { where('rating < 2') }) + .map(&:_object)).to match_array(countries.first(2) + [nil] * 4) + end + specify do + expect(PlacesIndex.order(:rating).limit(6).preload(only: [:city], except: :city, scope: -> { where('rating < 2') }) + .map(&:_object)).to match_array([nil] * 6) + end end end end diff --git a/spec/chewy/query/nodes/and_spec.rb b/spec/chewy/query/nodes/and_spec.rb index c58aa8eac..9f5ff1ec7 100644 --- a/spec/chewy/query/nodes/and_spec.rb +++ b/spec/chewy/query/nodes/and_spec.rb @@ -2,15 +2,11 @@ describe Chewy::Query::Nodes::And do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { name? & (email == 'email') }).to eq({ - and: [{exists: {field: 'name'}}, {term: {'email' => 'email'}}] - }) } - specify { expect(render { ~(name? & (email == 'email')) }).to eq({ - and: {filters: [{exists: {field: 'name'}}, {term: {'email' => 'email'}}], _cache: true} - }) } + specify { expect(render { name? & (email == 'email') }).to eq(and: [{ exists: { field: 'name' } }, { term: { 'email' => 'email' } }]) } + specify { expect(render { ~(name? & (email == 'email')) }).to eq(and: { filters: [{ exists: { field: 'name' } }, { term: { 'email' => 'email' } }], _cache: true }) } end end diff --git a/spec/chewy/query/nodes/bool_spec.rb b/spec/chewy/query/nodes/bool_spec.rb index a99483489..1062183ea 100644 --- a/spec/chewy/query/nodes/bool_spec.rb +++ b/spec/chewy/query/nodes/bool_spec.rb @@ -2,21 +2,13 @@ describe Chewy::Query::Nodes::Bool do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { must(name == 'name', email == 'email') }).to eq({ - bool: {must: [{term: {'name' => 'name'}}, {term: {'email' => 'email'}}] - } }) } - specify { expect(render { must(name == 'name').must_not(email == 'email') }).to eq({ - bool: {must: [{term: {'name' => 'name'}}], must_not: [{term: {'email' => 'email'}}] - } }) } - specify { expect(render { must(name == 'name').should(email == 'email') }).to eq({ - bool: {must: [{term: {'name' => 'name'}}], should: [{ term: {'email' => 'email'}}] - } }) } - specify { expect(render { ~must(name == 'name').should(email == 'email') }).to eq({ - bool: {must: [{term: {'name' => 'name'}}], should: [{ term: {'email' => 'email'}}], _cache: true - } }) } + specify { expect(render { must(name == 'name', email == 'email') }).to eq(bool: { must: [{ term: { 'name' => 'name' } }, { term: { 'email' => 'email' } }] }) } + specify { expect(render { must(name == 'name').must_not(email == 'email') }).to eq(bool: { must: [{ term: { 'name' => 'name' } }], must_not: [{ term: { 'email' => 'email' } }] }) } + specify { expect(render { must(name == 'name').should(email == 'email') }).to eq(bool: { must: [{ term: { 'name' => 'name' } }], should: [{ term: { 'email' => 'email' } }] }) } + specify { expect(render { ~must(name == 'name').should(email == 'email') }).to eq(bool: { must: [{ term: { 'name' => 'name' } }], should: [{ term: { 'email' => 'email' } }], _cache: true }) } end end diff --git a/spec/chewy/query/nodes/equal_spec.rb b/spec/chewy/query/nodes/equal_spec.rb index 066588f79..a70b7393b 100644 --- a/spec/chewy/query/nodes/equal_spec.rb +++ b/spec/chewy/query/nodes/equal_spec.rb @@ -2,31 +2,31 @@ describe Chewy::Query::Nodes::Equal do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { name == 'name' }).to eq({term: {'name' => 'name'}}) } - specify { expect(render { name != 'name' }).to eq({not: {term: {'name' => 'name'}}}) } - specify { expect(render { name == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2']}}) } - specify { expect(render { name != ['name1', 'name2'] }).to eq({not: {terms: {'name' => ['name1', 'name2']}}}) } + specify { expect(render { name == 'name' }).to eq(term: { 'name' => 'name' }) } + specify { expect(render { name != 'name' }).to eq(not: { term: { 'name' => 'name' } }) } + specify { expect(render { name == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2) }) } + specify { expect(render { name != %w(name1 name2) }).to eq(not: { terms: { 'name' => %w(name1 name2) } }) } - specify { expect(render { name(:bool) == 'name' }).to eq({term: {'name' => 'name'}}) } - specify { expect(render { name(:borogoves) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2']}}) } + specify { expect(render { name(:bool) == 'name' }).to eq(term: { 'name' => 'name' }) } + specify { expect(render { name(:borogoves) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2) }) } - specify { expect(render { name(:|) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :or}}) } - specify { expect(render { name(:or) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :or}}) } - specify { expect(render { name(:&) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :and}}) } - specify { expect(render { name(:and) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :and}}) } - specify { expect(render { name(:b) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :bool}}) } - specify { expect(render { name(:bool) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :bool}}) } - specify { expect(render { name(:f) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :fielddata}}) } - specify { expect(render { name(:fielddata) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :fielddata}}) } + specify { expect(render { name(:|) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :or }) } + specify { expect(render { name(:or) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :or }) } + specify { expect(render { name(:&) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :and }) } + specify { expect(render { name(:and) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :and }) } + specify { expect(render { name(:b) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :bool }) } + specify { expect(render { name(:bool) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :bool }) } + specify { expect(render { name(:f) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :fielddata }) } + specify { expect(render { name(:fielddata) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :fielddata }) } - specify { expect(render { ~name == 'name' }).to eq({term: {'name' => 'name', _cache: true}}) } - specify { expect(render { ~(name == 'name') }).to eq({term: {'name' => 'name', _cache: true}}) } - specify { expect(render { ~name != 'name' }).to eq({not: {term: {'name' => 'name', _cache: true}}}) } - specify { expect(render { ~name(:|) == ['name1', 'name2'] }).to eq({terms: {'name' => ['name1', 'name2'], execution: :or, _cache: true}}) } - specify { expect(render { ~name != ['name1', 'name2'] }).to eq({not: {terms: {'name' => ['name1', 'name2'], _cache: true}}}) } + specify { expect(render { ~name == 'name' }).to eq(term: { 'name' => 'name', _cache: true }) } + specify { expect(render { ~(name == 'name') }).to eq(term: { 'name' => 'name', _cache: true }) } + specify { expect(render { ~name != 'name' }).to eq(not: { term: { 'name' => 'name', _cache: true } }) } + specify { expect(render { ~name(:|) == %w(name1 name2) }).to eq(terms: { 'name' => %w(name1 name2), execution: :or, _cache: true }) } + specify { expect(render { ~name != %w(name1 name2) }).to eq(not: { terms: { 'name' => %w(name1 name2), _cache: true } }) } end end diff --git a/spec/chewy/query/nodes/exists_spec.rb b/spec/chewy/query/nodes/exists_spec.rb index 6102f3015..e391f87a9 100644 --- a/spec/chewy/query/nodes/exists_spec.rb +++ b/spec/chewy/query/nodes/exists_spec.rb @@ -2,17 +2,17 @@ describe Chewy::Query::Nodes::Exists do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { name? }).to eq({exists: {field: 'name'}}) } + specify { expect(render { name? }).to eq(exists: { field: 'name' }) } - specify { expect(render { !!name? }).to eq({exists: {field: 'name'}}) } - specify { expect(render { !!name }).to eq({exists: {field: 'name'}}) } - specify { expect(render { name != nil }).to eq({exists: {field: 'name'}}) } - specify { expect(render { !(name == nil) }).to eq({exists: {field: 'name'}}) } + specify { expect(render { !!name? }).to eq(exists: { field: 'name' }) } + specify { expect(render { !!name }).to eq(exists: { field: 'name' }) } + specify { expect(render { name != nil }).to eq(exists: { field: 'name' }) } + specify { expect(render { name != nil }).to eq(exists: { field: 'name' }) } - specify { expect(render { ~name? }).to eq({exists: {field: 'name'}}) } + specify { expect(render { ~name? }).to eq(exists: { field: 'name' }) } end end diff --git a/spec/chewy/query/nodes/has_child_spec.rb b/spec/chewy/query/nodes/has_child_spec.rb index bcf080444..2050f73f3 100644 --- a/spec/chewy/query/nodes/has_child_spec.rb +++ b/spec/chewy/query/nodes/has_child_spec.rb @@ -2,39 +2,58 @@ describe Chewy::Query::Nodes::HasChild do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { has_child('child') }).to eq({has_child: {type: 'child'}}) } + specify { expect(render { has_child('child') }).to eq(has_child: { type: 'child' }) } + specify do + expect(render { has_child('child').filter(term: { name: 'name' }) }) + .to eq(has_child: { type: 'child', filter: { term: { name: 'name' } } }) + end + specify do + expect(render { has_child('child').filter { name == 'name' } }) + .to eq(has_child: { type: 'child', filter: { term: { 'name' => 'name' } } }) + end + specify do + expect(render { has_child('child').filter(term: { name: 'name' }).filter { age < 42 } }) + .to eq(has_child: { type: 'child', filter: { and: [{ term: { name: 'name' } }, range: { 'age' => { lt: 42 } }] } }) + end + specify do + expect(render { has_child('child').filter(term: { name: 'name' }).filter { age < 42 }.filter_mode(:or) }) + .to eq(has_child: { type: 'child', filter: { or: [{ term: { name: 'name' } }, range: { 'age' => { lt: 42 } }] } }) + end - specify { expect(render { has_child('child').filter(term: {name: 'name'}) }) - .to eq({has_child: {type: 'child', filter: {term: {name: 'name'}}}}) } - specify { expect(render { has_child('child').filter{ name == 'name' } }) - .to eq({has_child: {type: 'child', filter: {term: {'name' => 'name'}}}}) } - specify { expect(render { has_child('child').filter(term: {name: 'name'}).filter{ age < 42 } }) - .to eq({has_child: {type: 'child', filter: {and: [{term: {name: 'name'}}, range: {'age' => {lt: 42}}]}}}) } - specify { expect(render { has_child('child').filter(term: {name: 'name'}).filter{ age < 42 }.filter_mode(:or) }) - .to eq({has_child: {type: 'child', filter: {or: [{term: {name: 'name'}}, range: {'age' => {lt: 42}}]}}}) } - - specify { expect(render { has_child('child').query(match: {name: 'name'}) }) - .to eq({has_child: {type: 'child', query: {match: {name: 'name'}}}}) } - specify { expect(render { has_child('child').query(match: {name: 'name'}).query(match: {surname: 'surname'}) }) - .to eq({has_child: {type: 'child', query: {bool: {must: [{match: {name: 'name'}}, {match: {surname: 'surname'}}]}}}}) } - specify { expect(render { has_child('child').query(match: {name: 'name'}).query(match: {surname: 'surname'}).query_mode(:should) }) - .to eq({has_child: {type: 'child', query: {bool: {should: [{match: {name: 'name'}}, {match: {surname: 'surname'}}]}}}}) } + specify do + expect(render { has_child('child').query(match: { name: 'name' }) }) + .to eq(has_child: { type: 'child', query: { match: { name: 'name' } } }) + end + specify do + expect(render { has_child('child').query(match: { name: 'name' }).query(match: { surname: 'surname' }) }) + .to eq(has_child: { type: 'child', query: { bool: { must: [{ match: { name: 'name' } }, { match: { surname: 'surname' } }] } } }) + end + specify do + expect(render { has_child('child').query(match: { name: 'name' }).query(match: { surname: 'surname' }).query_mode(:should) }) + .to eq(has_child: { type: 'child', query: { bool: { should: [{ match: { name: 'name' } }, { match: { surname: 'surname' } }] } } }) + end - specify { expect(render { has_child('child').filter{ name == 'name' }.query(match: {name: 'name'}) }) - .to eq({has_child: {type: 'child', query: {filtered: {query: {match: {name: 'name'}}, filter: {term: {'name' => 'name'}}}}}}) } - specify { expect(render { has_child('child').filter{ name == 'name' }.query(match: {name: 'name'}).filter{ age < 42 } }) - .to eq({has_child: {type: 'child', query: {filtered: {query: {match: {name: 'name'}}, filter: {and: [{term: {'name' => 'name'}}, range: {'age' => {lt: 42}}]}}}}}) } + specify do + expect(render { has_child('child').filter { name == 'name' }.query(match: { name: 'name' }) }) + .to eq(has_child: { type: 'child', query: { filtered: { query: { match: { name: 'name' } }, filter: { term: { 'name' => 'name' } } } } }) + end + specify do + expect(render { has_child('child').filter { name == 'name' }.query(match: { name: 'name' }).filter { age < 42 } }) + .to eq(has_child: { type: 'child', query: { filtered: { query: { match: { name: 'name' } }, filter: { and: [{ term: { 'name' => 'name' } }, range: { 'age' => { lt: 42 } }] } } } }) + end context do let(:name) { 'Name' } - specify { expect(render { has_child('child').filter{ name == o{name} } }) - .to eq({has_child: {type: 'child', filter: {term: {'name' => 'Name'}}}}) } + specify do + expect(render { has_child('child').filter { name == o { name } } }) + .to eq(has_child: { type: 'child', filter: { term: { 'name' => 'Name' } } }) + end end end end diff --git a/spec/chewy/query/nodes/has_parent_spec.rb b/spec/chewy/query/nodes/has_parent_spec.rb index 3a2f59c49..88deac668 100644 --- a/spec/chewy/query/nodes/has_parent_spec.rb +++ b/spec/chewy/query/nodes/has_parent_spec.rb @@ -2,39 +2,58 @@ describe Chewy::Query::Nodes::HasParent do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { has_parent('child') }).to eq({has_parent: {type: 'child'}}) } + specify { expect(render { has_parent('child') }).to eq(has_parent: { type: 'child' }) } + specify do + expect(render { has_parent('child').filter(term: { name: 'name' }) }) + .to eq(has_parent: { type: 'child', filter: { term: { name: 'name' } } }) + end + specify do + expect(render { has_parent('child').filter { name == 'name' } }) + .to eq(has_parent: { type: 'child', filter: { term: { 'name' => 'name' } } }) + end + specify do + expect(render { has_parent('child').filter(term: { name: 'name' }).filter { age < 42 } }) + .to eq(has_parent: { type: 'child', filter: { and: [{ term: { name: 'name' } }, range: { 'age' => { lt: 42 } }] } }) + end + specify do + expect(render { has_parent('child').filter(term: { name: 'name' }).filter { age < 42 }.filter_mode(:or) }) + .to eq(has_parent: { type: 'child', filter: { or: [{ term: { name: 'name' } }, range: { 'age' => { lt: 42 } }] } }) + end - specify { expect(render { has_parent('child').filter(term: {name: 'name'}) }) - .to eq({has_parent: {type: 'child', filter: {term: {name: 'name'}}}}) } - specify { expect(render { has_parent('child').filter{ name == 'name' } }) - .to eq({has_parent: {type: 'child', filter: {term: {'name' => 'name'}}}}) } - specify { expect(render { has_parent('child').filter(term: {name: 'name'}).filter{ age < 42 } }) - .to eq({has_parent: {type: 'child', filter: {and: [{term: {name: 'name'}}, range: {'age' => {lt: 42}}]}}}) } - specify { expect(render { has_parent('child').filter(term: {name: 'name'}).filter{ age < 42 }.filter_mode(:or) }) - .to eq({has_parent: {type: 'child', filter: {or: [{term: {name: 'name'}}, range: {'age' => {lt: 42}}]}}}) } - - specify { expect(render { has_parent('child').query(match: {name: 'name'}) }) - .to eq({has_parent: {type: 'child', query: {match: {name: 'name'}}}}) } - specify { expect(render { has_parent('child').query(match: {name: 'name'}).query(match: {surname: 'surname'}) }) - .to eq({has_parent: {type: 'child', query: {bool: {must: [{match: {name: 'name'}}, {match: {surname: 'surname'}}]}}}}) } - specify { expect(render { has_parent('child').query(match: {name: 'name'}).query(match: {surname: 'surname'}).query_mode(:should) }) - .to eq({has_parent: {type: 'child', query: {bool: {should: [{match: {name: 'name'}}, {match: {surname: 'surname'}}]}}}}) } + specify do + expect(render { has_parent('child').query(match: { name: 'name' }) }) + .to eq(has_parent: { type: 'child', query: { match: { name: 'name' } } }) + end + specify do + expect(render { has_parent('child').query(match: { name: 'name' }).query(match: { surname: 'surname' }) }) + .to eq(has_parent: { type: 'child', query: { bool: { must: [{ match: { name: 'name' } }, { match: { surname: 'surname' } }] } } }) + end + specify do + expect(render { has_parent('child').query(match: { name: 'name' }).query(match: { surname: 'surname' }).query_mode(:should) }) + .to eq(has_parent: { type: 'child', query: { bool: { should: [{ match: { name: 'name' } }, { match: { surname: 'surname' } }] } } }) + end - specify { expect(render { has_parent('child').filter{ name == 'name' }.query(match: {name: 'name'}) }) - .to eq({has_parent: {type: 'child', query: {filtered: {query: {match: {name: 'name'}}, filter: {term: {'name' => 'name'}}}}}}) } - specify { expect(render { has_parent('child').filter{ name == 'name' }.query(match: {name: 'name'}).filter{ age < 42 } }) - .to eq({has_parent: {type: 'child', query: {filtered: {query: {match: {name: 'name'}}, filter: {and: [{term: {'name' => 'name'}}, range: {'age' => {lt: 42}}]}}}}}) } + specify do + expect(render { has_parent('child').filter { name == 'name' }.query(match: { name: 'name' }) }) + .to eq(has_parent: { type: 'child', query: { filtered: { query: { match: { name: 'name' } }, filter: { term: { 'name' => 'name' } } } } }) + end + specify do + expect(render { has_parent('child').filter { name == 'name' }.query(match: { name: 'name' }).filter { age < 42 } }) + .to eq(has_parent: { type: 'child', query: { filtered: { query: { match: { name: 'name' } }, filter: { and: [{ term: { 'name' => 'name' } }, range: { 'age' => { lt: 42 } }] } } } }) + end context do let(:name) { 'Name' } - specify { expect(render { has_parent('child').filter{ name == o{name} } }) - .to eq({has_parent: {type: 'child', filter: {term: {'name' => 'Name'}}}}) } + specify do + expect(render { has_parent('child').filter { name == o { name } } }) + .to eq(has_parent: { type: 'child', filter: { term: { 'name' => 'Name' } } }) + end end end end diff --git a/spec/chewy/query/nodes/match_all_spec.rb b/spec/chewy/query/nodes/match_all_spec.rb index bfb482422..d74f8f3ae 100644 --- a/spec/chewy/query/nodes/match_all_spec.rb +++ b/spec/chewy/query/nodes/match_all_spec.rb @@ -2,10 +2,10 @@ describe Chewy::Query::Nodes::MatchAll do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { match_all }).to eq({match_all: {}}) } + specify { expect(render { match_all }).to eq(match_all: {}) } end end diff --git a/spec/chewy/query/nodes/missing_spec.rb b/spec/chewy/query/nodes/missing_spec.rb index 0b857d2b6..a4ea46610 100644 --- a/spec/chewy/query/nodes/missing_spec.rb +++ b/spec/chewy/query/nodes/missing_spec.rb @@ -2,14 +2,14 @@ describe Chewy::Query::Nodes::Missing do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { !name }).to eq({missing: {field: 'name', existence: true, null_value: false}}) } - specify { expect(render { !name? }).to eq({missing: {field: 'name', existence: true, null_value: true}}) } - specify { expect(render { name == nil }).to eq({missing: {field: 'name', existence: false, null_value: true}}) } + specify { expect(render { !name }).to eq(missing: { field: 'name', existence: true, null_value: false }) } + specify { expect(render { !name? }).to eq(missing: { field: 'name', existence: true, null_value: true }) } + specify { expect(render { name == nil }).to eq(missing: { field: 'name', existence: false, null_value: true }) } - specify { expect(render { ~!name }).to eq({missing: {field: 'name', existence: true, null_value: false}}) } + specify { expect(render { ~!name }).to eq(missing: { field: 'name', existence: true, null_value: false }) } end end diff --git a/spec/chewy/query/nodes/not_spec.rb b/spec/chewy/query/nodes/not_spec.rb index 9c2e82445..f090e04a1 100644 --- a/spec/chewy/query/nodes/not_spec.rb +++ b/spec/chewy/query/nodes/not_spec.rb @@ -2,15 +2,11 @@ describe Chewy::Query::Nodes::Not do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { !(email == 'email') }).to eq({ - not: {term: {'email' => 'email'}} - }) } - specify { expect(render { ~!(email == 'email') }).to eq({ - not: {filter: {term: {'email' => 'email'}}, _cache: true} - }) } + specify { expect(render { !(email == 'email') }).to eq(not: { term: { 'email' => 'email' } }) } + specify { expect(render { ~!(email == 'email') }).to eq(not: { filter: { term: { 'email' => 'email' } }, _cache: true }) } end end diff --git a/spec/chewy/query/nodes/or_spec.rb b/spec/chewy/query/nodes/or_spec.rb index 2641f452c..66fb3c96c 100644 --- a/spec/chewy/query/nodes/or_spec.rb +++ b/spec/chewy/query/nodes/or_spec.rb @@ -2,15 +2,11 @@ describe Chewy::Query::Nodes::Or do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { name? | (email == 'email') }).to eq({ - or: [{exists: {field: 'name'}}, {term: {'email' => 'email'}}] - }) } - specify { expect(render { ~(name? | (email == 'email')) }).to eq({ - or: {filters: [{exists: {field: 'name'}}, {term: {'email' => 'email'}}], _cache: true} - }) } + specify { expect(render { name? | (email == 'email') }).to eq(or: [{ exists: { field: 'name' } }, { term: { 'email' => 'email' } }]) } + specify { expect(render { ~(name? | (email == 'email')) }).to eq(or: { filters: [{ exists: { field: 'name' } }, { term: { 'email' => 'email' } }], _cache: true }) } end end diff --git a/spec/chewy/query/nodes/prefix_spec.rb b/spec/chewy/query/nodes/prefix_spec.rb index cbf951874..6cdab6426 100644 --- a/spec/chewy/query/nodes/prefix_spec.rb +++ b/spec/chewy/query/nodes/prefix_spec.rb @@ -2,15 +2,15 @@ describe Chewy::Query::Nodes::Prefix do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { name =~ 'nam' }).to eq({prefix: {'name' => 'nam'}}) } - specify { expect(render { name !~ 'nam' }).to eq({not: {prefix: {'name' => 'nam'}}}) } + specify { expect(render { name =~ 'nam' }).to eq(prefix: { 'name' => 'nam' }) } + specify { expect(render { name !~ 'nam' }).to eq(not: { prefix: { 'name' => 'nam' } }) } - specify { expect(render { ~name =~ 'nam' }).to eq({prefix: {'name' => 'nam', _cache: true}}) } - specify { expect(render { ~name !~ 'nam' }).to eq({not: {prefix: {'name' => 'nam', _cache: true}}}) } - specify { expect(render { name(cache: false) =~ 'nam' }).to eq({prefix: {'name' => 'nam', _cache: false}}) } + specify { expect(render { ~name =~ 'nam' }).to eq(prefix: { 'name' => 'nam', _cache: true }) } + specify { expect(render { ~name !~ 'nam' }).to eq(not: { prefix: { 'name' => 'nam', _cache: true } }) } + specify { expect(render { name(cache: false) =~ 'nam' }).to eq(prefix: { 'name' => 'nam', _cache: false }) } end end diff --git a/spec/chewy/query/nodes/query_spec.rb b/spec/chewy/query/nodes/query_spec.rb index 589a609b1..56897f112 100644 --- a/spec/chewy/query/nodes/query_spec.rb +++ b/spec/chewy/query/nodes/query_spec.rb @@ -2,11 +2,11 @@ describe Chewy::Query::Nodes::Query do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { q(query_string: {query: 'name: hello'}) }).to eq({query: {query_string: {query: 'name: hello'}}}) } - specify { expect(render { ~q(query_string: {query: 'name: hello'}) }).to eq({fquery: {query: {query_string: {query: 'name: hello'}}, _cache: true}}) } + specify { expect(render { q(query_string: { query: 'name: hello' }) }).to eq(query: { query_string: { query: 'name: hello' } }) } + specify { expect(render { ~q(query_string: { query: 'name: hello' }) }).to eq(fquery: { query: { query_string: { query: 'name: hello' } }, _cache: true }) } end end diff --git a/spec/chewy/query/nodes/range_spec.rb b/spec/chewy/query/nodes/range_spec.rb index c7c3734d6..f44a46a9e 100644 --- a/spec/chewy/query/nodes/range_spec.rb +++ b/spec/chewy/query/nodes/range_spec.rb @@ -2,31 +2,31 @@ describe Chewy::Query::Nodes::Range do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { age > nil }).to eq({range: {'age' => {gt: nil}}}) } - specify { expect(render { age == (nil..nil) }).to eq({range: {'age' => {gt: nil, lt: nil}}}) } + specify { expect(render { age > nil }).to eq(range: { 'age' => { gt: nil } }) } + specify { expect(render { age == (nil..nil) }).to eq(range: { 'age' => { gt: nil, lt: nil } }) } - specify { expect(render { age > 42 }).to eq({range: {'age' => {gt: 42}}}) } - specify { expect(render { age == (42..45) }).to eq({range: {'age' => {gt: 42, lt: 45}}}) } - specify { expect(render { age == [42..45] }).to eq({range: {'age' => {gte: 42, lte: 45}}}) } - specify { expect(render { (age > 42) & (age <= 45) }).to eq({range: {'age' => {gt: 42, lte: 45}}}) } + specify { expect(render { age > 42 }).to eq(range: { 'age' => { gt: 42 } }) } + specify { expect(render { age == (42..45) }).to eq(range: { 'age' => { gt: 42, lt: 45 } }) } + specify { expect(render { age == [42..45] }).to eq(range: { 'age' => { gte: 42, lte: 45 } }) } + specify { expect(render { (age > 42) & (age <= 45) }).to eq(range: { 'age' => { gt: 42, lte: 45 } }) } - specify { expect(render { ~age > 42 }).to eq({range: {'age' => {gt: 42}, _cache: true}}) } - specify { expect(render { ~age == (42..45) }).to eq({range: {'age' => {gt: 42, lt: 45}, _cache: true}}) } - specify { expect(render { ~age == [42..45] }).to eq({range: {'age' => {gte: 42, lte: 45}, _cache: true}}) } - specify { expect(render { (age > 42) & ~(age <= 45) }).to eq({range: {'age' => {gt: 42, lte: 45}, _cache: true}}) } - specify { expect(render { (~age > 42) & (age <= 45) }).to eq({range: {'age' => {gt: 42, lte: 45}, _cache: true}}) } + specify { expect(render { ~age > 42 }).to eq(range: { 'age' => { gt: 42 }, _cache: true }) } + specify { expect(render { ~age == (42..45) }).to eq(range: { 'age' => { gt: 42, lt: 45 }, _cache: true }) } + specify { expect(render { ~age == [42..45] }).to eq(range: { 'age' => { gte: 42, lte: 45 }, _cache: true }) } + specify { expect(render { (age > 42) & ~(age <= 45) }).to eq(range: { 'age' => { gt: 42, lte: 45 }, _cache: true }) } + specify { expect(render { (~age > 42) & (age <= 45) }).to eq(range: { 'age' => { gt: 42, lte: 45 }, _cache: true }) } - specify { expect(render { age(:i) > 42 }).to eq({range: {'age' => {gt: 42}, execution: :index}}) } - specify { expect(render { age(:index) > 42 }).to eq({range: {'age' => {gt: 42}, execution: :index}}) } - specify { expect(render { age(:f) > 42 }).to eq({range: {'age' => {gt: 42}, execution: :fielddata}}) } - specify { expect(render { age(:fielddata) > 42 }).to eq({range: {'age' => {gt: 42}, execution: :fielddata}}) } - specify { expect(render { (age(:f) > 42) & (age <= 45) }).to eq({range: {'age' => {gt: 42, lte: 45}, execution: :fielddata}}) } + specify { expect(render { age(:i) > 42 }).to eq(range: { 'age' => { gt: 42 }, execution: :index }) } + specify { expect(render { age(:index) > 42 }).to eq(range: { 'age' => { gt: 42 }, execution: :index }) } + specify { expect(render { age(:f) > 42 }).to eq(range: { 'age' => { gt: 42 }, execution: :fielddata }) } + specify { expect(render { age(:fielddata) > 42 }).to eq(range: { 'age' => { gt: 42 }, execution: :fielddata }) } + specify { expect(render { (age(:f) > 42) & (age <= 45) }).to eq(range: { 'age' => { gt: 42, lte: 45 }, execution: :fielddata }) } - specify { expect(render { ~age(:f) > 42 }).to eq({range: {'age' => {gt: 42}, execution: :fielddata, _cache: true}}) } - specify { expect(render { (age(:f) > 42) & (~age <= 45) }).to eq({range: {'age' => {gt: 42, lte: 45}, execution: :fielddata, _cache: true}}) } + specify { expect(render { ~age(:f) > 42 }).to eq(range: { 'age' => { gt: 42 }, execution: :fielddata, _cache: true }) } + specify { expect(render { (age(:f) > 42) & (~age <= 45) }).to eq(range: { 'age' => { gt: 42, lte: 45 }, execution: :fielddata, _cache: true }) } end end diff --git a/spec/chewy/query/nodes/raw_spec.rb b/spec/chewy/query/nodes/raw_spec.rb index 0bcbdb1ce..d1e0ccbab 100644 --- a/spec/chewy/query/nodes/raw_spec.rb +++ b/spec/chewy/query/nodes/raw_spec.rb @@ -2,10 +2,10 @@ describe Chewy::Query::Nodes::Raw do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { r(term: {name: 'name'}) }).to eq({term: {name: 'name'}}) } + specify { expect(render { r(term: { name: 'name' }) }).to eq(term: { name: 'name' }) } end end diff --git a/spec/chewy/query/nodes/regexp_spec.rb b/spec/chewy/query/nodes/regexp_spec.rb index ee80a5264..dc36fdd1c 100644 --- a/spec/chewy/query/nodes/regexp_spec.rb +++ b/spec/chewy/query/nodes/regexp_spec.rb @@ -2,30 +2,42 @@ describe Chewy::Query::Nodes::Regexp do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { names.first == /nam.*/ }).to eq({regexp: {'names.first' => 'nam.*'}}) } - specify { expect(render { names.first =~ /nam.*/ }).to eq({regexp: {'names.first' => 'nam.*'}}) } - specify { expect(render { name != /nam.*/ }).to eq({not: {regexp: {'name' => 'nam.*'}}}) } - specify { expect(render { name !~ /nam.*/ }).to eq({not: {regexp: {'name' => 'nam.*'}}}) } + specify { expect(render { names.first == /nam.*/ }).to eq(regexp: { 'names.first' => 'nam.*' }) } + specify { expect(render { names.first =~ /nam.*/ }).to eq(regexp: { 'names.first' => 'nam.*' }) } + specify { expect(render { name != /nam.*/ }).to eq(not: { regexp: { 'name' => 'nam.*' } }) } + specify { expect(render { name !~ /nam.*/ }).to eq(not: { regexp: { 'name' => 'nam.*' } }) } - specify { expect(render { names.first(flags: [:anystring, :intersection, :borogoves]) == /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}}) } - specify { expect(render { names.first(:anystring, :intersection, :borogoves) == /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}}) } + specify do + expect(render { names.first(flags: [:anystring, :intersection, :borogoves]) == /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING|INTERSECTION' } }) + end + specify do + expect(render { names.first(:anystring, :intersection, :borogoves) == /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING|INTERSECTION' } }) + end - specify { expect(render { names.first(flags: [:anystring, :intersection, :borogoves]) =~ /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}}) } - specify { expect(render { names.first(:anystring, :intersection, :borogoves) =~ /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING|INTERSECTION'}}}) } + specify do + expect(render { names.first(flags: [:anystring, :intersection, :borogoves]) =~ /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING|INTERSECTION' } }) + end + specify do + expect(render { names.first(:anystring, :intersection, :borogoves) =~ /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING|INTERSECTION' } }) + end - specify { expect(render { ~names.first == /nam.*/ }).to eq({regexp: {'names.first' => 'nam.*', _cache: true, _cache_key: 'nam.*'}}) } - specify { expect(render { names.first(cache: 'name') == /nam.*/ }).to eq({regexp: {'names.first' => 'nam.*', _cache: true, _cache_key: 'name'}}) } - specify { expect(render { ~names.first(:anystring) =~ /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING'}, _cache: true, _cache_key: 'nam.*'}}) } - specify { expect(render { names.first(:anystring, cache: 'name') =~ /nam.*/ }) - .to eq({regexp: {'names.first' => {value: 'nam.*', flags: 'ANYSTRING'}, _cache: true, _cache_key: 'name'}}) } + specify { expect(render { ~names.first == /nam.*/ }).to eq(regexp: { 'names.first' => 'nam.*', _cache: true, _cache_key: 'nam.*' }) } + specify { expect(render { names.first(cache: 'name') == /nam.*/ }).to eq(regexp: { 'names.first' => 'nam.*', _cache: true, _cache_key: 'name' }) } + specify do + expect(render { ~names.first(:anystring) =~ /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING' }, _cache: true, _cache_key: 'nam.*' }) + end + specify do + expect(render { names.first(:anystring, cache: 'name') =~ /nam.*/ }) + .to eq(regexp: { 'names.first' => { value: 'nam.*', flags: 'ANYSTRING' }, _cache: true, _cache_key: 'name' }) + end end end diff --git a/spec/chewy/query/nodes/script_spec.rb b/spec/chewy/query/nodes/script_spec.rb index 851197307..9c639285a 100644 --- a/spec/chewy/query/nodes/script_spec.rb +++ b/spec/chewy/query/nodes/script_spec.rb @@ -2,14 +2,14 @@ describe Chewy::Query::Nodes::Script do describe '#__render__' do - def render &block + def render(&block) Chewy::Query::Filters.new(&block).__render__ end - specify { expect(render { s('var = val') }).to eq({script: {script: 'var = val'}}) } - specify { expect(render { s('var = val', val: 42) }).to eq({script: {script: 'var = val', params: {val: 42}}}) } + specify { expect(render { s('var = val') }).to eq(script: { script: 'var = val' }) } + specify { expect(render { s('var = val', val: 42) }).to eq(script: { script: 'var = val', params: { val: 42 } }) } - specify { expect(render { ~s('var = val') }).to eq({script: {script: 'var = val', _cache: true}}) } - specify { expect(render { ~s('var = val', val: 42) }).to eq({script: {script: 'var = val', params: {val: 42}, _cache: true}}) } + specify { expect(render { ~s('var = val') }).to eq(script: { script: 'var = val', _cache: true }) } + specify { expect(render { ~s('var = val', val: 42) }).to eq(script: { script: 'var = val', params: { val: 42 }, _cache: true }) } end end diff --git a/spec/chewy/query/pagination/kaminari_spec.rb b/spec/chewy/query/pagination/kaminari_spec.rb index 5eeb49c28..9f1c0f301 100644 --- a/spec/chewy/query/pagination/kaminari_spec.rb +++ b/spec/chewy/query/pagination/kaminari_spec.rb @@ -18,7 +18,7 @@ specify { expect(search.total_pages).to eq(0) } context do - let(:data) { Array.new(10) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } + let(:data) { Array.new(10) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } before { allow(::Kaminari.config).to receive_messages(default_per_page: 3) } @@ -41,7 +41,7 @@ describe '#total_count' do specify { expect(search.per(4).page(1).total_count).to eq(10) } - specify { expect(search.filter(numeric_range: {age: {gt: 20}}).limit(3).total_count).to eq(8) } + specify { expect(search.filter(numeric_range: { age: { gt: 20 } }).limit(3).total_count).to eq(8) } end describe '#load' do diff --git a/spec/chewy/query/pagination/will_paginage_spec.rb b/spec/chewy/query/pagination/will_paginage_spec.rb index a73df6ecd..a6ee3d18f 100644 --- a/spec/chewy/query/pagination/will_paginage_spec.rb +++ b/spec/chewy/query/pagination/will_paginage_spec.rb @@ -1,6 +1,5 @@ require 'spec_helper' - if defined?(::WillPaginate) describe Chewy::Query::Pagination::WillPaginate do before { Chewy.massacre } @@ -16,10 +15,10 @@ let(:search) { ProductsIndex.order(:age) } - specify { expect(search.total_pages).to eq(1) } #defaults to 1 on will_paginate + specify { expect(search.total_pages).to eq(1) } # defaults to 1 on will_paginate context do - let(:data) { Array.new(10) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } + let(:data) { Array.new(10) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } before { allow(::WillPaginate).to receive_messages(per_page: 3) } @@ -30,7 +29,7 @@ specify { expect(search.page(2).map { |e| e.attributes.except('_score', '_explanation') }).to eq(data[3..5]) } end - describe "#paginate" do + describe '#paginate' do specify { expect(search.paginate(page: 2, per_page: 4).map { |e| e.attributes.except('_score', '_explanation') }).to eq(data[4..7]) } specify { expect(search.paginate(per_page: 2, page: 3).page(3).map { |e| e.attributes.except('_score', '_explanation') }).to eq(data[4..5]) } specify { expect(search.paginate(per_page: 5).map { |e| e.attributes.except('_score', '_explanation') }).to eq(data[0..4]) } @@ -44,7 +43,7 @@ describe '#total_entries' do specify { expect(search.paginate(page: 1, per_page: 4).total_entries).to eq(10) } - specify { expect(search.filter(numeric_range: {age: {gt: 20}}).limit(3).total_entries).to eq(8) } + specify { expect(search.filter(numeric_range: { age: { gt: 20 } }).limit(3).total_entries).to eq(8) } end describe '#load' do @@ -52,8 +51,8 @@ specify { expect(search.paginate(per_page: 2, page: 3).load.first.age).to eq(50) } specify { expect(search.paginate(per_page: 2, page: 3).load.page(2).load.first.age).to eq(30) } - specify { expect(search.paginate(per_page:4, page:1).load.total_count).to eq(10) } - specify { expect(search.paginate(per_page:2, page:3).load.total_pages).to eq(5) } + specify { expect(search.paginate(per_page: 4, page: 1).load.total_count).to eq(10) } + specify { expect(search.paginate(per_page: 2, page: 3).load.total_pages).to eq(5) } end end end diff --git a/spec/chewy/query/pagination_spec.rb b/spec/chewy/query/pagination_spec.rb index d52e85c8c..d29f3e3ac 100644 --- a/spec/chewy/query/pagination_spec.rb +++ b/spec/chewy/query/pagination_spec.rb @@ -17,14 +17,14 @@ specify { expect(search.total_count).to eq(0) } context do - let(:data) { Array.new(10) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } + let(:data) { Array.new(10) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } describe '#total_count' do specify { expect(search.total_count).to eq(10) } specify { expect(search.limit(5).total_count).to eq(10) } - specify { expect(search.filter(range: {age: {gt: 20}}).limit(3).total_count).to eq(8) } + specify { expect(search.filter(range: { age: { gt: 20 } }).limit(3).total_count).to eq(8) } end describe '#load' do @@ -32,5 +32,4 @@ specify { expect(search.limit(5).load.total_count).to eq(10) } end end - end diff --git a/spec/chewy/query_spec.rb b/spec/chewy/query_spec.rb index 24650d6d9..cdd335df3 100644 --- a/spec/chewy/query_spec.rb +++ b/spec/chewy/query_spec.rb @@ -20,9 +20,9 @@ end context 'integration' do - let(:products) { Array.new(3) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } - let(:cities) { Array.new(3) { |i| {id: i.next.to_s}.stringify_keys! } } - let(:countries) { Array.new(3) { |i| {id: i.next.to_s}.stringify_keys! } } + let(:products) { Array.new(3) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } + let(:cities) { Array.new(3) { |i| { id: i.next.to_s }.stringify_keys! } } + let(:countries) { Array.new(3) { |i| { id: i.next.to_s }.stringify_keys! } } before do ProductsIndex::Product.import!(products.map { |h| double(h) }) ProductsIndex::City.import!(cities.map { |h| double(h) }) @@ -33,20 +33,20 @@ specify { expect(subject.first._data).to be_a Hash } specify { expect(subject.limit(6).count).to eq(6) } specify { expect(subject.offset(6).count).to eq(3) } - specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name).to eq('Name3') } - specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name_highlight).to eq('Name3') } - specify { expect(subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first._data['_source']['name']).to eq('Name3') } + specify { expect(subject.query(match: { name: 'name3' }).highlight(fields: { name: {} }).first.name).to eq('Name3') } + specify { expect(subject.query(match: { name: 'name3' }).highlight(fields: { name: {} }).first.name_highlight).to eq('Name3') } + specify { expect(subject.query(match: { name: 'name3' }).highlight(fields: { name: {} }).first._data['_source']['name']).to eq('Name3') } specify { expect(subject.types(:product).count).to eq(3) } specify { expect(subject.types(:product, :country).count).to eq(6) } - specify { expect(subject.filter(term: {age: 10}).count).to eq(1) } - specify { expect(subject.query(term: {age: 10}).count).to eq(1) } + specify { expect(subject.filter(term: { age: 10 }).count).to eq(1) } + specify { expect(subject.query(term: { age: 10 }).count).to eq(1) } specify { expect(subject.order(nil).count).to eq(9) } specify { expect(subject.search_type(:count).count).to eq(0) } specify { expect(subject.search_type(:count).total).to eq(9) } end describe '#==' do - let(:data) { Array.new(3) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } + let(:data) { Array.new(3) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } specify { expect(subject.query(match: 'hello')).to eq(subject.query(match: 'hello')) } @@ -96,7 +96,7 @@ specify { expect(subject.limit(10)).not_to eq(subject) } specify { expect(subject.limit(10).criteria.request_options).to include(size: 10) } specify { expect { subject.limit(10) }.not_to change { subject.criteria.request_options } } - specify { expect(subject.limit { 20/2 }.criteria.request_body[:body]).to include(size: 10) } + specify { expect(subject.limit { 20 / 2 }.criteria.request_body[:body]).to include(size: 10) } end describe '#offset' do @@ -104,7 +104,7 @@ specify { expect(subject.offset(10)).not_to eq(subject) } specify { expect(subject.offset(10).criteria.request_options).to include(from: 10) } specify { expect { subject.offset(10) }.not_to change { subject.criteria.request_options } } - specify { expect(subject.offset { 20/2 }.criteria.request_body[:body]).to include(from: 10) } + specify { expect(subject.offset { 20 / 2 }.criteria.request_body[:body]).to include(from: 10) } end describe '#script_fields' do @@ -117,72 +117,74 @@ describe '#script_score' do specify { expect(subject.script_score('23')).to be_a described_class } specify { expect(subject.script_score('23')).not_to eq(subject) } - specify { expect(subject.script_score('23').criteria.scores).to eq([ { script_score: { script: '23' } } ]) } + specify { expect(subject.script_score('23').criteria.scores).to eq([{ script_score: { script: '23' } }]) } specify { expect { subject.script_score('23') }.not_to change { subject.criteria.scores } } - specify { expect(subject.script_score('23 * factor', params: { factor: 0.5}).criteria.scores).to eq([{ script_score: { script: '23 * factor', params: { factor: 0.5} } }]) } + specify { expect(subject.script_score('23 * factor', params: { factor: 0.5 }).criteria.scores).to eq([{ script_score: { script: '23 * factor', params: { factor: 0.5 } } }]) } end describe '#boost_factor' do specify { expect(subject.boost_factor('23')).to be_a described_class } specify { expect(subject.boost_factor('23')).not_to eq(subject) } - specify { expect(subject.boost_factor('23').criteria.scores).to eq([ { boost_factor: 23 } ]) } + specify { expect(subject.boost_factor('23').criteria.scores).to eq([{ boost_factor: 23 }]) } specify { expect { subject.boost_factor('23') }.not_to change { subject.criteria.scores } } - specify { expect(subject.boost_factor('23', filter: { foo: :bar}).criteria.scores).to eq([{ boost_factor: 23, filter: { foo: :bar } }]) } + specify { expect(subject.boost_factor('23', filter: { foo: :bar }).criteria.scores).to eq([{ boost_factor: 23, filter: { foo: :bar } }]) } end describe '#weight' do specify { expect(subject.weight('23')).to be_a described_class } specify { expect(subject.weight('23')).not_to eq(subject) } - specify { expect(subject.weight('23').criteria.scores).to eq([ { weight: 23 } ]) } + specify { expect(subject.weight('23').criteria.scores).to eq([{ weight: 23 }]) } specify { expect { subject.weight('23') }.not_to change { subject.criteria.scores } } - specify { expect(subject.weight('23', filter: { foo: :bar}).criteria.scores).to eq([{ weight: 23, filter: { foo: :bar } }]) } + specify { expect(subject.weight('23', filter: { foo: :bar }).criteria.scores).to eq([{ weight: 23, filter: { foo: :bar } }]) } end describe '#random_score' do specify { expect(subject.random_score('23')).to be_a described_class } specify { expect(subject.random_score('23')).not_to eq(subject) } - specify { expect(subject.random_score('23').criteria.scores).to eq([ { random_score: { seed: 23 } } ]) } + specify { expect(subject.random_score('23').criteria.scores).to eq([{ random_score: { seed: 23 } }]) } specify { expect { subject.random_score('23') }.not_to change { subject.criteria.scores } } - specify { expect(subject.random_score('23', filter: { foo: :bar}).criteria.scores).to eq([{ random_score: { seed: 23 }, filter: { foo: :bar } }]) } + specify { expect(subject.random_score('23', filter: { foo: :bar }).criteria.scores).to eq([{ random_score: { seed: 23 }, filter: { foo: :bar } }]) } end describe '#field_value_score' do specify { expect(subject.field_value_factor(field: :boost)).to be_a described_class } specify { expect(subject.field_value_factor(field: :boost)).not_to eq(subject) } - specify { expect(subject.field_value_factor(field: :boost).criteria.scores).to eq([ { field_value_factor: { field: :boost } } ]) } + specify { expect(subject.field_value_factor(field: :boost).criteria.scores).to eq([{ field_value_factor: { field: :boost } }]) } specify { expect { subject.field_value_factor(field: :boost) }.not_to change { subject.criteria.scores } } - specify { expect(subject.field_value_factor({ field: :boost }, filter: { foo: :bar}).criteria.scores).to eq([{ field_value_factor: { field: :boost }, filter: { foo: :bar } }]) } + specify { expect(subject.field_value_factor({ field: :boost }, filter: { foo: :bar }).criteria.scores).to eq([{ field_value_factor: { field: :boost }, filter: { foo: :bar } }]) } end describe '#decay' do specify { expect(subject.decay(:gauss, :field)).to be_a described_class } specify { expect(subject.decay(:gauss, :field)).not_to eq(subject) } - specify { expect(subject.decay(:gauss, :field).criteria.scores).to eq([ { - gauss: { - field: {} - } - }]) } + specify do + expect(subject.decay(:gauss, :field).criteria.scores).to eq([{ + gauss: { + field: {} + } + }]) + end specify { expect { subject.decay(:gauss, :field) }.not_to change { subject.criteria.scores } } - specify { + specify do expect(subject.decay(:gauss, :field, - origin: '11, 12', - scale: '2km', - offset: '5km', - decay: 0.4, - filter: { foo: :bar }).criteria.scores).to eq([ - { - gauss: { - field: { - origin: '11, 12', - scale: '2km', - offset: '5km', - decay: 0.4 - } - }, - filter: { foo: :bar } - } - ]) - } + origin: '11, 12', + scale: '2km', + offset: '5km', + decay: 0.4, + filter: { foo: :bar }).criteria.scores).to eq([ + { + gauss: { + field: { + origin: '11, 12', + scale: '2km', + offset: '5km', + decay: 0.4 + } + }, + filter: { foo: :bar } + } + ]) + end end describe '#facets' do @@ -193,19 +195,19 @@ specify do skip_on_version_gte('2.0') - expect(subject.facets(term: {field: 'hello'})).to be_a described_class + expect(subject.facets(term: { field: 'hello' })).to be_a described_class end specify do skip_on_version_gte('2.0') - expect(subject.facets(term: {field: 'hello'})).not_to eq(subject) + expect(subject.facets(term: { field: 'hello' })).not_to eq(subject) end specify do skip_on_version_gte('2.0') - expect(subject.facets(term: {field: 'hello'}).criteria.facets).to include(term: {field: 'hello'}) + expect(subject.facets(term: { field: 'hello' }).criteria.facets).to include(term: { field: 'hello' }) end specify do skip_on_version_gte('2.0') - expect { subject.facets(term: {field: 'hello'}) }.not_to change { subject.criteria.facets } + expect { subject.facets(term: { field: 'hello' }) }.not_to change { subject.criteria.facets } end context 'results', :orm do @@ -228,28 +230,25 @@ end specify do skip_on_version_gte('2.0') - expect(CitiesIndex.facets(ratings: {terms: {field: 'rating'}}).facets).to eq({ - 'ratings' => { - '_type' => 'terms', 'missing' => 0, 'total' => 10, 'other' => 0, - 'terms' => [ - {'term' => 0, 'count' => 4}, - {'term' => 2, 'count' => 3}, - {'term' => 1, 'count' => 3} - ] - } - }) + expect(CitiesIndex.facets(ratings: { terms: { field: 'rating' } }).facets).to eq('ratings' => { + '_type' => 'terms', 'missing' => 0, 'total' => 10, 'other' => 0, + 'terms' => [ + { 'term' => 0, 'count' => 4 }, + { 'term' => 2, 'count' => 3 }, + { 'term' => 1, 'count' => 3 } + ] + }) end end end describe '#aggregations' do - specify { expect(subject.aggregations(aggregation1: {field: 'hello'})).to be_a described_class } - specify { expect(subject.aggregations(aggregation1: {field: 'hello'})).not_to eq(subject) } - specify { expect(subject.aggregations(aggregation1: {field: 'hello'}).criteria.aggregations).to include(aggregation1: {field: 'hello'}) } - specify { expect { subject.aggregations(aggregation1: {field: 'hello'}) }.not_to change { subject.criteria.aggregations } } + specify { expect(subject.aggregations(aggregation1: { field: 'hello' })).to be_a described_class } + specify { expect(subject.aggregations(aggregation1: { field: 'hello' })).not_to eq(subject) } + specify { expect(subject.aggregations(aggregation1: { field: 'hello' }).criteria.aggregations).to include(aggregation1: { field: 'hello' }) } + specify { expect { subject.aggregations(aggregation1: { field: 'hello' }) }.not_to change { subject.criteria.aggregations } } context 'when requesting a named aggregation' do - before do stub_index(:products) do define_type :product do @@ -303,16 +302,18 @@ end end - it "is the aggregation definition that was last defined" do + it 'is the aggregation definition that was last defined' do expect(subject.aggregations(:named_agg).criteria.aggregations).to include(named_agg: { avg: { field: 'comments.rating' } }) end - context "when the fully qualified aggregation name is provided" do - specify { expect(subject - .aggregations("products#product.named_agg") + context 'when the fully qualified aggregation name is provided' do + specify do + expect(subject + .aggregations('products#product.named_agg') .criteria .aggregations) - .to include({ "products#product.named_agg" => { avg: { field: 'title.subfield1' } } }) } + .to include('products#product.named_agg' => { avg: { field: 'title.subfield1' } }) + end end end end @@ -333,21 +334,23 @@ before { CitiesIndex::City.import! cities } specify { expect(CitiesIndex.aggregations).to eq({}) } - specify { expect(CitiesIndex.aggregations(ratings: {terms: {field: 'rating'}}) + specify do + expect(CitiesIndex.aggregations(ratings: { terms: { field: 'rating' } }) .aggregations['ratings']['buckets'].map { |h| h.slice('key', 'doc_count') }).to eq([ - { 'key' => 0, 'doc_count' => 4 }, - { 'key' => 1, 'doc_count' => 3 }, - { 'key' => 2, 'doc_count' => 3 } - ]) } + { 'key' => 0, 'doc_count' => 4 }, + { 'key' => 1, 'doc_count' => 3 }, + { 'key' => 2, 'doc_count' => 3 } + ]) + end end end end describe '#suggest' do - specify { subject.suggest(name1: {text: 'hello', term: {field: 'name'}}) } - specify { expect(subject.suggest(name1: {text: 'hello'})).not_to eq(subject) } - specify { expect(subject.suggest(name1: {text: 'hello'}).criteria.suggest).to include(name1: {text: 'hello'}) } - specify { expect { subject.suggest(name1: {text: 'hello'}) }.not_to change { subject.criteria.suggest } } + specify { subject.suggest(name1: { text: 'hello', term: { field: 'name' } }) } + specify { expect(subject.suggest(name1: { text: 'hello' })).not_to eq(subject) } + specify { expect(subject.suggest(name1: { text: 'hello' }).criteria.suggest).to include(name1: { text: 'hello' }) } + specify { expect { subject.suggest(name1: { text: 'hello' }) }.not_to change { subject.criteria.suggest } } context 'results', :orm do before { stub_model(:city) } @@ -365,26 +368,25 @@ before { CitiesIndex::City.import! cities } specify { expect(CitiesIndex.suggest).to eq({}) } - specify { expect(CitiesIndex.suggest(name: {text: 'name', term: {field: 'name'}}).suggest).to eq({ - 'name' => [ - {'text' => 'name', 'offset' => 0, 'length' => 4, 'options' => [ - {'text' => 'name0', 'score' => 0.75, 'freq' => 1}, - {'text' => 'name1', 'score' => 0.75, 'freq' => 1}, - {'text' => 'name2', 'score' => 0.75, 'freq' => 1}, - {'text' => 'name3', 'score' => 0.75, 'freq' => 1}, - {'text' => 'name4', 'score' => 0.75, 'freq' => 1} - ] - } - ] }) - } + specify do + expect(CitiesIndex.suggest(name: { text: 'name', term: { field: 'name' } }).suggest).to eq('name' => [ + { 'text' => 'name', 'offset' => 0, 'length' => 4, 'options' => [ + { 'text' => 'name0', 'score' => 0.75, 'freq' => 1 }, + { 'text' => 'name1', 'score' => 0.75, 'freq' => 1 }, + { 'text' => 'name2', 'score' => 0.75, 'freq' => 1 }, + { 'text' => 'name3', 'score' => 0.75, 'freq' => 1 }, + { 'text' => 'name4', 'score' => 0.75, 'freq' => 1 } + ] } + ]) + end end end end describe '#delete_all' do - let(:products) { Array.new(3) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } - let(:cities) { Array.new(3) { |i| {id: i.next.to_s}.stringify_keys! } } - let(:countries) { Array.new(3) { |i| {id: i.next.to_s}.stringify_keys! } } + let(:products) { Array.new(3) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } + let(:cities) { Array.new(3) { |i| { id: i.next.to_s }.stringify_keys! } } + let(:countries) { Array.new(3) { |i| { id: i.next.to_s }.stringify_keys! } } before do ProductsIndex::Product.import!(products.map { |h| double(h) }) @@ -394,46 +396,51 @@ specify do skip_on_plugin_missing_from_version('delete-by-query', '2.0') - expect { - subject.query(match: {name: 'name3'}).delete_all - Chewy.client.indices.refresh(index: 'products') }.to change { ProductsIndex.total }.from(9).to(8) + expect do + subject.query(match: { name: 'name3' }).delete_all + Chewy.client.indices.refresh(index: 'products') + end.to change { ProductsIndex.total }.from(9).to(8) end specify do skip_on_plugin_missing_from_version('delete-by-query', '2.0') - expect { + expect do subject.filter { age == [10, 20] }.delete_all - Chewy.client.indices.refresh(index: 'products') }.to change { ProductsIndex.total_count }.from(9).to(7) + Chewy.client.indices.refresh(index: 'products') + end.to change { ProductsIndex.total_count }.from(9).to(7) end specify do skip_on_plugin_missing_from_version('delete-by-query', '2.0') - expect { + expect do subject.types(:product).delete_all - Chewy.client.indices.refresh(index: 'products') }.to change { ProductsIndex::Product.total_entries }.from(3).to(0) + Chewy.client.indices.refresh(index: 'products') + end.to change { ProductsIndex::Product.total_entries }.from(3).to(0) end specify do skip_on_plugin_missing_from_version('delete-by-query', '2.0') - expect { + expect do ProductsIndex.delete_all - Chewy.client.indices.refresh(index: 'products') }.to change { ProductsIndex.total }.from(9).to(0) + Chewy.client.indices.refresh(index: 'products') + end.to change { ProductsIndex.total }.from(9).to(0) end specify do skip_on_plugin_missing_from_version('delete-by-query', '2.0') - expect { + expect do ProductsIndex::City.delete_all - Chewy.client.indices.refresh(index: 'products') }.to change { ProductsIndex.total }.from(9).to(6) + Chewy.client.indices.refresh(index: 'products') + end.to change { ProductsIndex.total }.from(9).to(6) end specify do skip_on_version_lt('2.0') - expect(Chewy.client.nodes).to receive(:info).and_return({"nodes" => {"a" => {"plugins" => {"name" => "hello"}}}}) - expect { ProductsIndex.delete_all }.to raise_error(Chewy::PluginMissing).with_message("install delete-by-query plugin") + expect(Chewy.client.nodes).to receive(:info).and_return('nodes' => { 'a' => { 'plugins' => { 'name' => 'hello' } } }) + expect { ProductsIndex.delete_all }.to raise_error(Chewy::PluginMissing).with_message('install delete-by-query plugin') end end describe '#find' do - let(:products) { Array.new(3) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } } - let(:cities) { Array.new(1) { {id: '4'}.stringify_keys! } } - let(:countries) { Array.new(1) { {id: '4'}.stringify_keys! } } + let(:products) { Array.new(3) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next }.stringify_keys! } } + let(:cities) { Array.new(1) { { id: '4' }.stringify_keys! } } + let(:countries) { Array.new(1) { { id: '4' }.stringify_keys! } } before do ProductsIndex::Product.import!(products.map { |h| double(h) }) @@ -456,19 +463,19 @@ end describe '#exists?' do - let(:data) { Array.new(10) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next} } } + let(:data) { Array.new(10) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next } } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } specify { expect(subject.exists?).to eq true } specify { expect(subject.limit(5).exists?).to eq true } - specify { expect(subject.filter(range: {age: {gt: 20}}).limit(3).exists?).to eq true } - specify { expect(subject.filter(range: {age: {lt: 0}}).exists?).to eq false } + specify { expect(subject.filter(range: { age: { gt: 20 } }).limit(3).exists?).to eq true } + specify { expect(subject.filter(range: { age: { lt: 0 } }).exists?).to eq false } end describe '#unlimited' do let(:data_length) { 10 } - let(:data) { Array.new(data_length) { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next} } } + let(:data) { Array.new(data_length) { |i| { id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next } } } before { ProductsIndex::Product.import!(data.map { |h| double(h) }) } @@ -507,25 +514,29 @@ end describe '#filter' do - specify { expect(subject.filter(term: {field: 'hello'})).to be_a described_class } - specify { expect(subject.filter(term: {field: 'hello'})).not_to eq(subject) } - specify { expect { subject.filter(term: {field: 'hello'}) }.not_to change { subject.criteria.filters } } - specify { expect(subject.filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.filters) - .to eq([{term: {field: 'hello'}}, {term: {field: 'world'}}]) } + specify { expect(subject.filter(term: { field: 'hello' })).to be_a described_class } + specify { expect(subject.filter(term: { field: 'hello' })).not_to eq(subject) } + specify { expect { subject.filter(term: { field: 'hello' }) }.not_to change { subject.criteria.filters } } + specify do + expect(subject.filter([{ term: { field: 'hello' } }, { term: { field: 'world' } }]).criteria.filters) + .to eq([{ term: { field: 'hello' } }, { term: { field: 'world' } }]) + end - specify { expect { subject.filter{ name == 'John' } }.not_to change { subject.criteria.filters } } - specify { expect(subject.filter{ name == 'John' }.criteria.filters).to eq([{term: {'name' => 'John'}}]) } + specify { expect { subject.filter { name == 'John' } }.not_to change { subject.criteria.filters } } + specify { expect(subject.filter { name == 'John' }.criteria.filters).to eq([{ term: { 'name' => 'John' } }]) } end describe '#post_filter' do - specify { expect(subject.post_filter(term: {field: 'hello'})).to be_a described_class } - specify { expect(subject.post_filter(term: {field: 'hello'})).not_to eq(subject) } - specify { expect { subject.post_filter(term: {field: 'hello'}) }.not_to change { subject.criteria.post_filters } } - specify { expect(subject.post_filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.post_filters) - .to eq([{term: {field: 'hello'}}, {term: {field: 'world'}}]) } + specify { expect(subject.post_filter(term: { field: 'hello' })).to be_a described_class } + specify { expect(subject.post_filter(term: { field: 'hello' })).not_to eq(subject) } + specify { expect { subject.post_filter(term: { field: 'hello' }) }.not_to change { subject.criteria.post_filters } } + specify do + expect(subject.post_filter([{ term: { field: 'hello' } }, { term: { field: 'world' } }]).criteria.post_filters) + .to eq([{ term: { field: 'hello' } }, { term: { field: 'world' } }]) + end - specify { expect { subject.post_filter{ name == 'John' } }.not_to change { subject.criteria.post_filters } } - specify { expect(subject.post_filter{ name == 'John' }.criteria.post_filters).to eq([{term: {'name' => 'John'}}]) } + specify { expect { subject.post_filter { name == 'John' } }.not_to change { subject.criteria.post_filters } } + specify { expect(subject.post_filter { name == 'John' }.criteria.post_filters).to eq([{ term: { 'name' => 'John' } }]) } end describe '#order' do @@ -535,9 +546,9 @@ specify { expect(subject.order(:field).criteria.sort).to eq([:field]) } specify { expect(subject.order([:field1, :field2]).criteria.sort).to eq([:field1, :field2]) } - specify { expect(subject.order(field: :asc).criteria.sort).to eq([{field: :asc}]) } - specify { expect(subject.order({field1: :asc, field2: :desc}).criteria.sort).to eq([{field1: :asc}, {field2: :desc}]) } - specify { expect(subject.order({field1: {order: :asc}, field2: :desc}).order([:field3], :field4).criteria.sort).to eq([{field1: {order: :asc}}, {field2: :desc}, :field3, :field4]) } + specify { expect(subject.order(field: :asc).criteria.sort).to eq([{ field: :asc }]) } + specify { expect(subject.order(field1: :asc, field2: :desc).criteria.sort).to eq([{ field1: :asc }, { field2: :desc }]) } + specify { expect(subject.order(field1: { order: :asc }, field2: :desc).order([:field3], :field4).criteria.sort).to eq([{ field1: { order: :asc } }, { field2: :desc }, :field3, :field4]) } end describe '#reorder' do @@ -555,8 +566,8 @@ specify { expect(subject.only(:field)).not_to eq(subject) } specify { expect { subject.only(:field) }.not_to change { subject.criteria.fields } } - specify { expect(subject.only(:field1, :field2).criteria.fields).to match_array(['field1', 'field2']) } - specify { expect(subject.only([:field1, :field2]).only(:field3).criteria.fields).to match_array(['field1', 'field2', 'field3']) } + specify { expect(subject.only(:field1, :field2).criteria.fields).to match_array(%w(field1 field2)) } + specify { expect(subject.only([:field1, :field2]).only(:field3).criteria.fields).to match_array(%w(field1 field2 field3)) } end describe '#only!' do @@ -564,7 +575,7 @@ specify { expect(subject.only!(:field)).not_to eq(subject) } specify { expect { subject.only!(:field) }.not_to change { subject.criteria.fields } } - specify { expect(subject.only!(:field1, :field2).criteria.fields).to match_array(['field1', 'field2']) } + specify { expect(subject.only!(:field1, :field2).criteria.fields).to match_array(%w(field1 field2)) } specify { expect(subject.only!([:field1, :field2]).only!(:field3).criteria.fields).to match_array(['field3']) } specify { expect(subject.only([:field1, :field2]).only!(:field3).criteria.fields).to match_array(['field3']) } end @@ -575,8 +586,8 @@ specify { expect { subject.types(:product) }.not_to change { subject.criteria.types } } specify { expect(subject.types(:user).criteria.types).to eq(['user']) } - specify { expect(subject.types(:product, :city).criteria.types).to match_array(['product', 'city']) } - specify { expect(subject.types([:product, :city]).types(:country).criteria.types).to match_array(['product', 'city', 'country']) } + specify { expect(subject.types(:product, :city).criteria.types).to match_array(%w(product city)) } + specify { expect(subject.types([:product, :city]).types(:country).criteria.types).to match_array(%w(product city country)) } end describe '#types!' do @@ -585,7 +596,7 @@ specify { expect { subject.types!(:product) }.not_to change { subject.criteria.types } } specify { expect(subject.types!(:user).criteria.types).to eq(['user']) } - specify { expect(subject.types!(:product, :city).criteria.types).to match_array(['product', 'city']) } + specify { expect(subject.types!(:product, :city).criteria.types).to match_array(%w(product city)) } specify { expect(subject.types!([:product, :city]).types!(:country).criteria.types).to match_array(['country']) } specify { expect(subject.types([:product, :city]).types!(:country).criteria.types).to match_array(['country']) } end @@ -595,16 +606,18 @@ end describe '#aggregations' do - specify { expect(subject.aggregations(attribute: {terms: {field: 'attribute'}})).to be_a described_class } - specify { expect(subject.aggregations(attribute: {terms: {field: 'attribute'}})).not_to eq(subject) } - specify { expect(subject.aggregations(attribute: {terms: {field: 'attribute'}}).criteria.request_body[:body]).to include(aggregations: {attribute: {terms: {field: 'attribute'}}}) } + specify { expect(subject.aggregations(attribute: { terms: { field: 'attribute' } })).to be_a described_class } + specify { expect(subject.aggregations(attribute: { terms: { field: 'attribute' } })).not_to eq(subject) } + specify { expect(subject.aggregations(attribute: { terms: { field: 'attribute' } }).criteria.request_body[:body]).to include(aggregations: { attribute: { terms: { field: 'attribute' } } }) } end describe '#merge' do let(:query) { described_class.new(ProductsIndex) } - specify { expect(subject.filter { name == 'name' }.merge(query.filter { age == 42 }).criteria.filters) - .to eq([{term: {'name' => 'name'}}, {term: {'age' => 42}}]) } + specify do + expect(subject.filter { name == 'name' }.merge(query.filter { age == 42 }).criteria.filters) + .to eq([{ term: { 'name' => 'name' } }, { term: { 'age' => 42 } }]) + end end describe '#to_a', :orm do @@ -617,7 +630,7 @@ define_type :city do field :name field :rating, type: 'integer' - field :nested, type: 'object', value: ->{ {name: name} } + field :nested, type: 'object', value: -> { { name: name } } end end end @@ -627,17 +640,17 @@ specify { expect(CitiesIndex.order(:rating).first).to be_a CitiesIndex::City } specify { expect(CitiesIndex.order(:rating).first.name).to eq('name0') } specify { expect(CitiesIndex.order(:rating).first.rating).to eq(0) } - specify { expect(CitiesIndex.order(:rating).first.nested).to eq({'name' => 'name0'}) } + specify { expect(CitiesIndex.order(:rating).first.nested).to eq('name' => 'name0') } specify { expect(CitiesIndex.order(:rating).first.id).to eq(cities.first.id.to_s) } specify { expect(CitiesIndex.order(:rating).only(:name).first.name).to eq('name0') } specify { expect(CitiesIndex.order(:rating).only(:name).first.rating).to be_nil } - specify { expect(CitiesIndex.order(:rating).only(:nested).first.nested).to eq({'name' => 'name0'}) } + specify { expect(CitiesIndex.order(:rating).only(:nested).first.nested).to eq('name' => 'name0') } specify { expect(CitiesIndex.order(:rating).first._score).to be_nil } specify { expect(CitiesIndex.all.first._score).to be > 0 } - specify { expect(CitiesIndex.query(match: {name: 'name0'}).first._score).to be > 0 } - specify { expect(CitiesIndex.query(match: {name: 'name0'}).took).to be >= 0 } + specify { expect(CitiesIndex.query(match: { name: 'name0' }).first._score).to be > 0 } + specify { expect(CitiesIndex.query(match: { name: 'name0' }).took).to be >= 0 } specify { expect(CitiesIndex.order(:rating).first._explanation).to be_nil } specify { expect(CitiesIndex.order(:rating).explain.first._explanation).to be_present } @@ -647,10 +660,10 @@ before do stub_index(:cities) do define_type :city do - root _source: {enabled: false} do + root _source: { enabled: false } do field :name field :rating, type: 'integer' - field :nested, type: 'object', value: ->{ {name: name} } + field :nested, type: 'object', value: -> { { name: name } } end end end diff --git a/spec/chewy/repository_spec.rb b/spec/chewy/repository_spec.rb index 7be2181e2..24660ab6c 100644 --- a/spec/chewy/repository_spec.rb +++ b/spec/chewy/repository_spec.rb @@ -13,8 +13,8 @@ context do before { subject.analyzer(:name, option: :foo) } - specify { expect(subject.analyzer(:name)).to eq({option: :foo}) } - specify { expect(subject.analyzers).to eq({name: {option: :foo}}) } + specify { expect(subject.analyzer(:name)).to eq(option: :foo) } + specify { expect(subject.analyzers).to eq(name: { option: :foo }) } end end @@ -23,8 +23,8 @@ context do before { subject.tokenizer(:name, option: :foo) } - specify { expect(subject.tokenizer(:name)).to eq({option: :foo}) } - specify { expect(subject.tokenizers).to eq({name: {option: :foo}}) } + specify { expect(subject.tokenizer(:name)).to eq(option: :foo) } + specify { expect(subject.tokenizers).to eq(name: { option: :foo }) } end end @@ -33,8 +33,8 @@ context do before { subject.filter(:name, option: :foo) } - specify { expect(subject.filter(:name)).to eq({option: :foo}) } - specify { expect(subject.filters).to eq({name: {option: :foo}}) } + specify { expect(subject.filter(:name)).to eq(option: :foo) } + specify { expect(subject.filters).to eq(name: { option: :foo }) } end end @@ -43,8 +43,8 @@ context do before { subject.char_filter(:name, option: :foo) } - specify { expect(subject.char_filter(:name)).to eq({option: :foo}) } - specify { expect(subject.char_filters).to eq({name: {option: :foo}}) } + specify { expect(subject.char_filter(:name)).to eq(option: :foo) } + specify { expect(subject.char_filters).to eq(name: { option: :foo }) } end end end diff --git a/spec/chewy/rspec/update_index_spec.rb b/spec/chewy/rspec/update_index_spec.rb index ab66212db..0ebce2d42 100644 --- a/spec/chewy/rspec/update_index_spec.rb +++ b/spec/chewy/rspec/update_index_spec.rb @@ -6,22 +6,25 @@ before do stub_index(:dummies) do define_type :dummy do - root value: ->(_o){{}} + root value: ->(_o) { {} } end end end - specify { expect { }.not_to update_index(DummiesIndex::Dummy) } + specify { expect {}.not_to update_index(DummiesIndex::Dummy) } specify { expect { DummiesIndex::Dummy.bulk body: [] }.not_to update_index(DummiesIndex::Dummy) } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42}}] }.not_to update_index(DummiesIndex::Dummy) } - .to fail_with(/Expected index .* not to be updated, but it was with/) } + specify do + expect { expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42 } }] }.not_to update_index(DummiesIndex::Dummy) } + .to fail_with(/Expected index .* not to be updated, but it was with/) + end context do let(:expectation) do - expect { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42}}, {index: {_id: 41}}, {index: {_id: 42}}] - }.not_to update_index(DummiesIndex::Dummy) } + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42 } }, { index: { _id: 41 } }, { index: { _id: 42 } }] + end.not_to update_index(DummiesIndex::Dummy) end end specify { expectation.to fail_matching 'document id `42` (2 times)' } @@ -29,62 +32,107 @@ end context '#only' do - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(41, 42).only } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(41).only } - .to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(41, times: 2).only } - .to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' } - - specify { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_delete(41, 42).only } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_delete(41).only } - .to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_delete(41, times: 2).only } - .to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' } - - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(42).only } - .to fail_matching 'to update documents ["42"] only, but ["41"] was deleted also' } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(42).only } - .to fail_matching 'to update documents ["42"] only, but ["43"] was updated and ["41"] was deleted also' } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 41}}] } - .to update_index(DummiesIndex::Dummy).and_delete(41).only } - .to fail_matching 'to delete documents ["41"] only, but ["42"] was updated also' } - specify { expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 41}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_delete(41).only } - .to fail_matching 'to delete documents ["41"] only, but ["42"] was updated and ["43"] was deleted also' } + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(41, 42).only + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(41).only + end + .to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 41, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(41, times: 2).only + end + .to fail_matching 'to update documents ["41"] only, but ["42"] was updated also' + end + + specify do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(41, 42).only + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(41).only + end + .to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(41, times: 2).only + end + .to fail_matching 'to delete documents ["41"] only, but ["42"] was deleted also' + end + + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(42).only + end + .to fail_matching 'to update documents ["42"] only, but ["41"] was deleted also' + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(42).only + end + .to fail_matching 'to update documents ["42"] only, but ["43"] was updated and ["41"] was deleted also' + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { delete: { _id: 41 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(41).only + end + .to fail_matching 'to delete documents ["41"] only, but ["42"] was updated also' + end + specify do + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { delete: { _id: 41 } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(41).only + end + .to fail_matching 'to delete documents ["41"] only, but ["42"] was updated and ["43"] was deleted also' + end end context '#and_reindex' do - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42}}] }.to update_index(DummiesIndex::Dummy) } - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(42) } - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(double(id: 42)) } - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(double(id: 42), double(id: 43)) } - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] } - .to update_index(DummiesIndex::Dummy).and_reindex([double(id: 42), 43]) } + specify { expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42 } }] }.to update_index(DummiesIndex::Dummy) } + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(42) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(double(id: 42)) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(double(id: 42), double(id: 43)) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] } + .to update_index(DummiesIndex::Dummy).and_reindex([double(id: 42), 43]) + end specify do - expect { - expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex([44, 43]) - }.to fail_matching 'Expected document with id `44` to be reindexed, but it was not' + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] + end.to update_index(DummiesIndex::Dummy).and_reindex([44, 43]) + end.to fail_matching 'Expected document with id `44` to be reindexed, but it was not' end context do let(:expectation) do - expect { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(44, double(id: 47)) } + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(44, double(id: 47)) end end specify { expectation.to fail_matching('Expected document with id `44` to be reindexed, but it was not') } @@ -92,23 +140,26 @@ end context ':times' do - specify { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] - DummiesIndex::Dummy.bulk body: [{index: {_id: 43, data: {}}}, {index: {_id: 44, data: {}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, 44, times: 1).and_reindex(43, times: 2) } + specify do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 43, data: {} } }, { index: { _id: 44, data: {} } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, 44, times: 1).and_reindex(43, times: 2) end - specify { expect { - expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, times: 3) - }.to fail_matching('Expected document with id `42` to be reindexed, but it was not') } + specify do + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 43, data: { a: '1' } } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, times: 3) + end.to fail_matching('Expected document with id `42` to be reindexed, but it was not') end context do let(:expectation) do - expect { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 43, data: {}}}] - DummiesIndex::Dummy.bulk body: [{index: {_id: 43, data: {}}}, {index: {_id: 44, data: {}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, times: 3).and_reindex(44, 43, times: 4) } + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { index: { _id: 43, data: {} } }] + DummiesIndex::Dummy.bulk body: [{ index: { _id: 43, data: {} } }, { index: { _id: 44, data: {} } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, times: 3).and_reindex(44, 43, times: 4) end end specify { expectation.to fail_matching 'Expected document with id `44` to be reindexed' } @@ -119,51 +170,57 @@ end context ':with' do - specify { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {a: '1'}}}, {index: {_id: 42, data: {'a' => 2}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, with: {a: 2}) } + specify do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: { a: '1' } } }, { index: { _id: 42, data: { 'a' => 2 } } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, with: { a: 2 }) end - specify { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {a: '1'}}}, {index: {_id: 42, data: {'b' => 2}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, with: {a: '1', b: 2}) } + specify do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: { a: '1' } } }, { index: { _id: 42, data: { 'b' => 2 } } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, with: { a: '1', b: 2 }) end - specify { expect { - expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, with: {a: 1}) - }.to fail_matching('Expected document with id `42` to be reindexed, but it was not') } + specify do + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 43, data: { a: '1' } } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, with: { a: 1 }) + end.to fail_matching('Expected document with id `42` to be reindexed, but it was not') end [ - [{a: ['one', 'two']}, {a: ['one', 'two']}], - [{a: ['one', 'two']}, {a: ['two', 'one']}], - [{a: ['one', 'one', 'two']}, {a: ['one', 'two', 'one']}], - [{a: {b: ['one', 'one', 'two']}}, {a: {b: ['one', 'two', 'one']}}], - [{a: 1, b: 1}, {a: 1}] + [{ a: %w(one two) }, { a: %w(one two) }], + [{ a: %w(one two) }, { a: %w(two one) }], + [{ a: %w(one one two) }, { a: %w(one two one) }], + [{ a: { b: %w(one one two) } }, { a: { b: %w(one two one) } }], + [{ a: 1, b: 1 }, { a: 1 }] ].each do |(data, with)| - specify { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: data}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, with: with) } + specify do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: data } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, with: with) end end [ - [{a: ['one', 'two']}, {a: ['one', 'one', 'two']}], - [{a: ['one', 'one', 'two']}, {a: ['one', 'two']}], - [{a: ['one', 'two']}, {a: 1}], - [{a: 1}, {a: ['one', 'two']}], - [{a: 1}, {a: 1, b: 1}] + [{ a: %w(one two) }, { a: %w(one one two) }], + [{ a: %w(one one two) }, { a: %w(one two) }], + [{ a: %w(one two) }, { a: 1 }], + [{ a: 1 }, { a: %w(one two) }], + [{ a: 1 }, { a: 1, b: 1 }] ].each do |(data, with)| - specify { expect { - expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: data}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(42, with: with) - }.to fail_matching('Expected document with id `42` to be reindexed') } + specify do + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: data } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(42, with: with) + end.to fail_matching('Expected document with id `42` to be reindexed') end end context do let(:expectation) do - expect { expect { - DummiesIndex::Dummy.bulk body: [{index: {_id: 43, data: {a: '1'}}}, {index: {_id: 42, data: {'a' => 2}}}] - }.to update_index(DummiesIndex::Dummy).and_reindex(43, times: 2, with: {a: 2}) } + expect do + expect do + DummiesIndex::Dummy.bulk body: [{ index: { _id: 43, data: { a: '1' } } }, { index: { _id: 42, data: { 'a' => 2 } } }] + end.to update_index(DummiesIndex::Dummy).and_reindex(43, times: 2, with: { a: 2 }) end end specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed' } @@ -174,19 +231,29 @@ end context '#and_delete' do - specify { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(42).and_delete(double(id: 43)) } - specify { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_delete(42).and_delete(double(id: 43)) } - specify { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_delete(42, double(id: 43)) } - specify { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_delete([43, double(id: 42)]) } + specify do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(42).and_delete(double(id: 43)) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(42).and_delete(double(id: 43)) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(42, double(id: 43)) + end + specify do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42 } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_delete([43, double(id: 42)]) + end context do let(:expectation) do - expect { expect { DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {delete: {_id: 43}}] } - .to update_index(DummiesIndex::Dummy).and_reindex(43).and_delete(double(id: 42)) } + expect do + expect { DummiesIndex::Dummy.bulk body: [{ index: { _id: 42, data: {} } }, { delete: { _id: 43 } }] } + .to update_index(DummiesIndex::Dummy).and_reindex(43).and_delete(double(id: 42)) + end end specify { expectation.to fail_matching 'Expected document with id `43` to be reindexed, but it was not' } @@ -195,8 +262,10 @@ context do let(:expectation) do - expect { expect { DummiesIndex::Dummy.bulk body: [{delete: {_id: 42, data: {}}}, {delete: {_id: 42}}] } - .to update_index(DummiesIndex::Dummy).and_delete(44, times: 2).and_delete(double(id: 42), times: 3) } + expect do + expect { DummiesIndex::Dummy.bulk body: [{ delete: { _id: 42, data: {} } }, { delete: { _id: 42 } }] } + .to update_index(DummiesIndex::Dummy).and_delete(44, times: 2).and_delete(double(id: 42), times: 3) + end end specify { expectation.to fail_matching 'Expected document with id `44` to be deleted, but it was not' } diff --git a/spec/chewy/search_spec.rb b/spec/chewy/search_spec.rb index 753ef054e..c0c40162f 100644 --- a/spec/chewy/search_spec.rb +++ b/spec/chewy/search_spec.rb @@ -71,8 +71,8 @@ def self.by_rating end end - let!(:cities) { Array.new(3) { |i| City.create! rating: i + 1, name: "Name#{i+1}" } } - let!(:countries) { Array.new(3) { |i| Country.create! rating: i + 1, name: "Name#{i+4}" } } + let!(:cities) { Array.new(3) { |i| City.create! rating: i + 1, name: "Name#{i + 1}" } } + let!(:countries) { Array.new(3) { |i| Country.create! rating: i + 1, name: "Name#{i + 4}" } } before { PlacesIndex.import! city: cities, country: countries } @@ -83,12 +83,12 @@ def self.by_rating specify { expect(PlacesIndex.order(:name).by_rating(1).map(&:rating)).to eq([1, 1]) } specify { expect(PlacesIndex.order(:name).by_rating(1).map(&:class)).to match_array([PlacesIndex::City, PlacesIndex::Country]) } - specify { expect(PlacesIndex::City.by_rating {2}.map(&:rating)).to eq([2]) } - specify { expect(PlacesIndex::City.by_rating {2}.map(&:class)).to eq([PlacesIndex::City]) } - specify { expect(PlacesIndex::City.by_rating {2}.by_name(2).map(&:rating)).to eq([2]) } - specify { expect(PlacesIndex::City.by_rating {2}.by_name(2).map(&:class)).to eq([PlacesIndex::City]) } - specify { expect(PlacesIndex::City.order(:name).by_rating {2}.map(&:rating)).to eq([2]) } - specify { expect(PlacesIndex::City.order(:name).by_rating {2}.map(&:class)).to eq([PlacesIndex::City]) } + specify { expect(PlacesIndex::City.by_rating { 2 }.map(&:rating)).to eq([2]) } + specify { expect(PlacesIndex::City.by_rating { 2 }.map(&:class)).to eq([PlacesIndex::City]) } + specify { expect(PlacesIndex::City.by_rating { 2 }.by_name(2).map(&:rating)).to eq([2]) } + specify { expect(PlacesIndex::City.by_rating { 2 }.by_name(2).map(&:class)).to eq([PlacesIndex::City]) } + specify { expect(PlacesIndex::City.order(:name).by_rating { 2 }.map(&:rating)).to eq([2]) } + specify { expect(PlacesIndex::City.order(:name).by_rating { 2 }.map(&:class)).to eq([PlacesIndex::City]) } specify { expect(PlacesIndex::Country.by_rating(3).map(&:rating)).to eq([3]) } specify { expect(PlacesIndex::Country.by_rating(3).map(&:class)).to eq([PlacesIndex::Country]) } diff --git a/spec/chewy/strategy/active_job_spec.rb b/spec/chewy/strategy/active_job_spec.rb index 874932d19..61e39cf4f 100644 --- a/spec/chewy/strategy/active_job_spec.rb +++ b/spec/chewy/strategy/active_job_spec.rb @@ -47,8 +47,8 @@ end specify do - expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], {suffix: '201601'}) - Chewy::Strategy::ActiveJob::Worker.new.perform("CitiesIndex::City", [city.id, other_city.id], suffix: '201601') + expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], suffix: '201601') + Chewy::Strategy::ActiveJob::Worker.new.perform('CitiesIndex::City', [city.id, other_city.id], suffix: '201601') end end end diff --git a/spec/chewy/strategy/atomic_spec.rb b/spec/chewy/strategy/atomic_spec.rb index cffa9a97f..d479be6bc 100644 --- a/spec/chewy/strategy/atomic_spec.rb +++ b/spec/chewy/strategy/atomic_spec.rb @@ -51,7 +51,10 @@ end specify do - expect { country.save!; other_country.destroy } + expect do + country.save! + other_country.destroy + end .to update_index(CountriesIndex::Country, strategy: :atomic) .and_reindex('HL').and_delete('WD').only end diff --git a/spec/chewy/strategy/resque_spec.rb b/spec/chewy/strategy/resque_spec.rb index e039f4c55..af18c1a3e 100644 --- a/spec/chewy/strategy/resque_spec.rb +++ b/spec/chewy/strategy/resque_spec.rb @@ -33,8 +33,8 @@ end specify do - expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], {suffix: '201601'}) - Chewy::Strategy::Resque::Worker.perform("CitiesIndex::City", [city.id, other_city.id], suffix: '201601') + expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], suffix: '201601') + Chewy::Strategy::Resque::Worker.perform('CitiesIndex::City', [city.id, other_city.id], suffix: '201601') end end end diff --git a/spec/chewy/strategy/sidekiq_spec.rb b/spec/chewy/strategy/sidekiq_spec.rb index 7a34c70fe..bab9aab46 100644 --- a/spec/chewy/strategy/sidekiq_spec.rb +++ b/spec/chewy/strategy/sidekiq_spec.rb @@ -33,8 +33,8 @@ end specify do - expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], {suffix: '201601'}) - Chewy::Strategy::Sidekiq::Worker.new.perform("CitiesIndex::City", [city.id, other_city.id], suffix: '201601') + expect(CitiesIndex::City).to receive(:import!).with([city.id, other_city.id], suffix: '201601') + Chewy::Strategy::Sidekiq::Worker.new.perform('CitiesIndex::City', [city.id, other_city.id], suffix: '201601') end end end diff --git a/spec/chewy/type/adapter/active_record_spec.rb b/spec/chewy/type/adapter/active_record_spec.rb index 74ce5af3e..0ccf58b27 100644 --- a/spec/chewy/type/adapter/active_record_spec.rb +++ b/spec/chewy/type/adapter/active_record_spec.rb @@ -72,38 +72,54 @@ def import(*args) let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) } } subject { described_class.new(City) } - specify { expect(import).to eq([{index: cities}]) } - specify { expect(import nil).to eq([]) } - - specify { expect(import(City.order(:id))).to eq([{index: cities}]) } - specify { expect(import(City.order(:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - - specify { expect(import(cities)).to eq([{index: cities}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities}, {delete: deleted}]) } - specify { expect(import(cities, deleted, batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2)}, - {delete: deleted.last(2)}]) } - - specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) } - specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities}, {delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2).map(&:id)}, - {delete: deleted.last(2).map(&:id)}]) } - - specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) } - specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) } + specify { expect(import).to eq([{ index: cities }]) } + specify { expect(import(nil)).to eq([]) } + + specify { expect(import(City.order(:id))).to eq([{ index: cities }]) } + specify do + expect(import(City.order(:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + + specify { expect(import(cities)).to eq([{ index: cities }]) } + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities }, { delete: deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2) }, + { delete: deleted.last(2) } + ]) + end + + specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) } + specify { expect(import(deleted.map(&:id))).to eq([{ delete: deleted.map(&:id) }]) } + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities }, { delete: deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2).map(&:id) }, + { delete: deleted.last(2).map(&:id) } + ]) + end + + specify { expect(import(cities.first, nil)).to eq([{ index: [cities.first] }]) } + specify { expect(import(cities.first.id, nil)).to eq([{ index: [cities.first] }]) } context 'raw_import' do let(:probe) { double } @@ -122,7 +138,7 @@ def import(*args) expect(probe).to receive(:call).with(a_hash_including('id' => @two.id, 'name' => @one.name)).and_return(warsaw) expect(probe).to receive(:call).with(a_hash_including('id' => @three.id, 'name' => @three.name)).and_return(madrid) - expect(import(City.where(nil), raw_import: converter)).to eq([{index: [moscow, warsaw, madrid]}]) + expect(import(City.where(nil), raw_import: converter)).to eq([{ index: [moscow, warsaw, madrid] }]) end end end @@ -139,19 +155,25 @@ def delete_already? end end end - subject { described_class.new(City, delete_if: ->{ delete_already? }) } - - specify { expect(import(City.where(nil))).to eq([ - { index: [cities[0]], delete: [cities[1]] } - ]) } - specify { expect(import(cities)).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2) } - ]) } - specify { expect(import(cities.map(&:id))).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2).map(&:id) } - ]) } + subject { described_class.new(City, delete_if: -> { delete_already? }) } + + specify do + expect(import(City.where(nil))).to eq([ + { index: [cities[0]], delete: [cities[1]] } + ]) + end + specify do + expect(import(cities)).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2) } + ]) + end + specify do + expect(import(cities.map(&:id))).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2).map(&:id) } + ]) + end end context 'custom primary_key' do @@ -160,75 +182,119 @@ def delete_already? let!(:deleted) { Array.new(3) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } } subject { described_class.new(City) } - specify { expect(import).to eq([{index: cities}]) } - - specify { expect(import(City.order(:rating))).to eq([{index: cities}]) } - specify { expect(import(City.order(:rating), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - - specify { expect(import(cities)).to eq([{index: cities}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities}, {delete: deleted}]) } - specify { expect(import(cities, deleted, batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2)}, - {delete: deleted.last(1)}]) } - - specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities}, {delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2).map(&:id)}, - {delete: deleted.last(1).map(&:id)}]) } + specify { expect(import).to eq([{ index: cities }]) } + + specify { expect(import(City.order(:rating))).to eq([{ index: cities }]) } + specify do + expect(import(City.order(:rating), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + + specify { expect(import(cities)).to eq([{ index: cities }]) } + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities }, { delete: deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2) }, + { delete: deleted.last(1) } + ]) + end + + specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) } + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities }, { delete: deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2).map(&:id) }, + { delete: deleted.last(1).map(&:id) } + ]) + end end context 'default scope' do - let!(:cities) { Array.new(4) { |i| City.create!(rating: i/3) } } + let!(:cities) { Array.new(4) { |i| City.create!(rating: i / 3) } } let!(:deleted) { Array.new(3) { City.create!.tap(&:destroy) } } subject { described_class.new(City.where(rating: 0)) } - specify { expect(import).to eq([{index: cities.first(3)}]) } + specify { expect(import).to eq([{ index: cities.first(3) }]) } - specify { expect(import(City.where('rating < 2'))) - .to eq([{index: cities.first(3)}]) } - specify { expect(import(City.where('rating < 2'), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}]) } - specify { expect(import(City.where('rating < 1'))) - .to eq([{index: cities.first(3)}]) } + specify do + expect(import(City.where('rating < 2'))) + .to eq([{ index: cities.first(3) }]) + end + specify do + expect(import(City.where('rating < 2'), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }]) + end + specify do + expect(import(City.where('rating < 1'))) + .to eq([{ index: cities.first(3) }]) + end specify { expect(import(City.where('rating > 1'))).to eq([]) } - specify { expect(import(cities.first(2))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) } - specify { expect(import(cities, deleted, batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: cities.last(1) + deleted.first(2)}, - {delete: deleted.last(1)}]) } - - specify { expect(import(cities.first(2).map(&:id))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: [cities.last.id] + deleted.first(2).map(&:id)}, - {delete: deleted.last(1).map(&:id)}]) } + specify do + expect(import(cities.first(2))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) + deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: cities.last(1) + deleted.first(2) }, + { delete: deleted.last(1) } + ]) + end + + specify do + expect(import(cities.first(2).map(&:id))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] + deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: [cities.last.id] + deleted.first(2).map(&:id) }, + { delete: deleted.last(1).map(&:id) } + ]) + end end context 'error handling' do @@ -238,7 +304,10 @@ def delete_already? subject { described_class.new(City) } let(:data_comparer) do - ->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) } + lambda do |id, data| + objects = data[:index] || data[:delete] + !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) + end end context 'implicit scope' do @@ -287,7 +356,7 @@ def delete_already? describe '#load' do context do - let!(:cities) { Array.new(3) { |i| City.create!(rating: i/2) } } + let!(:cities) { Array.new(3) { |i| City.create!(rating: i / 2) } } let!(:deleted) { Array.new(2) { City.create!.tap(&:destroy) } } let(:type) { double(type_name: 'user') } @@ -298,21 +367,29 @@ def delete_already? specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) } specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) } specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) })) - .to eq(cities.first(2) + [nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}})) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}})) - .to eq(cities.first(2) + [nil]) } + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(rating: 0) })) + .to eq(cities.first(2) + [nil]) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: -> { where(rating: 0) }, user: { scope: -> { where(rating: 1) } })) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: City.where(rating: 1), user: { scope: -> { where(rating: 0) } })) + .to eq(cities.first(2) + [nil]) + end end context 'custom primary_key' do before { stub_model(:city) { self.primary_key = 'rating' } } - let!(:cities) { Array.new(3) { |i| City.create!(country_id: i/2) { |c| c.rating = i + 7 } } } + let!(:cities) { Array.new(3) { |i| City.create!(country_id: i / 2) { |c| c.rating = i + 7 } } } let!(:deleted) { Array.new(2) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } } let(:type) { double(type_name: 'user') } @@ -323,16 +400,24 @@ def delete_already? specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) } specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) } specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(country_id: 0) })) - .to eq(cities.first(2) + [nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: ->{ where(country_id: 0) }, user: {scope: ->{ where(country_id: 1)}})) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(country_id: 1))) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: City.where(country_id: 1), user: {scope: ->{ where(country_id: 0)}})) - .to eq(cities.first(2) + [nil]) } + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(country_id: 0) })) + .to eq(cities.first(2) + [nil]) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: -> { where(country_id: 0) }, user: { scope: -> { where(country_id: 1) } })) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(country_id: 1))) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: City.where(country_id: 1), user: { scope: -> { where(country_id: 0) } })) + .to eq(cities.first(2) + [nil]) + end end end end diff --git a/spec/chewy/type/adapter/mongoid_spec.rb b/spec/chewy/type/adapter/mongoid_spec.rb index a2784a558..60b2ec389 100644 --- a/spec/chewy/type/adapter/mongoid_spec.rb +++ b/spec/chewy/type/adapter/mongoid_spec.rb @@ -47,7 +47,7 @@ specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id).map(&:to_s)) } context 'non-bson ids' do - let!(:cities) { Array.new(3) { |i| City.create! id: i+1 } } + let!(:cities) { Array.new(3) { |i| City.create! id: i + 1 } } specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id)) } specify { expect(subject.identify(cities)).to eq(cities.map(&:id)) } @@ -68,38 +68,54 @@ def import(*args) let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) }.sort_by(&:id) } subject { described_class.new(City) } - specify { expect(import).to match([{index: match_array(cities)}]) } - specify { expect(import nil).to eq([]) } - - specify { expect(import(City.order(:id.asc))).to eq([{index: cities}]) } - specify { expect(import(City.order(:id.asc), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - - specify { expect(import(cities)).to eq([{index: cities}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities}, {delete: deleted}]) } - specify { expect(import(cities, deleted, batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2)}, - {delete: deleted.last(2)}]) } - - specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) } - specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities}, {delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2).map(&:id)}, - {delete: deleted.last(2).map(&:id)}]) } - - specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) } - specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) } + specify { expect(import).to match([{ index: match_array(cities) }]) } + specify { expect(import(nil)).to eq([]) } + + specify { expect(import(City.order(:id.asc))).to eq([{ index: cities }]) } + specify do + expect(import(City.order(:id.asc), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + + specify { expect(import(cities)).to eq([{ index: cities }]) } + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities }, { delete: deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2) }, + { delete: deleted.last(2) } + ]) + end + + specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) } + specify { expect(import(deleted.map(&:id))).to eq([{ delete: deleted.map(&:id) }]) } + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities }, { delete: deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2).map(&:id) }, + { delete: deleted.last(2).map(&:id) } + ]) + end + + specify { expect(import(cities.first, nil)).to eq([{ index: [cities.first] }]) } + specify { expect(import(cities.first.id, nil)).to eq([{ index: [cities.first] }]) } end context 'additional delete conditions' do @@ -114,61 +130,95 @@ def delete_already? end end end - subject { described_class.new(City, delete_if: ->{ delete_already? }) } - - specify { expect(import(City.all)).to eq([ - { index: [cities[0]], delete: [cities[1]] } - ]) } - specify { expect(import(cities)).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2) } - ]) } - specify { expect(import(cities.map(&:id))).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2).map(&:id) } - ]) } + subject { described_class.new(City, delete_if: -> { delete_already? }) } + + specify do + expect(import(City.all)).to eq([ + { index: [cities[0]], delete: [cities[1]] } + ]) + end + specify do + expect(import(cities)).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2) } + ]) + end + specify do + expect(import(cities.map(&:id))).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2).map(&:id) } + ]) + end end context 'default scope' do - let!(:cities) { Array.new(4) { |i| City.create!(id: i, rating: i/3) }.sort_by(&:id) } + let!(:cities) { Array.new(4) { |i| City.create!(id: i, rating: i / 3) }.sort_by(&:id) } let!(:deleted) { Array.new(3) { |i| City.create!(id: 4 + i).tap(&:destroy) }.sort_by(&:id) } subject { described_class.new(City.where(rating: 0)) } - specify { expect(import).to eq([{index: cities.first(3)}]) } + specify { expect(import).to eq([{ index: cities.first(3) }]) } - specify { expect(import(City.where(:rating.lt => 2).order(:id.asc))) - .to eq([{index: cities.first(3)}]) } - specify { expect(import(City.where(:rating.lt => 2).order(:id.asc), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}]) } - specify { expect(import(City.where(:rating.lt => 1).order(:id.asc))) - .to eq([{index: cities.first(3)}]) } + specify do + expect(import(City.where(:rating.lt => 2).order(:id.asc))) + .to eq([{ index: cities.first(3) }]) + end + specify do + expect(import(City.where(:rating.lt => 2).order(:id.asc), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }]) + end + specify do + expect(import(City.where(:rating.lt => 1).order(:id.asc))) + .to eq([{ index: cities.first(3) }]) + end specify { expect(import(City.where(:rating.gt => 1).order(:id.asc))).to eq([]) } - specify { expect(import(cities.first(2))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) } - specify { expect(import(cities, deleted, batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: cities.last(1) + deleted.first(2)}, - {delete: deleted.last(1)}]) } - - specify { expect(import(cities.first(2).map(&:id))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: [cities.last.id] + deleted.first(2).map(&:id)}, - {delete: deleted.last(1).map(&:id)}]) } + specify do + expect(import(cities.first(2))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) + deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: cities.last(1) + deleted.first(2) }, + { delete: deleted.last(1) } + ]) + end + + specify do + expect(import(cities.first(2).map(&:id))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] + deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: [cities.last.id] + deleted.first(2).map(&:id) }, + { delete: deleted.last(1).map(&:id) } + ]) + end end context 'error handling' do @@ -178,7 +228,10 @@ def delete_already? subject { described_class.new(City) } let(:data_comparer) do - ->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) } + lambda do |id, data| + objects = data[:index] || data[:delete] + !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) + end end context 'implicit scope' do @@ -227,7 +280,7 @@ def delete_already? describe '#load' do context do - let!(:cities) { Array.new(3) { |i| City.create!(id: i, rating: i/2) }.sort_by(&:id) } + let!(:cities) { Array.new(3) { |i| City.create!(id: i, rating: i / 2) }.sort_by(&:id) } let!(:deleted) { Array.new(2) { |i| City.create!(id: 3 + i).tap(&:destroy) }.sort_by(&:id) } let(:type) { double(type_name: 'user') } @@ -238,16 +291,24 @@ def delete_already? specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) } specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) } specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) })) - .to eq(cities.first(2) + [nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}})) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}})) - .to eq(cities.first(2) + [nil]) } + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(rating: 0) })) + .to eq(cities.first(2) + [nil]) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: -> { where(rating: 0) }, user: { scope: -> { where(rating: 1) } })) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: City.where(rating: 1), user: { scope: -> { where(rating: 0) } })) + .to eq(cities.first(2) + [nil]) + end end end end diff --git a/spec/chewy/type/adapter/object_spec.rb b/spec/chewy/type/adapter/object_spec.rb index ef94c3a67..f6b12d5f4 100644 --- a/spec/chewy/type/adapter/object_spec.rb +++ b/spec/chewy/type/adapter/object_spec.rb @@ -52,42 +52,53 @@ def import(*args) subject { described_class.new('product') } specify { expect(import).to eq([]) } - specify { expect(import nil).to eq([]) } + specify { expect(import(nil)).to eq([]) } - specify { expect(import(objects)).to eq([{index: objects}]) } - specify { expect(import(objects, batch_size: 2)) - .to eq([{index: objects.first(2)}, {index: objects.last(1)}]) } - specify { expect(import(objects, deleted)).to eq([{index: objects, delete: deleted}]) } - specify { expect(import(objects, deleted, batch_size: 2)).to eq([ - {index: objects.first(2)}, - {index: objects.last(1), delete: deleted.first(1)}, - {delete: deleted.last(1)}]) } + specify { expect(import(objects)).to eq([{ index: objects }]) } + specify do + expect(import(objects, batch_size: 2)) + .to eq([{ index: objects.first(2) }, { index: objects.last(1) }]) + end + specify { expect(import(objects, deleted)).to eq([{ index: objects, delete: deleted }]) } + specify do + expect(import(objects, deleted, batch_size: 2)).to eq([ + { index: objects.first(2) }, + { index: objects.last(1), delete: deleted.first(1) }, + { delete: deleted.last(1) } + ]) + end - specify { expect(import(objects.first, nil)).to eq([{index: [objects.first]}]) } + specify { expect(import(objects.first, nil)).to eq([{ index: [objects.first] }]) } context 'initial data' do - subject { described_class.new ->{ objects } } + subject { described_class.new -> { objects } } - specify { expect(import).to eq([{index: objects}]) } - specify { expect(import nil).to eq([]) } + specify { expect(import).to eq([{ index: objects }]) } + specify { expect(import(nil)).to eq([]) } - specify { expect(import(objects[0..1])).to eq([{index: objects[0..1]}]) } - specify { expect(import(batch_size: 2)) - .to eq([{index: objects.first(2)}, {index: objects.last(1)}]) } + specify { expect(import(objects[0..1])).to eq([{ index: objects[0..1] }]) } + specify do + expect(import(batch_size: 2)) + .to eq([{ index: objects.first(2) }, { index: objects.last(1) }]) + end end context do subject { described_class.new('product', delete_if: :delete?) } - let(:deleted) { [ - double(delete?: true, destroyed?: true), - double(delete?: true, destroyed?: false), - double(delete?: false, destroyed?: true), - double(delete?: false, destroyed?: false) - ] } - - specify { expect(import(deleted)).to eq([ - { delete: deleted[0..2], index: deleted.last(1) } - ]) } + let(:deleted) do + [ + double(delete?: true, destroyed?: true), + double(delete?: true, destroyed?: false), + double(delete?: false, destroyed?: true), + double(delete?: false, destroyed?: false) + ] + end + + specify do + expect(import(deleted)).to eq([ + { delete: deleted[0..2], index: deleted.last(1) } + ]) + end end end @@ -120,7 +131,12 @@ def import(*args) [:wrap, :load_one].each do |load_method| context do - before { allow(Product).to receive(load_method) { |object| allow(object).to receive_messages(wrapped?: true); object } } + before do + allow(Product).to receive(load_method) { |object| + allow(object).to receive_messages(wrapped?: true) + object + } + end subject { described_class.new(Product) } let(:objects) { Array.new(3) { double(wrapped?: false) } } diff --git a/spec/chewy/type/adapter/sequel_spec.rb b/spec/chewy/type/adapter/sequel_spec.rb index bb6d4e0ec..9b145f962 100644 --- a/spec/chewy/type/adapter/sequel_spec.rb +++ b/spec/chewy/type/adapter/sequel_spec.rb @@ -7,24 +7,24 @@ end describe '#name' do - it { expect( described_class.new(City).name ).to eq 'City' } - it { expect( described_class.new(City.order(:id)).name ).to eq 'City' } - it { expect( described_class.new(City, name: 'town').name ).to eq 'Town' } + it { expect(described_class.new(City).name).to eq 'City' } + it { expect(described_class.new(City.order(:id)).name).to eq 'City' } + it { expect(described_class.new(City, name: 'town').name).to eq 'Town' } context do before { stub_model('namespace/city') } - it { expect( described_class.new(Namespace::City).name ).to eq 'City' } - it { expect( described_class.new(Namespace::City.order(:id)).name ).to eq 'City' } + it { expect(described_class.new(Namespace::City).name).to eq 'City' } + it { expect(described_class.new(Namespace::City.order(:id)).name).to eq 'City' } end end describe '#default_scope' do - it { expect( described_class.new(City).default_scope.sql ).to eql City.where(nil).sql } - it { expect( described_class.new(City.order(:id)).default_scope.sql ).to eql City.where(nil).sql } - it { expect( described_class.new(City.limit(10)).default_scope.sql ).to eql City.where(nil).sql } - it { expect( described_class.new(City.offset(10)).default_scope.sql ).to eql City.where(nil).sql } - it { expect( described_class.new(City.where(rating: 10)).default_scope.sql ).to eql City.where(rating: 10).sql } + it { expect(described_class.new(City).default_scope.sql).to eql City.where(nil).sql } + it { expect(described_class.new(City.order(:id)).default_scope.sql).to eql City.where(nil).sql } + it { expect(described_class.new(City.limit(10)).default_scope.sql).to eql City.where(nil).sql } + it { expect(described_class.new(City.offset(10)).default_scope.sql).to eql City.where(nil).sql } + it { expect(described_class.new(City.where(rating: 10)).default_scope.sql).to eql City.where(rating: 10).sql } end describe '#type_name' do @@ -46,10 +46,10 @@ context do let!(:cities) { Array.new(3) { City.new.save! } } - it { expect(subject.identify(City.where(nil)) ).to match_array cities.map(&:id) } - it { expect(subject.identify(cities) ).to eq cities.map(&:id) } - it { expect(subject.identify(cities.first) ).to eq([cities.first.id]) } - it { expect(subject.identify(cities.first(2).map(&:id)) ).to eq cities.first(2).map(&:id) } + it { expect(subject.identify(City.where(nil))).to match_array cities.map(&:id) } + it { expect(subject.identify(cities)).to eq cities.map(&:id) } + it { expect(subject.identify(cities.first)).to eq([cities.first.id]) } + it { expect(subject.identify(cities.first(2).map(&:id))).to eq cities.first(2).map(&:id) } end context 'custom primary_key' do @@ -75,38 +75,54 @@ def import(*args) let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) } } subject { described_class.new(City) } - specify { expect(import).to eq([{index: cities}]) } - specify { expect(import nil).to eq([]) } - - specify { expect(import(City.order(:id))).to eq([{index: cities}]) } - specify { expect(import(City.order(:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - - specify { expect(import(cities)).to eq([{index: cities}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities}, {delete: deleted}]) } - specify { expect(import(cities, deleted, batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2)}, - {delete: deleted.last(2)}]) } - - specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) } - specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities}, {delete: deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2).map(&:id)}, - {delete: deleted.last(2).map(&:id)}]) } - - specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) } - specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) } + specify { expect(import).to eq([{ index: cities }]) } + specify { expect(import(nil)).to eq([]) } + + specify { expect(import(City.order(:id))).to eq([{ index: cities }]) } + specify do + expect(import(City.order(:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + + specify { expect(import(cities)).to eq([{ index: cities }]) } + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities }, { delete: deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2) }, + { delete: deleted.last(2) } + ]) + end + + specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) } + specify { expect(import(deleted.map(&:id))).to eq([{ delete: deleted.map(&:id) }]) } + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities }, { delete: deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2).map(&:id) }, + { delete: deleted.last(2).map(&:id) } + ]) + end + + specify { expect(import(cities.first, nil)).to eq([{ index: [cities.first] }]) } + specify { expect(import(cities.first.id, nil)).to eq([{ index: [cities.first] }]) } end context 'additional delete conditions' do @@ -121,19 +137,25 @@ def delete_already? end end end - subject { described_class.new(City, delete_if: ->{ delete_already? }) } - - specify { expect(import(City.where(nil))).to eq([ - { index: [cities[0]], delete: [cities[1]] } - ]) } - specify { expect(import(cities)).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2) } - ]) } - specify { expect(import(cities.map(&:id))).to eq([ - { index: [cities[0]], delete: [cities[1]] }, - { delete: cities.last(2).map(&:id) } - ]) } + subject { described_class.new(City, delete_if: -> { delete_already? }) } + + specify do + expect(import(City.where(nil))).to eq([ + { index: [cities[0]], delete: [cities[1]] } + ]) + end + specify do + expect(import(cities)).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2) } + ]) + end + specify do + expect(import(cities.map(&:id))).to eq([ + { index: [cities[0]], delete: [cities[1]] }, + { delete: cities.last(2).map(&:id) } + ]) + end end context 'custom primary_key' do @@ -142,75 +164,119 @@ def delete_already? let!(:deleted) { Array.new(3) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } } subject { described_class.new(City) } - specify { expect(import).to eq([{index: cities}]) } - - specify { expect(import(City.order(:rating))).to eq([{index: cities}]) } - specify { expect(import(City.order(:rating), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - - specify { expect(import(cities)).to eq([{index: cities}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities}, {delete: deleted}]) } - specify { expect(import(cities, deleted, batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2)}, - {delete: deleted.last(1)}]) } - - specify { expect(import(cities.map(&:rating))).to eq([{index: cities}]) } - specify { expect(import(cities.map(&:rating), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) } - specify { expect(import(cities.map(&:rating), deleted.map(&:rating))) - .to eq([{index: cities}, {delete: deleted.map(&:rating)}]) } - specify { expect(import(cities.map(&:rating), deleted.map(&:rating), batch_size: 2)).to eq([ - {index: cities.first(2)}, - {index: cities.last(1)}, - {delete: deleted.first(2).map(&:rating)}, - {delete: deleted.last(1).map(&:rating)}]) } + specify { expect(import).to eq([{ index: cities }]) } + + specify { expect(import(City.order(:rating))).to eq([{ index: cities }]) } + specify do + expect(import(City.order(:rating), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + + specify { expect(import(cities)).to eq([{ index: cities }]) } + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities }, { delete: deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2) }, + { delete: deleted.last(1) } + ]) + end + + specify { expect(import(cities.map(&:rating))).to eq([{ index: cities }]) } + specify do + expect(import(cities.map(&:rating), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: cities.last(1) }]) + end + specify do + expect(import(cities.map(&:rating), deleted.map(&:rating))) + .to eq([{ index: cities }, { delete: deleted.map(&:rating) }]) + end + specify do + expect(import(cities.map(&:rating), deleted.map(&:rating), batch_size: 2)).to eq([ + { index: cities.first(2) }, + { index: cities.last(1) }, + { delete: deleted.first(2).map(&:rating) }, + { delete: deleted.last(1).map(&:rating) } + ]) + end end context 'default scope' do - let!(:cities) { Array.new(4) { |i| City.create!(rating: i/3) } } + let!(:cities) { Array.new(4) { |i| City.create!(rating: i / 3) } } let!(:deleted) { Array.new(3) { City.create!.tap(&:destroy) } } subject { described_class.new(City.where(rating: 0)) } - specify { expect(import).to eq([{index: cities.first(3)}]) } + specify { expect(import).to eq([{ index: cities.first(3) }]) } - specify { expect(import(City.where('rating < 2'))) - .to eq([{index: cities.first(3)}]) } - specify { expect(import(City.where('rating < 2'), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}]) } - specify { expect(import(City.where('rating < 1'))) - .to eq([{index: cities.first(3)}]) } + specify do + expect(import(City.where('rating < 2'))) + .to eq([{ index: cities.first(3) }]) + end + specify do + expect(import(City.where('rating < 2'), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }]) + end + specify do + expect(import(City.where('rating < 1'))) + .to eq([{ index: cities.first(3) }]) + end specify { expect(import(City.where('rating > 1'))).to eq([]) } - specify { expect(import(cities.first(2))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) } - specify { expect(import(cities, batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) } - specify { expect(import(cities, deleted)) - .to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) } - specify { expect(import(cities, deleted, batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: cities.last(1) + deleted.first(2)}, - {delete: deleted.last(1)}]) } - - specify { expect(import(cities.first(2).map(&:id))) - .to eq([{index: cities.first(2)}]) } - specify { expect(import(cities.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), batch_size: 2)) - .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id))) - .to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) } - specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ - {index: cities.first(3)}, - {delete: [cities.last.id] + deleted.first(2).map(&:id)}, - {delete: deleted.last(1).map(&:id)}]) } + specify do + expect(import(cities.first(2))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: cities.last(1) }]) + end + specify do + expect(import(cities, deleted)) + .to eq([{ index: cities.first(3) }, { delete: cities.last(1) + deleted }]) + end + specify do + expect(import(cities, deleted, batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: cities.last(1) + deleted.first(2) }, + { delete: deleted.last(1) } + ]) + end + + specify do + expect(import(cities.first(2).map(&:id))) + .to eq([{ index: cities.first(2) }]) + end + specify do + expect(import(cities.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), batch_size: 2)) + .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: [cities.last.id] }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id))) + .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] + deleted.map(&:id) }]) + end + specify do + expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([ + { index: cities.first(3) }, + { delete: [cities.last.id] + deleted.first(2).map(&:id) }, + { delete: deleted.last(1).map(&:id) } + ]) + end end context 'error handling' do @@ -220,7 +286,10 @@ def delete_already? subject { described_class.new(City) } let(:data_comparer) do - ->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) } + lambda do |id, data| + objects = data[:index] || data[:delete] + !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) + end end context 'implicit scope' do @@ -269,7 +338,7 @@ def delete_already? describe '#load' do context do - let!(:cities) { Array.new(3) { |i| City.create!(rating: i/2) } } + let!(:cities) { Array.new(3) { |i| City.create!(rating: i / 2) } } let!(:deleted) { Array.new(2) { City.create!.tap(&:destroy) } } let(:type) { double(type_name: 'user') } @@ -280,21 +349,29 @@ def delete_already? specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) } specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) } specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) })) - .to eq(cities.first(2) + [nil]) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}})) - .to eq([nil, nil] + cities.last(1)) } - xspecify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(id: c.id) }, - _type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}})) - .to eq(cities.first(2) + [nil]) } + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(rating: 0) })) + .to eq(cities.first(2) + [nil]) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: -> { where(rating: 0) }, user: { scope: -> { where(rating: 1) } })) + .to eq([nil, nil] + cities.last(1)) + end + xspecify do + expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1))) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(id: c.id) }, + _type: type, scope: City.where(rating: 1), user: { scope: -> { where(rating: 0) } })) + .to eq(cities.first(2) + [nil]) + end end context 'custom primary_key' do before { stub_model(:city).set_dataset :rating_cities } - let!(:cities) { Array.new(3) { |i| City.create!(country_id: i/2) { |c| c.rating = i + 7 } } } + let!(:cities) { Array.new(3) { |i| City.create!(country_id: i / 2) { |c| c.rating = i + 7 } } } let!(:deleted) { Array.new(2) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } } let(:type) { double(type_name: 'user') } @@ -305,16 +382,24 @@ def delete_already? specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }.reverse, _type: type)).to eq(cities.reverse) } specify { expect(subject.load(deleted.map { |c| double(rating: c.rating) }, _type: type)).to eq([nil, nil]) } specify { expect(subject.load((cities + deleted).map { |c| double(rating: c.rating) }, _type: type)).to eq([*cities, nil, nil]) } - specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: ->{ where(country_id: 0) })) - .to eq(cities.first(2) + [nil]) } - specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, - _type: type, scope: ->{ where(country_id: 0) }, user: {scope: ->{ where(country_id: 1)}})) - .to eq([nil, nil] + cities.last(1)) } - xspecify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: City.where(country_id: 1))) - .to eq([nil, nil] + cities.last(1)) } - specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, - _type: type, scope: City.where(country_id: 1), user: {scope: ->{ where(country_id: 0)}})) - .to eq(cities.first(2) + [nil]) } + specify do + expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: -> { where(country_id: 0) })) + .to eq(cities.first(2) + [nil]) + end + specify do + expect(subject.load(cities.map { |c| double(rating: c.rating) }, + _type: type, scope: -> { where(country_id: 0) }, user: { scope: -> { where(country_id: 1) } })) + .to eq([nil, nil] + cities.last(1)) + end + xspecify do + expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: City.where(country_id: 1))) + .to eq([nil, nil] + cities.last(1)) + end + specify do + expect(subject.load(cities.map { |c| double(rating: c.rating) }, + _type: type, scope: City.where(country_id: 1), user: { scope: -> { where(country_id: 0) } })) + .to eq(cities.first(2) + [nil]) + end end end end diff --git a/spec/chewy/type/import_spec.rb b/spec/chewy/type/import_spec.rb index 4d551e9cb..fc8d24914 100644 --- a/spec/chewy/type/import_spec.rb +++ b/spec/chewy/type/import_spec.rb @@ -59,13 +59,16 @@ dummy_cities.first.destroy imported = [] - allow(CitiesIndex.client).to receive(:bulk) { |params| imported << params[:body]; nil } + allow(CitiesIndex.client).to receive(:bulk) { |params| + imported << params[:body] + nil + } city.import dummy_cities.map(&:id), batch_size: 2 expect(imported.flatten).to match_array([ - {index: {_id: 2, data: {'name' => 'name1'}}}, - {index: {_id: 3, data: {'name' => 'name2'}}}, - {delete: {_id: dummy_cities.first.id}} + { index: { _id: 2, data: { 'name' => 'name1' } } }, + { index: { _id: 3, data: { 'name' => 'name2' } } }, + { delete: { _id: dummy_cities.first.id } } ]) end @@ -78,12 +81,15 @@ dummy_cities.first.destroy imported = [] - allow(CitiesIndex.client).to receive(:bulk) { |params| imported << params[:body]; nil } + allow(CitiesIndex.client).to receive(:bulk) { |params| + imported << params[:body] + nil + } city.import dummy_cities.map(&:id), bulk_size: 1.2.kilobyte expect(imported.flatten).to match_array([ - %Q({"delete":{"_id":1}}\n), - %Q({"index":{"_id":2}}\n{"name":"name1"}\n{"index":{"_id":3}}\n{"name":"name2"}\n) + %({"delete":{"_id":1}}\n), + %({"index":{"_id":2}}\n{"name":"name1"}\n{"index":{"_id":3}}\n{"name":"name2"}\n) ]) end @@ -94,13 +100,16 @@ dummy_cities.first.destroy imported = [] - allow(CitiesIndex.client).to receive(:bulk) { |params| imported << params[:body]; nil } + allow(CitiesIndex.client).to receive(:bulk) { |params| + imported << params[:body] + nil + } city.import dummy_cities.map(&:id), bulk_size: 1.2.kilobyte expect(imported.flatten).to match_array([ - %Q({"delete":{"_id":1}}\n), - %Q({"index":{"_id":2}}\n{"name":"#{'name1' * 20}"}\n), - %Q({"index":{"_id":3}}\n{"name":"#{'name2' * 20}"}\n) + %({"delete":{"_id":1}}\n), + %({"index":{"_id":2}}\n{"name":"#{'name1' * 20}"}\n), + %({"index":{"_id":3}}\n{"name":"#{'name2' * 20}"}\n) ]) end @@ -162,7 +171,7 @@ dummy_cities.first.destroy city.import dummy_cities - expect(outer_payload).to eq({type: CitiesIndex::City, import: {delete: 1, index: 2}}) + expect(outer_payload).to eq(type: CitiesIndex::City, import: { delete: 1, index: 2 }) end specify do @@ -173,7 +182,7 @@ dummy_cities.first.destroy city.import dummy_cities, batch_size: 2 - expect(outer_payload).to eq({type: CitiesIndex::City, import: {delete: 1, index: 2}}) + expect(outer_payload).to eq(type: CitiesIndex::City, import: { delete: 1, index: 2 }) end specify do @@ -183,7 +192,7 @@ end city.import dummy_cities, batch_size: 2 - expect(outer_payload).to eq({type: CitiesIndex::City, import: {index: 3}}) + expect(outer_payload).to eq(type: CitiesIndex::City, import: { index: 3 }) end context do @@ -203,16 +212,14 @@ end city.import dummy_cities, batch_size: 2 - expect(outer_payload).to eq({ - type: CitiesIndex::City, + expect(outer_payload).to eq(type: CitiesIndex::City, errors: { index: { - "WriteFailureException; nested: MapperParsingException[object mapping for [city] tried to parse field [name] as object, but got EOF, has a concrete value been provided to it?]; " => ["1"], - "MapperParsingException[object mapping for [city] tried to parse field [name] as object, but got EOF, has a concrete value been provided to it?]" => ["2", "3"] + 'WriteFailureException; nested: MapperParsingException[object mapping for [city] tried to parse field [name] as object, but got EOF, has a concrete value been provided to it?]; ' => ['1'], + 'MapperParsingException[object mapping for [city] tried to parse field [name] as object, but got EOF, has a concrete value been provided to it?]' => %w(2 3) } }, - import: {index: 3} - }) + import: { index: 3 }) end specify do @@ -223,15 +230,13 @@ end city.import dummy_cities, batch_size: 2 - expect(outer_payload).to eq({ - type: CitiesIndex::City, + expect(outer_payload).to eq(type: CitiesIndex::City, errors: { index: { - {"type"=>"mapper_parsing_exception", "reason"=>"object mapping for [name] tried to parse field [name] as object, but found a concrete value"} => ["1", "2", "3"] + { 'type' => 'mapper_parsing_exception', 'reason' => 'object mapping for [name] tried to parse field [name] as object, but found a concrete value' } => %w(1 2 3) } }, - import: {index: 3} - }) + import: { index: 3 }) end end end @@ -255,7 +260,7 @@ before do stub_index(:cities) do define_type City do - field :name, type: 'object', value: ->{ name == 'name1' ? name : {name: name} } + field :name, type: 'object', value: -> { name == 'name1' ? name : { name: name } } end end end @@ -295,12 +300,12 @@ let(:child_city) { City.create(id: 4, country_id: country.id, name: 'city') } let(:city) { CountriesIndex::City } - specify { expect(city.import(child_city)).to eq(true) } + specify { expect(city.import(child_city)).to eq(true) } specify { expect { city.import child_city }.to update_index(city).and_reindex(child_city) } specify do expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ index: { _id: child_city.id, parent: country.id, data: { 'name' => 'city' } } }] + body: [{ index: { _id: child_city.id, parent: country.id, data: { 'name' => 'city' } } }] )) city.import child_city @@ -313,10 +318,10 @@ child_city.update_attributes(country_id: another_country.id) expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [ - { delete: { _id: child_city.id, parent: country.id.to_s } }, - { index: { _id: child_city.id, parent: another_country.id, data: { 'name' => 'city' } } } - ] + body: [ + { delete: { _id: child_city.id, parent: country.id.to_s } }, + { index: { _id: child_city.id, parent: another_country.id, data: { 'name' => 'city' } } } + ] )) city.import child_city @@ -326,7 +331,7 @@ child_city.destroy expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ delete: { _id: child_city.id, parent: country.id.to_s } }] + body: [{ delete: { _id: child_city.id, parent: country.id.to_s } }] )) city.import child_city @@ -336,7 +341,7 @@ child_city.destroy expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ delete: { _id: child_city.id, parent: country.id.to_s } }] + body: [{ delete: { _id: child_city.id, parent: country.id.to_s } }] )) city.import child_city.id @@ -345,8 +350,8 @@ specify do child_city.destroy - expect(city.import child_city).to eq(true) - expect(city.import child_city).to eq(true) + expect(city.import(child_city)).to eq(true) + expect(city.import(child_city)).to eq(true) end end end @@ -370,12 +375,12 @@ end end - specify { expect(country.import(canada)).to eq(true) } + specify { expect(country.import(canada)).to eq(true) } specify { expect { country.import(canada) }.to update_index(country).and_reindex(canada.country_code) } specify do expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ index: { _id: canada.country_code, data: { 'name' => 'Canada', 'rating' => 4 } } }] + body: [{ index: { _id: canada.country_code, data: { 'name' => 'Canada', 'rating' => 4 } } }] )) country.import canada @@ -385,7 +390,7 @@ canada.update_attributes(rating: 9) expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ index: { _id: canada.country_code, data: { 'name' => 'Canada', 'rating' => 9 } } }] + body: [{ index: { _id: canada.country_code, data: { 'name' => 'Canada', 'rating' => 9 } } }] )) country.import canada @@ -395,12 +400,11 @@ canada.destroy expect(CountriesIndex.client).to receive(:bulk).with(hash_including( - body: [{ delete: { _id: canada.country_code } }] + body: [{ delete: { _id: canada.country_code } }] )) country.import canada end - end context 'default_import_options is set' do @@ -437,7 +441,11 @@ specify do expect(ActiveSupport::Notifications).to receive(:unsubscribe) - city.import!(dummy_cities) rescue nil + begin + city.import!(dummy_cities) + rescue + nil + end end end end diff --git a/spec/chewy/type/mapping_spec.rb b/spec/chewy/type/mapping_spec.rb index ca04a83ab..b4f28b689 100644 --- a/spec/chewy/type/mapping_spec.rb +++ b/spec/chewy/type/mapping_spec.rb @@ -34,8 +34,8 @@ end describe '.agg' do - specify { expect(product._agg_defs[:named_agg].call).to eq({ avg: { field: 'title.subfield1' } }) } - specify { expect(review._agg_defs[:named_agg].call).to eq({ avg: { field: 'comments.rating' } }) } + specify { expect(product._agg_defs[:named_agg].call).to eq(avg: { field: 'title.subfield1' }) } + specify { expect(review._agg_defs[:named_agg].call).to eq(avg: { field: 'comments.rating' }) } end describe '.field' do @@ -68,26 +68,26 @@ end end - specify { expect(product.mappings_hash[:product][:_parent]).to eq({ type: 'project' }) } + specify { expect(product.mappings_hash[:product][:_parent]).to eq(type: 'project') } end context do before do stub_index(:products) do define_type :product do - root parent: {'type' => 'project'}, parent_id: -> { project_id } do + root parent: { 'type' => 'project' }, parent_id: -> { project_id } do field :name, 'surname' end end end end - specify { expect(product.mappings_hash[:product][:_parent]).to eq({ type: 'project' }) } + specify { expect(product.mappings_hash[:product][:_parent]).to eq(type: 'project') } end end end - context "no root element call" do + context 'no root element call' do before do stub_index(:products) do define_type :product do diff --git a/spec/chewy/type/observe_spec.rb b/spec/chewy/type/observe_spec.rb index 179536bf0..aa79c2260 100644 --- a/spec/chewy/type/observe_spec.rb +++ b/spec/chewy/type/observe_spec.rb @@ -10,12 +10,18 @@ let(:backreferenced) { Array.new(3) { |i| double(id: i) } } - specify { expect { DummiesIndex::Dummy.update_index(backreferenced) } - .to raise_error Chewy::UndefinedUpdateStrategy } - specify { expect { DummiesIndex::Dummy.update_index([]) } - .not_to update_index('dummies#dummy') } - specify { expect { DummiesIndex::Dummy.update_index(nil) } - .not_to update_index('dummies#dummy') } + specify do + expect { DummiesIndex::Dummy.update_index(backreferenced) } + .to raise_error Chewy::UndefinedUpdateStrategy + end + specify do + expect { DummiesIndex::Dummy.update_index([]) } + .not_to update_index('dummies#dummy') + end + specify do + expect { DummiesIndex::Dummy.update_index(nil) } + .not_to update_index('dummies#dummy') + end end context 'integration', :orm do @@ -35,7 +41,7 @@ stub_model(:country) do update_index('cities#city', if: -> { update_condition }) { cities } - update_index(->{ "countries##{self.class.name.underscore}" }, :self) + update_index(-> { "countries##{self.class.name.underscore}" }, :self) attr_accessor :update_condition end diff --git a/spec/chewy/type/witchcraft_spec.rb b/spec/chewy/type/witchcraft_spec.rb index 7c3011df0..987a26c4c 100644 --- a/spec/chewy/type/witchcraft_spec.rb +++ b/spec/chewy/type/witchcraft_spec.rb @@ -15,7 +15,7 @@ def self.mapping(&block) describe '#cauldron' do let(:type) { ProductsIndex::Product } - let(:object) { } + let(:object) {} context 'empty mapping' do mapping {} @@ -28,7 +28,7 @@ def self.mapping(&block) field :age field :tags end - let(:attributes) { { name: 'Name', age: 13, tags: %w[Ruby RoR] } } + let(:attributes) { { name: 'Name', age: 13, tags: %w(Ruby RoR) } } context do let(:object) { double(attributes) } @@ -44,12 +44,12 @@ def self.mapping(&block) context 'simple lambdas' do mapping do field :name - field :age, value: -> (obj) { + field :age, value: lambda { |obj| obj.age if obj } field :tags, value: -> { tags.map(&:to_sym) } end - let(:attributes) { { name: 'Name', age: 13, tags: %w[Ruby RoR] } } + let(:attributes) { { name: 'Name', age: 13, tags: %w(Ruby RoR) } } context do let(:object) { double(attributes) } @@ -66,7 +66,7 @@ def self.mapping(&block) context do let(:object) { double(attributes) } let(:crutches) { double(names: ['Other']) } - specify { expect(type.cauldron.brew(object, crutches)).to eq({name: 'Other'}.as_json) } + specify { expect(type.cauldron.brew(object, crutches)).to eq({ name: 'Other' }.as_json) } end end @@ -79,14 +79,18 @@ def self.mapping(&block) end end - let(:object) { double(queries: [ - {title: 'Title1', body: 'Body1'}, - {title: 'Title2', body: 'Body2'} - ]) } - specify { expect(type.cauldron.brew(object)).to eq({ queries: [ - {title: 'Title1', body: 'This Body1'}, - {title: 'Title2', body: 'This Body2'} - ] }.as_json) } + let(:object) do + double(queries: [ + { title: 'Title1', body: 'Body1' }, + { title: 'Title2', body: 'Body2' } + ]) + end + specify do + expect(type.cauldron.brew(object)).to eq({ queries: [ + { title: 'Title1', body: 'This Body1' }, + { title: 'Title2', body: 'This Body2' } + ] }.as_json) + end end context do @@ -97,14 +101,18 @@ def self.mapping(&block) end end - let(:object) { double(queries: [ - double(title: 'Title1', body: 'Body1'), - double(title: 'Title2', body: 'Body2') - ]) } - specify { expect(type.cauldron.brew(object)).to eq({ queries: [ - {title: 'Title1', body: 'This Body1'}, - {title: 'Title2', body: 'This Body2'} - ] }.as_json) } + let(:object) do + double(queries: [ + double(title: 'Title1', body: 'Body1'), + double(title: 'Title2', body: 'Body2') + ]) + end + specify do + expect(type.cauldron.brew(object)).to eq({ queries: [ + { title: 'Title1', body: 'This Body1' }, + { title: 'Title2', body: 'This Body2' } + ] }.as_json) + end end context do @@ -115,14 +123,18 @@ def self.mapping(&block) end end - let(:object) { double(queries: [ - double(title: 'Title1', body: 'Body1'), - double(title: 'Title2', body: 'Body2') - ]) } - specify { expect(type.cauldron.brew(object)).to eq({ queries: [ - {title: 'Title1', body: 'This Body1'}, - {title: 'Title2', body: 'This Body2'} - ] }.as_json) } + let(:object) do + double(queries: [ + double(title: 'Title1', body: 'Body1'), + double(title: 'Title2', body: 'Body2') + ]) + end + specify do + expect(type.cauldron.brew(object)).to eq({ queries: [ + { title: 'Title1', body: 'This Body1' }, + { title: 'Title2', body: 'This Body2' } + ] }.as_json) + end end context do @@ -130,24 +142,28 @@ def self.mapping(&block) field :queries do field :fields, value: -> (_o, q) { q.fields } do field :first - field :second, value: -> (_o, q, f, c) { + field :second, value: lambda { |_o, q, f, c| q.value + (f.respond_to?(:second) ? f.second : c.second) } end end end - let(:object) { double(queries: [ - double(value: 'Value1', fields: [double(first: 'First1', second: 'Second1'), {first: 'First2'}]), - double(value: 'Value2', fields: double(first: 'First3', second: 'Second2', third: 'Third')) - ]) } - specify { expect(type.cauldron.brew(object, double(second: 'Crutch'))).to eq({queries: [ - {fields: [ - {first: 'First1', second: 'Value1Second1'}, - {first: 'First2', second: 'Value1Crutch'} - ]}, - {fields: {first: 'First3', second: 'Value2Second2'}} - ]}.as_json) } + let(:object) do + double(queries: [ + double(value: 'Value1', fields: [double(first: 'First1', second: 'Second1'), { first: 'First2' }]), + double(value: 'Value2', fields: double(first: 'First3', second: 'Second2', third: 'Third')) + ]) + end + specify do + expect(type.cauldron.brew(object, double(second: 'Crutch'))).to eq({ queries: [ + { fields: [ + { first: 'First1', second: 'Value1Second1' }, + { first: 'First2', second: 'Value1Crutch' } + ] }, + { fields: { first: 'First3', second: 'Value2Second2' } } + ] }.as_json) + end end end diff --git a/spec/chewy/type_spec.rb b/spec/chewy/type_spec.rb index 2b1f950ad..1fad9bb67 100644 --- a/spec/chewy/type_spec.rb +++ b/spec/chewy/type_spec.rb @@ -22,7 +22,7 @@ def self.by_name specify { expect { PlacesIndex::City.non_existing_method_call }.to raise_error(NoMethodError) } specify { expect(PlacesIndex::City._default_import_options).to eq({}) } - specify { expect { PlacesIndex::City.default_import_options(invalid_option: "Yeah!") }.to raise_error(ArgumentError) } + specify { expect { PlacesIndex::City.default_import_options(invalid_option: 'Yeah!') }.to raise_error(ArgumentError) } context 'default_import_options is set' do let(:converter) { -> {} } diff --git a/spec/chewy_spec.rb b/spec/chewy_spec.rb index 756a070f0..a627caf25 100644 --- a/spec/chewy_spec.rb +++ b/spec/chewy_spec.rb @@ -19,11 +19,11 @@ end end - specify { expect { described_class.derive_type('developers_index#developers') }.to raise_error Chewy::UnderivableType, /DevelopersIndexIndex/ } - specify { expect { described_class.derive_type('some#developers') }.to raise_error Chewy::UnderivableType, /SomeIndex/ } - specify { expect { described_class.derive_type('borogoves#developers') }.to raise_error Chewy::UnderivableType, /Borogoves/ } - specify { expect { described_class.derive_type('developers#borogoves') }.to raise_error Chewy::UnderivableType, /DevelopersIndex.*borogoves/ } - specify { expect { described_class.derive_type('namespace/autocomplete') }.to raise_error Chewy::UnderivableType, /AutocompleteIndex.*namespace\/autocomplete#type_name/ } + specify { expect { described_class.derive_type('developers_index#developers') }.to raise_error(Chewy::UnderivableType, /DevelopersIndexIndex/) } + specify { expect { described_class.derive_type('some#developers') }.to raise_error(Chewy::UnderivableType, /SomeIndex/) } + specify { expect { described_class.derive_type('borogoves#developers') }.to raise_error(Chewy::UnderivableType, /Borogoves/) } + specify { expect { described_class.derive_type('developers#borogoves') }.to raise_error(Chewy::UnderivableType, /DevelopersIndex.*borogoves/) } + specify { expect { described_class.derive_type('namespace/autocomplete') }.to raise_error(Chewy::UnderivableType, %r{AutocompleteIndex.*namespace/autocomplete#type_name}) } specify { expect(described_class.derive_type(DevelopersIndex::Developer)).to eq(DevelopersIndex::Developer) } specify { expect(described_class.derive_type('developers')).to eq(DevelopersIndex::Developer) } @@ -113,7 +113,7 @@ describe '.client' do let!(:initial_client) { Thread.current[:chewy_client] } - let(:faraday_block) { proc { } } + let(:faraday_block) { proc {} } let(:mock_client) { double(:client) } let(:expected_client_config) { { transport_options: {} } } diff --git a/spec/support/active_record.rb b/spec/support/active_record.rb index 16aaa4dbb..dac4ef7a7 100644 --- a/spec/support/active_record.rb +++ b/spec/support/active_record.rb @@ -25,7 +25,7 @@ def adapter :active_record end - def stub_model name, superclass = nil, &block + def stub_model(name, superclass = nil, &block) stub_class(name, superclass || ActiveRecord::Base, &block) end end diff --git a/spec/support/class_helpers.rb b/spec/support/class_helpers.rb index c4835ee65..04e0e9fa1 100644 --- a/spec/support/class_helpers.rb +++ b/spec/support/class_helpers.rb @@ -1,30 +1,30 @@ module ClassHelpers extend ActiveSupport::Concern - def stub_index name, superclass = nil, &block + def stub_index(name, superclass = nil, &block) stub_class("#{name.to_s.camelize}Index", superclass || Chewy::Index) .tap { |i| i.class_eval(&block) if block } end - def stub_class name, superclass = nil, &block + def stub_class(name, superclass = nil, &block) stub_const(name.to_s.camelize, Class.new(superclass || Object, &block)) end - def stub_model _name, _superclass = nil + def stub_model(_name, _superclass = nil) raise NotImplementedError, 'Seems like no ORM/ODM are loaded, please check your Gemfile' end - def skip_on_version_gte version, message = "Removed from elasticsearch #{version}" + def skip_on_version_gte(version, message = "Removed from elasticsearch #{version}") skip message if Chewy::Runtime.version >= version end - def skip_on_version_lt version, message = "Only for elasticsearch #{version} and greater" + def skip_on_version_lt(version, message = "Only for elasticsearch #{version} and greater") skip message if Chewy::Runtime.version < version end - def skip_on_plugin_missing_from_version plugin, version, message = "Plugin '#{plugin}' is missing on elasticsearch > #{version}" + def skip_on_plugin_missing_from_version(plugin, version, message = "Plugin '#{plugin}' is missing on elasticsearch > #{version}") return if Chewy::Runtime.version < version - plugins = Chewy.client.nodes.info(plugins: true)["nodes"].values.map { |item| item["plugins"] }.flatten - skip message unless plugins.find { |item| item["name"] == plugin } + plugins = Chewy.client.nodes.info(plugins: true)['nodes'].values.map { |item| item['plugins'] }.flatten + skip message unless plugins.find { |item| item['name'] == plugin } end end diff --git a/spec/support/mongoid.rb b/spec/support/mongoid.rb index b66805429..2a5082323 100644 --- a/spec/support/mongoid.rb +++ b/spec/support/mongoid.rb @@ -11,7 +11,7 @@ uri: 'mongodb://127.0.0.1:27017/chewy_mongoid_test' } } -} +}.freeze Mongoid.configure do |config| config.load_configuration(CONFIG) @@ -49,7 +49,7 @@ def adapter :mongoid end - def stub_model name, superclass = nil, &block + def stub_model(name, superclass = nil, &block) mixin = "MongoidClassHelpers::#{name.to_s.camelize}".safe_constantize || Mongoid::Document superclass ||= Class.new do include mixin diff --git a/spec/support/sequel.rb b/spec/support/sequel.rb index e5a076409..6dce0a9ca 100644 --- a/spec/support/sequel.rb +++ b/spec/support/sequel.rb @@ -1,6 +1,6 @@ require 'database_cleaner' -DB = Sequel.sqlite# logger: Logger.new(STDOUT) +DB = Sequel.sqlite # logger: Logger.new(STDOUT) DB.create_table :countries do primary_key :id