From e7188d6d86381e77925076423a3e6afe17b70618 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 8 May 2023 13:11:20 +0400 Subject: [PATCH 01/17] Update Rubocop version and configs, add .rubocop_todo.yml --- .rubocop.yml | 237 +++++++++++++++++++++++++++++++++- .rubocop_todo.yml | 320 ++++++++++++++++++++++++++++++++++++++++++++++ Gemfile | 4 +- 3 files changed, 556 insertions(+), 5 deletions(-) create mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml index 8b62c6d..4c72455 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,6 @@ --- +inherit_from: .rubocop_todo.yml + require: - rubocop-rspec @@ -10,9 +12,6 @@ Metrics/BlockLength: - "Gemfile" - "spec/**/*" -Style/BracesAroundHashParameters: - EnforcedStyle: context_dependent - Style/StringLiterals: EnforcedStyle: double_quotes @@ -44,3 +43,235 @@ Style/TrailingCommaInHashLiteral: Enabled: true EnforcedStyleForMultiline: consistent_comma +Gemspec/DeprecatedAttributeAssignment: # new in 1.30 + Enabled: true +Gemspec/DevelopmentDependencies: # new in 1.44 + Enabled: true +Gemspec/RequireMFA: # new in 1.23 + Enabled: true +Layout/LineContinuationLeadingSpace: # new in 1.31 + Enabled: true +Layout/LineContinuationSpacing: # new in 1.31 + Enabled: true +Layout/LineEndStringConcatenationIndentation: # new in 1.18 + Enabled: true +Layout/SpaceBeforeBrackets: # new in 1.7 + Enabled: true +Lint/AmbiguousAssignment: # new in 1.7 + Enabled: true +Lint/AmbiguousOperatorPrecedence: # new in 1.21 + Enabled: true +Lint/AmbiguousRange: # new in 1.19 + Enabled: true +Lint/ConstantOverwrittenInRescue: # new in 1.31 + Enabled: true +Lint/DeprecatedConstants: # new in 1.8 + Enabled: true +Lint/DuplicateBranch: # new in 1.3 + Enabled: true +Lint/DuplicateMagicComment: # new in 1.37 + Enabled: true +Lint/DuplicateMatchPattern: # new in 1.50 + Enabled: true +Lint/DuplicateRegexpCharacterClassElement: # new in 1.1 + Enabled: true +Lint/EmptyBlock: # new in 1.1 + Enabled: true +Lint/EmptyClass: # new in 1.3 + Enabled: true +Lint/EmptyInPattern: # new in 1.16 + Enabled: true +Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21 + Enabled: true +Lint/LambdaWithoutLiteralBlock: # new in 1.8 + Enabled: true +Lint/NoReturnInBeginEndBlocks: # new in 1.2 + Enabled: true +Lint/NonAtomicFileOperation: # new in 1.31 + Enabled: true +Lint/NumberedParameterAssignment: # new in 1.9 + Enabled: true +Lint/OrAssignmentToConstant: # new in 1.9 + Enabled: true +Lint/RedundantDirGlobSort: # new in 1.8 + Enabled: true +Lint/RefinementImportMethods: # new in 1.27 + Enabled: true +Lint/RequireRangeParentheses: # new in 1.32 + Enabled: true +Lint/RequireRelativeSelfPath: # new in 1.22 + Enabled: true +Lint/SymbolConversion: # new in 1.9 + Enabled: true +Lint/ToEnumArguments: # new in 1.1 + Enabled: true +Lint/TripleQuotes: # new in 1.9 + Enabled: true +Lint/UnexpectedBlockArity: # new in 1.5 + Enabled: true +Lint/UnmodifiedReduceAccumulator: # new in 1.1 + Enabled: true +Lint/UselessRescue: # new in 1.43 + Enabled: true +Lint/UselessRuby2Keywords: # new in 1.23 + Enabled: true +Metrics/CollectionLiteralLength: # new in 1.47 + Enabled: true +Naming/BlockForwarding: # new in 1.24 + Enabled: true +Security/CompoundHash: # new in 1.28 + Enabled: true +Security/IoMethods: # new in 1.22 + Enabled: true +Style/ArgumentsForwarding: # new in 1.1 + Enabled: true +Style/ArrayIntersect: # new in 1.40 + Enabled: true +Style/CollectionCompact: # new in 1.2 + Enabled: true +Style/ComparableClamp: # new in 1.44 + Enabled: true +Style/ConcatArrayLiterals: # new in 1.41 + Enabled: true +Style/DataInheritance: # new in 1.49 + Enabled: true +Style/DirEmpty: # new in 1.48 + Enabled: true +Style/DocumentDynamicEvalDefinition: # new in 1.1 + Enabled: true +Style/EmptyHeredoc: # new in 1.32 + Enabled: true +Style/EndlessMethod: # new in 1.8 + Enabled: true +Style/EnvHome: # new in 1.29 + Enabled: true +Style/FetchEnvVar: # new in 1.28 + Enabled: true +Style/FileEmpty: # new in 1.48 + Enabled: true +Style/FileRead: # new in 1.24 + Enabled: true +Style/FileWrite: # new in 1.24 + Enabled: true +Style/HashConversion: # new in 1.10 + Enabled: true +Style/HashExcept: # new in 1.7 + Enabled: true +Style/IfWithBooleanLiteralBranches: # new in 1.9 + Enabled: true +Style/InPatternThen: # new in 1.16 + Enabled: true +Style/MagicCommentFormat: # new in 1.35 + Enabled: true +Style/MapCompactWithConditionalBlock: # new in 1.30 + Enabled: true +Style/MapToHash: # new in 1.24 + Enabled: true +Style/MapToSet: # new in 1.42 + Enabled: true +Style/MinMaxComparison: # new in 1.42 + Enabled: true +Style/MultilineInPatternThen: # new in 1.16 + Enabled: true +Style/NegatedIfElseCondition: # new in 1.2 + Enabled: true +Style/NestedFileDirname: # new in 1.26 + Enabled: true +Style/NilLambda: # new in 1.3 + Enabled: true +Style/NumberedParameters: # new in 1.22 + Enabled: true +Style/NumberedParametersLimit: # new in 1.22 + Enabled: true +Style/ObjectThen: # new in 1.28 + Enabled: true +Style/OpenStructUse: # new in 1.23 + Enabled: true +Style/OperatorMethodCall: # new in 1.37 + Enabled: true +Style/QuotedSymbols: # new in 1.16 + Enabled: true +Style/RedundantArgument: # new in 1.4 + Enabled: true +Style/RedundantConstantBase: # new in 1.40 + Enabled: true +Style/RedundantDoubleSplatHashBraces: # new in 1.41 + Enabled: true +Style/RedundantEach: # new in 1.38 + Enabled: true +Style/RedundantHeredocDelimiterQuotes: # new in 1.45 + Enabled: true +Style/RedundantInitialize: # new in 1.27 + Enabled: true +Style/RedundantLineContinuation: # new in 1.49 + Enabled: true +Style/RedundantSelfAssignmentBranch: # new in 1.19 + Enabled: true +Style/RedundantStringEscape: # new in 1.37 + Enabled: true +Style/SelectByRegexp: # new in 1.22 + Enabled: true +Style/StringChars: # new in 1.12 + Enabled: true +Style/SwapValues: # new in 1.1 + Enabled: true +Capybara/MatchStyle: # new in 2.17 + Enabled: true +Capybara/NegationMatcher: # new in 2.14 + Enabled: true +Capybara/SpecificActions: # new in 2.14 + Enabled: true +Capybara/SpecificFinders: # new in 2.13 + Enabled: true +Capybara/SpecificMatcher: # new in 2.12 + Enabled: true +RSpec/BeEmpty: # new in 2.20 + Enabled: true +RSpec/BeEq: # new in 2.9.0 + Enabled: true +RSpec/BeNil: # new in 2.9.0 + Enabled: true +RSpec/ChangeByZero: # new in 2.11 + Enabled: true +RSpec/ContainExactly: # new in 2.19 + Enabled: true +RSpec/DuplicatedMetadata: # new in 2.16 + Enabled: true +RSpec/ExcessiveDocstringSpacing: # new in 2.5 + Enabled: true +RSpec/IdenticalEqualityAssertion: # new in 2.4 + Enabled: true +RSpec/IndexedLet: # new in 2.20 + Enabled: true +RSpec/MatchArray: # new in 2.19 + Enabled: true +RSpec/NoExpectationExample: # new in 2.13 + Enabled: true +RSpec/PendingWithoutReason: # new in 2.16 + Enabled: true +RSpec/RedundantAround: # new in 2.19 + Enabled: true +RSpec/SkipBlockInsideExample: # new in 2.19 + Enabled: true +RSpec/SortMetadata: # new in 2.14 + Enabled: true +RSpec/SubjectDeclaration: # new in 2.5 + Enabled: true +RSpec/VerifiedDoubleReference: # new in 2.10.0 + Enabled: true +RSpec/FactoryBot/ConsistentParenthesesStyle: # new in 2.14 + Enabled: true +RSpec/FactoryBot/FactoryNameStyle: # new in 2.16 + Enabled: true +RSpec/FactoryBot/SyntaxMethods: # new in 2.7 + Enabled: true +RSpec/Rails/AvoidSetupHook: # new in 2.4 + Enabled: true +RSpec/Rails/HaveHttpStatus: # new in 2.12 + Enabled: true +RSpec/Rails/InferredSpecType: # new in 2.14 + Enabled: true +RSpec/Rails/MinitestAssertions: # new in 2.17 + Enabled: true +RSpec/Rails/TravelAround: # new in 2.19 + Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000..caf16ca --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,320 @@ +# This configuration was generated by +# `rubocop --auto-gen-config --exclude-limit 10000` +# on 2023-05-08 09:01:57 UTC using RuboCop version 1.50.2. +# 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: 3 +# Configuration parameters: EnforcedStyle, AllowedGems, Include. +# SupportedStyles: Gemfile, gems.rb, gemspec +# Include: **/*.gemspec, **/Gemfile, **/gems.rb +Gemspec/DevelopmentDependencies: + Exclude: + - 'graphql-anycable.gemspec' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: Severity, Include. +# Include: **/*.gemspec +Gemspec/RequireMFA: + Exclude: + - 'graphql-anycable.gemspec' + +# Offense count: 1 +# Configuration parameters: Severity, Include. +# Include: **/*.gemspec +Gemspec/RequiredRubyVersion: + Exclude: + - 'graphql-anycable.gemspec' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLineAfterGuardClause: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. +Layout/EmptyLineBetweenDefs: + Exclude: + - 'spec/support/graphql_schema.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +Layout/EmptyLines: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + - 'spec/support/graphql_schema.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/LeadingEmptyLines: + Exclude: + - 'spec/integrations/per_client_subscriptions_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, IndentationWidth. +# SupportedStyles: aligned, indented +Layout/LineEndStringConcatenationIndentation: + Exclude: + - 'lib/graphql-anycable.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Layout/SpaceAfterComma: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 62 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. +# SupportedStyles: space, no_space, compact +# SupportedStylesForEmptyBraces: space, no_space +Layout/SpaceInsideHashLiteralBraces: + Exclude: + - 'spec/integration_helper.rb' + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + - 'spec/integrations/rails_spec.rb' + - 'spec/support/graphql_schema.rb' + +# Offense count: 24 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowInHeredoc. +Layout/TrailingWhitespace: + Exclude: + - 'spec/integration_helper.rb' + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 1 +Lint/NonLocalExitFromIterator: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Lint/RedundantCopDisableDirective: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. +Metrics/AbcSize: + Max: 21 + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 129 + +# Offense count: 1 +# Configuration parameters: AllowedMethods, AllowedPatterns. +Metrics/CyclomaticComplexity: + Max: 8 + +# Offense count: 2 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 25 + +# Offense count: 1 +# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. +# CheckDefinitionPathHierarchyRoots: lib, spec, test, src +# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS +Naming/FileName: + Exclude: + - 'lib/graphql-anycable.rb' + +# Offense count: 6 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 +Naming/VariableNumber: + Exclude: + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 2 +RSpec/AnyInstance: + Exclude: + - 'spec/graphql/anycable_spec.rb' + +# Offense count: 3 +# Configuration parameters: Prefixes, AllowedPatterns. +# Prefixes: when, with, without +RSpec/ContextWording: + Exclude: + - 'spec/graphql/anycable_spec.rb' + - 'spec/integration_helper.rb' + +# Offense count: 3 +# Configuration parameters: IgnoredMetadata. +RSpec/DescribeClass: + Exclude: + - '**/spec/features/**/*' + - '**/spec/requests/**/*' + - '**/spec/routing/**/*' + - '**/spec/system/**/*' + - '**/spec/views/**/*' + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 4 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: SkipBlocks, EnforcedStyle. +# SupportedStyles: described_class, explicit +RSpec/DescribedClass: + Exclude: + - 'spec/graphql/anycable_spec.rb' + +# Offense count: 13 +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 35 + +# Offense count: 1 +# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. +# Include: **/*_spec*rb*, **/spec/**/* +RSpec/FilePath: + Exclude: + - 'spec/graphql/anycable_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: implicit, each, example +RSpec/HookArgument: + Exclude: + - 'spec/redis_helper.rb' + +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +RSpec/LeadingSubject: + Exclude: + - 'spec/graphql/anycable_spec.rb' + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 20 +# Configuration parameters: AllowSubject. +RSpec/MultipleMemoizedHelpers: + Max: 8 + +# Offense count: 25 +# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. +# SupportedStyles: always, named_only +RSpec/NamedSubject: + Exclude: + - 'spec/graphql/anycable_spec.rb' + - 'spec/integrations/broadcastable_subscriptions_spec.rb' + - 'spec/integrations/per_client_subscriptions_spec.rb' + +# Offense count: 6 +# This cop supports safe autocorrection (--autocorrect). +RSpec/ScatteredLet: + Exclude: + - 'spec/integrations/rails_spec.rb' + +# Offense count: 7 +# This cop supports safe autocorrection (--autocorrect). +RSpec/ScatteredSetup: + Exclude: + - 'spec/graphql/anycable_spec.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 7 +# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. +RSpec/VerifiedDoubles: + Exclude: + - 'spec/graphql/anycable_spec.rb' + - 'spec/graphql/broadcast_spec.rb' + +# Offense count: 5 +# Configuration parameters: AllowedConstants. +Style/Documentation: + Exclude: + - 'spec/**/*' + - 'test/**/*' + - 'lib/graphql-anycable.rb' + - 'lib/graphql/anycable/cleaner.rb' + - 'lib/graphql/anycable/config.rb' + - 'lib/graphql/anycable/railtie.rb' + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 1 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, always_true, never +Style/FrozenStringLiteralComment: + Exclude: + - 'lib/graphql/anycable/errors.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowSplatArgument. +Style/HashConversion: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantAssignment: + Exclude: + - 'spec/integration_helper.rb' + +# Offense count: 3 +# This cop supports safe autocorrection (--autocorrect). +Style/RedundantConstantBase: + Exclude: + - 'spec/integrations/rails_spec.rb' + +# Offense count: 9 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: + Exclude: + - 'Gemfile' + - 'lib/graphql/anycable/cleaner.rb' + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'lib/graphql/subscriptions/anycable_subscriptions.rb' + - 'spec/integrations/rails_spec.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInArrayLiteral: + Exclude: + - 'spec/support/graphql_schema.rb' + +# Offense count: 1 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: EnforcedStyleForMultiline. +# SupportedStylesForMultiline: comma, consistent_comma, no_comma +Style/TrailingCommaInHashLiteral: + Exclude: + - 'spec/integrations/rails_spec.rb' + +# Offense count: 4 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 145 diff --git a/Gemfile b/Gemfile index e74ef60..d99cd6d 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,6 @@ group :development, :test do gem "pry" gem "pry-byebug", platform: :mri - gem "rubocop" - gem "rubocop-rspec" + gem 'rubocop', '~> 1.50', '>= 1.50.2', require: false + gem 'rubocop-rspec', '~> 2.20', require: false end From fc95269f1e8eb5157d473af3427b54f37d595648 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 8 May 2023 13:11:47 +0400 Subject: [PATCH 02/17] add Rubocop workflow to GitHub Actions --- .github/workflows/rubocop.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/rubocop.yml diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml new file mode 100644 index 0000000..16132dd --- /dev/null +++ b/.github/workflows/rubocop.yml @@ -0,0 +1,20 @@ +name: Rubocop + +on: [push, pull_request] + +jobs: + lint: + name: "Rubocop" + runs-on: ubuntu-latest + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2' + bundler-cache: true + - name: Bundle Update + run: bundle update + - name: Run Rubocop + run: bundle exec rubocop From beb47a2a44c0970293b6eeff290ee488593e0f3b Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 13:56:27 +0400 Subject: [PATCH 03/17] run rubocop --autocorrect --- .rubocop.yml | 1 + .rubocop_todo.yml | 161 +----------------- Gemfile | 4 +- graphql-anycable.gemspec | 1 + lib/graphql-anycable.rb | 2 +- lib/graphql/anycable/cleaner.rb | 2 +- .../tasks/clean_expired_subscriptions.rake | 3 +- .../subscriptions/anycable_subscriptions.rb | 14 +- spec/graphql/anycable_spec.rb | 18 +- spec/integration_helper.rb | 50 +++--- .../broadcastable_subscriptions_spec.rb | 46 ++--- .../per_client_subscriptions_spec.rb | 37 ++-- spec/integrations/rails_spec.rb | 60 +++---- spec/redis_helper.rb | 2 +- spec/support/graphql_schema.rb | 11 +- 15 files changed, 122 insertions(+), 290 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4c72455..b38ce42 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,7 @@ --- inherit_from: .rubocop_todo.yml + require: - rubocop-rspec diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index caf16ca..05cc4d3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by -# `rubocop --auto-gen-config --exclude-limit 10000` -# on 2023-05-08 09:01:57 UTC using RuboCop version 1.50.2. +# `rubocop --auto-gen-config` +# on 2023-05-09 09:45:24 UTC using RuboCop version 1.50.2. # 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 @@ -14,14 +14,6 @@ Gemspec/DevelopmentDependencies: Exclude: - 'graphql-anycable.gemspec' -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec -Gemspec/RequireMFA: - Exclude: - - 'graphql-anycable.gemspec' - # Offense count: 1 # Configuration parameters: Severity, Include. # Include: **/*.gemspec @@ -29,69 +21,6 @@ Gemspec/RequiredRubyVersion: Exclude: - 'graphql-anycable.gemspec' -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLineAfterGuardClause: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. -Layout/EmptyLineBetweenDefs: - Exclude: - - 'spec/support/graphql_schema.rb' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLines: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - - 'spec/support/graphql_schema.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/LeadingEmptyLines: - Exclude: - - 'spec/integrations/per_client_subscriptions_spec.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented -Layout/LineEndStringConcatenationIndentation: - Exclude: - - 'lib/graphql-anycable.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/SpaceAfterComma: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 62 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space, compact -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceInsideHashLiteralBraces: - Exclude: - - 'spec/integration_helper.rb' - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - 'spec/integrations/rails_spec.rb' - - 'spec/support/graphql_schema.rb' - -# Offense count: 24 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowInHeredoc. -Layout/TrailingWhitespace: - Exclude: - - 'spec/integration_helper.rb' - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - 'spec/integrations/rails_spec.rb' - # Offense count: 1 Lint/NonLocalExitFromIterator: Exclude: @@ -121,7 +50,7 @@ Metrics/CyclomaticComplexity: # Offense count: 2 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 25 + Max: 23 # Offense count: 1 # Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. @@ -187,23 +116,6 @@ RSpec/FilePath: Exclude: - 'spec/graphql/anycable_spec.rb' -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: implicit, each, example -RSpec/HookArgument: - Exclude: - - 'spec/redis_helper.rb' - -# Offense count: 5 -# This cop supports safe autocorrection (--autocorrect). -RSpec/LeadingSubject: - Exclude: - - 'spec/graphql/anycable_spec.rb' - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - 'spec/integrations/rails_spec.rb' - # Offense count: 20 # Configuration parameters: AllowSubject. RSpec/MultipleMemoizedHelpers: @@ -218,19 +130,6 @@ RSpec/NamedSubject: - 'spec/integrations/broadcastable_subscriptions_spec.rb' - 'spec/integrations/per_client_subscriptions_spec.rb' -# Offense count: 6 -# This cop supports safe autocorrection (--autocorrect). -RSpec/ScatteredLet: - Exclude: - - 'spec/integrations/rails_spec.rb' - -# Offense count: 7 -# This cop supports safe autocorrection (--autocorrect). -RSpec/ScatteredSetup: - Exclude: - - 'spec/graphql/anycable_spec.rb' - - 'spec/integrations/rails_spec.rb' - # Offense count: 7 # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: @@ -260,60 +159,6 @@ Style/FrozenStringLiteralComment: # Offense count: 2 # This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowSplatArgument. -Style/HashConversion: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantAssignment: - Exclude: - - 'spec/integration_helper.rb' - -# Offense count: 3 -# This cop supports safe autocorrection (--autocorrect). -Style/RedundantConstantBase: - Exclude: - - 'spec/integrations/rails_spec.rb' - -# Offense count: 9 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Exclude: - - 'Gemfile' - - 'lib/graphql/anycable/cleaner.rb' - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 4 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - - 'spec/integrations/rails_spec.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArrayLiteral: - Exclude: - - 'spec/support/graphql_schema.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInHashLiteral: - Exclude: - - 'spec/integrations/rails_spec.rb' - -# Offense count: 4 -# This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. # URISchemes: http, https Layout/LineLength: diff --git a/Gemfile b/Gemfile index d99cd6d..ce679a1 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,6 @@ group :development, :test do gem "pry" gem "pry-byebug", platform: :mri - gem 'rubocop', '~> 1.50', '>= 1.50.2', require: false - gem 'rubocop-rspec', '~> 2.20', require: false + gem "rubocop", "~> 1.50", ">= 1.50.2", require: false + gem "rubocop-rspec", "~> 2.20", require: false end diff --git a/graphql-anycable.gemspec b/graphql-anycable.gemspec index a5496e0..aeb714d 100644 --- a/graphql-anycable.gemspec +++ b/graphql-anycable.gemspec @@ -37,4 +37,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "railties" spec.add_development_dependency "rake", ">= 12.3.3" spec.add_development_dependency "rspec", "~> 3.0" + spec.metadata["rubygems_mfa_required"] = "true" end diff --git a/lib/graphql-anycable.rb b/lib/graphql-anycable.rb index c3896c5..9055bcc 100644 --- a/lib/graphql-anycable.rb +++ b/lib/graphql-anycable.rb @@ -27,7 +27,7 @@ def redis adapter = ::AnyCable.broadcast_adapter unless adapter.is_a?(::AnyCable::BroadcastAdapters::Redis) raise "Unsupported AnyCable adapter: #{adapter.class}. " \ - "graphql-anycable works only with redis broadcast adapter." + "graphql-anycable works only with redis broadcast adapter." end ::AnyCable.broadcast_adapter.redis_conn end diff --git a/lib/graphql/anycable/cleaner.rb b/lib/graphql/anycable/cleaner.rb index aab37c2..65151a8 100644 --- a/lib/graphql/anycable/cleaner.rb +++ b/lib/graphql/anycable/cleaner.rb @@ -48,7 +48,7 @@ def clean_fingerprint_subscriptions def clean_topic_fingerprints redis.scan_each(match: "#{adapter::FINGERPRINTS_PREFIX}*") do |key| - redis.zremrangebyscore(key, '-inf', '0') + redis.zremrangebyscore(key, "-inf", "0") redis.zrange(key, 0, -1).each do |fingerprint| next if redis.exists?(adapter::SUBSCRIPTIONS_PREFIX + fingerprint) diff --git a/lib/graphql/anycable/tasks/clean_expired_subscriptions.rake b/lib/graphql/anycable/tasks/clean_expired_subscriptions.rake index c9043a6..979a713 100644 --- a/lib/graphql/anycable/tasks/clean_expired_subscriptions.rake +++ b/lib/graphql/anycable/tasks/clean_expired_subscriptions.rake @@ -5,7 +5,8 @@ require "graphql-anycable" namespace :graphql do namespace :anycable do desc "Clean up stale graphql channels, subscriptions, and events from redis" - task clean: %i[clean:channels clean:subscriptions clean:events clean:fingerprint_subscriptions clean:topic_fingerprints] + task clean: %i[clean:channels clean:subscriptions clean:events clean:fingerprint_subscriptions + clean:topic_fingerprints] namespace :clean do # Clean up old channels diff --git a/lib/graphql/subscriptions/anycable_subscriptions.rb b/lib/graphql/subscriptions/anycable_subscriptions.rb index 4d9aca3..59889c9 100644 --- a/lib/graphql/subscriptions/anycable_subscriptions.rb +++ b/lib/graphql/subscriptions/anycable_subscriptions.rb @@ -73,20 +73,20 @@ def execute_all(event, object) fingerprints = redis.zrange(FINGERPRINTS_PREFIX + event.topic, 0, -1) return if fingerprints.empty? - fingerprint_subscription_ids = Hash[fingerprints.zip( + fingerprint_subscription_ids = fingerprints.zip( redis.pipelined do |pipeline| fingerprints.map do |fingerprint| pipeline.smembers(SUBSCRIPTIONS_PREFIX + fingerprint) end - end - )] + end, + ).to_h fingerprint_subscription_ids.each do |fingerprint, subscription_ids| execute_grouped(fingerprint, subscription_ids, event, object) end # Call to +trigger+ returns this. Convenient for playing in console - Hash[fingerprint_subscription_ids.map { |k,v| [k, v.size] }] + fingerprint_subscription_ids.map { |k, v| [k, v.size] }.to_h end # The fingerprint has told us that this response should be shared by all subscribers, @@ -131,7 +131,6 @@ def write_subscription(query, events) # Store subscription_id in the channel state to cleanup on disconnect write_subscription_id(channel, channel_uniq_id) - events.each do |event| channel.stream_from(SUBSCRIPTIONS_PREFIX + event.fingerprint) end @@ -152,6 +151,7 @@ def write_subscription(query, events) pipeline.sadd(SUBSCRIPTIONS_PREFIX + event.fingerprint, [subscription_id]) end next unless config.subscription_expiration_seconds + pipeline.expire(CHANNEL_PREFIX + channel_uniq_id, config.subscription_expiration_seconds) pipeline.expire(SUBSCRIPTION_PREFIX + subscription_id, config.subscription_expiration_seconds) end @@ -161,7 +161,7 @@ def write_subscription(query, events) def read_subscription(subscription_id) redis.mapped_hmget( "#{SUBSCRIPTION_PREFIX}#{subscription_id}", - :query_string, :variables, :context, :operation_name + :query_string, :variables, :context, :operation_name, ).tap do |subscription| return if subscription.values.all?(&:nil?) # Redis returns hash with all nils for missing key @@ -187,7 +187,7 @@ def delete_subscription(subscription_id) # Clean up fingerprints that doesn't have any subscriptions left redis.pipelined do |pipeline| fingerprint_subscriptions.each do |key, score| - pipeline.zremrangebyscore(key, '-inf', '0') if score.value.zero? + pipeline.zremrangebyscore(key, "-inf", "0") if score.value.zero? end end end diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index 8510ebd..b427623 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -90,11 +90,12 @@ end describe ".delete_channel_subscriptions" do - before do - GraphQL::AnyCable.config.use_client_provided_uniq_id = false + subject do + AnycableSchema.subscriptions.delete_channel_subscriptions(channel) end before do + GraphQL::AnyCable.config.use_client_provided_uniq_id = false AnycableSchema.execute( query: query, context: { channel: channel, subscription_id: subscription_id }, @@ -109,10 +110,6 @@ let(:redis) { AnycableSchema.subscriptions.redis } - subject do - AnycableSchema.subscriptions.delete_channel_subscriptions(channel) - end - it "removes subscription from redis" do expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be true expect(redis.exists?("graphql-channel:some-truly-random-number")).to be true @@ -125,11 +122,12 @@ end describe "legacy .delete_channel_subscriptions" do - before do - GraphQL::AnyCable.config.use_client_provided_uniq_id = true + subject do + AnycableSchema.subscriptions.delete_channel_subscriptions(channel.id) end before do + GraphQL::AnyCable.config.use_client_provided_uniq_id = true AnycableSchema.execute( query: query, context: { channel: channel, subscription_id: subscription_id }, @@ -144,10 +142,6 @@ let(:redis) { AnycableSchema.subscriptions.redis } - subject do - AnycableSchema.subscriptions.delete_channel_subscriptions(channel.id) - end - it "removes subscription from redis" do expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be true expect(redis.exists?("graphql-channel:legacy_id")).to be true diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index e76b85a..9722008 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -8,10 +8,10 @@ let(:user) { "john" } let(:schema) { nil } - let(:identifiers) { {current_user: "john", schema: schema.to_s} } + let(:identifiers) { { current_user: "john", schema: schema.to_s } } let(:channel_class) { "GraphqlChannel" } - let(:channel_params) { {channelId: rand(1000).to_s} } - let(:channel_identifier) { {channel: channel_class}.merge(channel_params) } + let(:channel_params) { { channelId: rand(1000).to_s } } + let(:channel_identifier) { { channel: channel_class }.merge(channel_params) } let(:channel_id) { channel_identifier.to_json } let(:handler) { AnyCable::RPC::Handler.new } @@ -52,29 +52,27 @@ def handle_channel_command(identifier, command, data) parsed_id.delete("channel") channel = Channel.new(self, identifier, parsed_id) - res = - case command - when "message" - data = JSON.parse(data) - result = - schema.execute( - query: data["query"], - context: identifiers.merge(channel: channel), - variables: Hash(data["variables"]), - operation_name: data["operationName"], - ) - - transmit( - result: result.subscription? ? { data: nil } : result.to_h, - more: result.subscription?, + case command + when "message" + data = JSON.parse(data) + result = + schema.execute( + query: data["query"], + context: identifiers.merge(channel: channel), + variables: Hash(data["variables"]), + operation_name: data["operationName"], ) - when "unsubscribe" - schema.subscriptions.delete_channel_subscriptions(channel) - true - else - raise "Unknown command" - end - res + + transmit( + result: result.subscription? ? { data: nil } : result.to_h, + more: result.subscription?, + ) + when "unsubscribe" + schema.subscriptions.delete_channel_subscriptions(channel) + true + else + raise "Unknown command" + end end def transmit(data) @@ -87,7 +85,7 @@ def identifiers_json def close socket.close - end + end end AnyCable.connection_factory = ->(socket, **options) { FakeConnection.new(socket, **options) } diff --git a/spec/integrations/broadcastable_subscriptions_spec.rb b/spec/integrations/broadcastable_subscriptions_spec.rb index 8b9a0f4..fdeec4f 100644 --- a/spec/integrations/broadcastable_subscriptions_spec.rb +++ b/spec/integrations/broadcastable_subscriptions_spec.rb @@ -3,6 +3,8 @@ require "integration_helper" RSpec.describe "broadcastable subscriptions" do + subject { handler.handle(:command, request) } + let(:schema) { BroadcastSchema } let(:query) do @@ -16,14 +18,12 @@ } GQL end - let(:variables) { {id: "a"} } + let(:variables) { { id: "a" } } - let(:subscription_payload) { {query: query, variables: variables} } + let(:subscription_payload) { { query: query, variables: variables } } let(:command) { "message" } - let(:data) { {action: "execute", **subscription_payload} } - - subject { handler.handle(:command, request) } + let(:data) { { action: "execute", **subscription_payload } } before { allow(AnyCable.broadcast_adapter).to receive(:broadcast) } @@ -31,7 +31,7 @@ it "responds with result" do expect(subject).to be_success expect(subject.transmissions.size).to eq 1 - expect(subject.transmissions.first).to eq({result: {data: nil}, more: true}.to_json) + expect(subject.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) expect(subject.streams.size).to eq 1 expect(subject.istate["sid"]).not_to be_nil end @@ -51,7 +51,7 @@ expect(response.streams).to eq([stream_name]) # now update the query param - request.data = data.merge(variables: {id: "b"}).to_json + request.data = data.merge(variables: { id: "b" }).to_json request.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json response = handler.handle(:command, request) @@ -88,18 +88,18 @@ # first, subscribe to obtain the connection state subscribe_response = handler.handle(:command, request) expect(subscribe_response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(1) - + istate = subscribe_response.istate - + request.command = "unsubscribe" request.data = "" request.istate[channel_id] = istate.to_h.to_json - + response = handler.handle(:command, request) expect(response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(0) end end @@ -123,7 +123,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).once first_state = response.istate @@ -138,7 +138,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice second_state = response_2.istate @@ -153,7 +153,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(0) expect(redis.keys("graphql-subscriptions:*").size).to eq(0) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice end @@ -172,27 +172,27 @@ # first, subscribe to obtain the connection state subscribe_response = handler.handle(:command, request) expect(subscribe_response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - + # update request context request.connection_identifiers = identifiers.merge(current_user: "alice").to_json - + response = handler.handle(:command, request) - + expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - + istate = response.istate - + request.command = "unsubscribe" request.data = "" request.istate = istate - + response = handler.handle(:command, request) expect(response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) end diff --git a/spec/integrations/per_client_subscriptions_spec.rb b/spec/integrations/per_client_subscriptions_spec.rb index 9a3a47a..9343988 100644 --- a/spec/integrations/per_client_subscriptions_spec.rb +++ b/spec/integrations/per_client_subscriptions_spec.rb @@ -1,9 +1,10 @@ - # frozen_string_literal: true require "integration_helper" RSpec.describe "non-broadcastable subscriptions" do + subject { handler.handle(:command, request) } + let(:schema) { AnycableSchema } let(:query) do @@ -17,14 +18,12 @@ } GQL end - let(:variables) { {id: "a"} } + let(:variables) { { id: "a" } } - let(:subscription_payload) { {query: query, variables: variables} } + let(:subscription_payload) { { query: query, variables: variables } } let(:command) { "message" } - let(:data) { {action: "execute", **subscription_payload} } - - subject { handler.handle(:command, request) } + let(:data) { { action: "execute", **subscription_payload } } before { allow(AnyCable.broadcast_adapter).to receive(:broadcast) } @@ -32,7 +31,7 @@ it "responds with result" do expect(subject).to be_success expect(subject.transmissions.size).to eq 1 - expect(subject.transmissions.first).to eq({result: {data: nil}, more: true}.to_json) + expect(subject.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) expect(subject.streams.size).to eq 1 expect(subject.istate["sid"]).not_to be_nil end @@ -54,7 +53,7 @@ expect(all_streams.size).to eq 2 # now update the query param - request.data = data.merge(variables: {id: "b"}).to_json + request.data = data.merge(variables: { id: "b" }).to_json request.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json response = handler.handle(:command, request) @@ -107,7 +106,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(2) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice first_state = response.istate @@ -122,7 +121,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).thrice second_state = response_2.istate @@ -137,7 +136,7 @@ expect(redis.keys("graphql-subscription:*").size).to eq(0) expect(redis.keys("graphql-subscriptions:*").size).to eq(0) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).thrice end @@ -156,27 +155,27 @@ # first, subscribe to obtain the connection state subscribe_response = handler.handle(:command, request) expect(subscribe_response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - + # update request context request.connection_identifiers = identifiers.merge(current_user: "alice").to_json - + response = handler.handle(:command, request) - + expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(2) - + istate = response.istate - + request.command = "unsubscribe" request.data = "" request.istate = istate - + response = handler.handle(:command, request) expect(response).to be_success - + expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) end diff --git a/spec/integrations/rails_spec.rb b/spec/integrations/rails_spec.rb index da79df7..2a63782 100644 --- a/spec/integrations/rails_spec.rb +++ b/spec/integrations/rails_spec.rb @@ -17,7 +17,7 @@ def self.root require "action_cable/server" require "action_cable/server/base" # Only for anycable-rails <1.3.0 -unless defined?(::AnyCable::Rails::Connection) +unless defined?(AnyCable::Rails::Connection) require "anycable/rails/channel_state" require "anycable/rails/actioncable/connection" end @@ -35,7 +35,7 @@ class GraphqlChannel < ActionCable::Channel::Base delegate :schema_class, to: :connection def execute(data) - result = + result = schema_class.execute( query: data["query"], context: context, @@ -46,8 +46,8 @@ def execute(data) transmit( { result: result.subscription? ? { data: nil } : result.to_h, - more: result.subscription? - } + more: result.subscription?, + }, ) end @@ -67,32 +67,13 @@ def context end RSpec.describe "Rails integration" do - let(:schema) { BroadcastSchema } - let(:channel_class) { "ApplicationCable::GraphqlChannel" } - - if defined?(::AnyCable::Rails::Connection) - before do - allow(AnyCable).to receive(:connection_factory) - .and_return(->(socket, **options) { ::AnyCable::Rails::Connection.new(ApplicationCable::Connection, socket, **options) }) - end - else - before do - allow(AnyCable).to receive(:connection_factory) - .and_return(->(socket, **options) { ApplicationCable::Connection.call(socket, **options) }) - end - end - - let(:variables) { {id: "a"} } - - let(:subscription_payload) { {query: query, variables: variables} } - - let(:command) { "message" } - let(:data) { {action: "execute", **subscription_payload} } - subject { handler.handle(:command, request) } - before { allow(AnyCable.broadcast_adapter).to receive(:broadcast) } - + let(:schema) { BroadcastSchema } + let(:variables) { { id: "a" } } + let(:subscription_payload) { { query: query, variables: variables } } + let(:command) { "message" } + let(:data) { { action: "execute", **subscription_payload } } let(:query) do <<~GQL subscription postSubscription($id: ID!) { @@ -104,8 +85,21 @@ def context } GQL end - let(:redis) { AnycableSchema.subscriptions.redis } + let(:channel_class) { "ApplicationCable::GraphqlChannel" } + + before do + if defined?(AnyCable::Rails::Connection) + allow(AnyCable).to receive(:connection_factory) + .and_return(lambda { |socket, **options| + AnyCable::Rails::Connection.new(ApplicationCable::Connection, socket, **options) + }) + else + allow(AnyCable).to receive(:connection_factory) + .and_return(->(socket, **options) { ApplicationCable::Connection.call(socket, **options) }) + end + allow(AnyCable.broadcast_adapter).to receive(:broadcast) + end it "execute multiple clients + trigger + disconnect one by one" do # first, subscribe to obtain the connection state @@ -126,7 +120,7 @@ def context expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).once first_state = response.istate @@ -141,7 +135,7 @@ def context expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice second_state = response_2.istate @@ -150,7 +144,7 @@ def context disconnect_request = AnyCable::DisconnectRequest.new( identifiers: request_2.connection_identifiers, subscriptions: [request_2.identifier], - env: request_2.env + env: request_2.env, ) disconnect_request.istate[request_2.identifier] = second_state.to_h.to_json @@ -161,7 +155,7 @@ def context expect(redis.keys("graphql-subscription:*").size).to eq(0) expect(redis.keys("graphql-subscriptions:*").size).to eq(0) - schema.subscriptions.trigger(:post_updated, {id: "a"}, POSTS.first) + schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice end end diff --git a/spec/redis_helper.rb b/spec/redis_helper.rb index f7187f3..5b9db5e 100644 --- a/spec/redis_helper.rb +++ b/spec/redis_helper.rb @@ -11,7 +11,7 @@ def setup_redis_test_db setup_redis_test_db RSpec.configure do |config| - config.before(:example) do + config.before do GraphQL::AnyCable.redis.flushdb end end diff --git a/spec/support/graphql_schema.rb b/spec/support/graphql_schema.rb index ee946b1..7d6b60c 100644 --- a/spec/support/graphql_schema.rb +++ b/spec/support/graphql_schema.rb @@ -2,7 +2,7 @@ POSTS = [ { id: "a", title: "GraphQL is good?", actions: %w[yes no] }, - { id: "b", title: "Is there life after GraphQL?", actions: %w[no still-no] } + { id: "b", title: "Is there life after GraphQL?", actions: %w[no still-no] }, ].freeze class Product < GraphQL::Schema::Object @@ -22,11 +22,11 @@ class PostUpdated < GraphQL::Schema::Subscription field :post, Post, null: false def subscribe(id:) - {post: POSTS.find { |post| post[:id] == id }} + { post: POSTS.find { |post| post[:id] == id } } end def update(*) - {post: object} + { post: object } end end @@ -53,18 +53,17 @@ class PostCreated < GraphQL::Schema::Subscription payload_type Post end - class PostUpdated < GraphQL::Schema::Subscription argument :id, ID, required: true field :post, Post, null: false def subscribe(id:) - {post: POSTS.find { |post| post[:id] == id }} + { post: POSTS.find { |post| post[:id] == id } } end def update(*) - {post: object} + { post: object } end end From e08327a635695ed75d1e12508377259cc0af4666 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 15:40:06 +0400 Subject: [PATCH 04/17] run rubocop --autocorrect-all, which fixes unsafe errors too --- .rubocop.yml | 1 + .rubocop_todo.yml | 18 +----------------- lib/graphql/anycable/errors.rb | 2 ++ spec/graphql/anycable_spec.rb | 8 ++++---- 4 files changed, 8 insertions(+), 21 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b38ce42..f852c63 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,7 @@ inherit_from: .rubocop_todo.yml + require: - rubocop-rspec diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 05cc4d3..aa34d17 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2023-05-09 09:45:24 UTC using RuboCop version 1.50.2. +# on 2023-05-09 11:37:51 UTC using RuboCop version 1.50.2. # 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 @@ -96,14 +96,6 @@ RSpec/DescribeClass: - 'spec/integrations/per_client_subscriptions_spec.rb' - 'spec/integrations/rails_spec.rb' -# Offense count: 4 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: SkipBlocks, EnforcedStyle. -# SupportedStyles: described_class, explicit -RSpec/DescribedClass: - Exclude: - - 'spec/graphql/anycable_spec.rb' - # Offense count: 13 # Configuration parameters: CountAsOne. RSpec/ExampleLength: @@ -149,14 +141,6 @@ Style/Documentation: - 'lib/graphql/anycable/railtie.rb' - 'lib/graphql/subscriptions/anycable_subscriptions.rb' -# Offense count: 1 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, always_true, never -Style/FrozenStringLiteralComment: - Exclude: - - 'lib/graphql/anycable/errors.rb' - # Offense count: 2 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. diff --git a/lib/graphql/anycable/errors.rb b/lib/graphql/anycable/errors.rb index 2e25cc0..a558c1d 100644 --- a/lib/graphql/anycable/errors.rb +++ b/lib/graphql/anycable/errors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module GraphQL module AnyCable # This error is thrown when ActionCable channel wasn't provided to subscription implementation. diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index b427623..42ac485 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -95,7 +95,7 @@ end before do - GraphQL::AnyCable.config.use_client_provided_uniq_id = false + described_class.config.use_client_provided_uniq_id = false AnycableSchema.execute( query: query, context: { channel: channel, subscription_id: subscription_id }, @@ -105,7 +105,7 @@ end after do - GraphQL::AnyCable.config.use_client_provided_uniq_id = false + described_class.config.use_client_provided_uniq_id = false end let(:redis) { AnycableSchema.subscriptions.redis } @@ -127,7 +127,7 @@ end before do - GraphQL::AnyCable.config.use_client_provided_uniq_id = true + described_class.config.use_client_provided_uniq_id = true AnycableSchema.execute( query: query, context: { channel: channel, subscription_id: subscription_id }, @@ -137,7 +137,7 @@ end after do - GraphQL::AnyCable.config.use_client_provided_uniq_id = false + described_class.config.use_client_provided_uniq_id = false end let(:redis) { AnycableSchema.subscriptions.redis } From e8b7d32f7b0146317450eb47eebac9f54d1a11d2 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 16:28:58 +0400 Subject: [PATCH 05/17] manually fix some rubocop warnings --- .rubocop.yml | 15 +++++ .rubocop_todo.yml | 67 ------------------- Gemfile | 6 ++ graphql-anycable.gemspec | 8 +-- lib/graphql-anycable.rb | 3 +- .../subscriptions/anycable_subscriptions.rb | 8 ++- spec/graphql/anycable_spec.rb | 3 +- spec/integration_helper.rb | 2 + spec/integrations/rails_spec.rb | 2 + 9 files changed, 36 insertions(+), 78 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f852c63..0322a9c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -45,6 +45,21 @@ Style/TrailingCommaInHashLiteral: Enabled: true EnforcedStyleForMultiline: consistent_comma +Layout/ExtraSpacing: + Enabled: false + +Layout/SpaceAroundOperators: + Enabled: false + + +Naming/FileName: + Exclude: + - 'lib/graphql-anycable.rb' + +RSpec/FilePath: + Exclude: + - 'spec/graphql/anycable_spec.rb' + Gemspec/DeprecatedAttributeAssignment: # new in 1.30 Enabled: true Gemspec/DevelopmentDependencies: # new in 1.44 diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index aa34d17..748ce90 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,59 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 3 -# Configuration parameters: EnforcedStyle, AllowedGems, Include. -# SupportedStyles: Gemfile, gems.rb, gemspec -# Include: **/*.gemspec, **/Gemfile, **/gems.rb -Gemspec/DevelopmentDependencies: - Exclude: - - 'graphql-anycable.gemspec' - -# Offense count: 1 -# Configuration parameters: Severity, Include. -# Include: **/*.gemspec -Gemspec/RequiredRubyVersion: - Exclude: - - 'graphql-anycable.gemspec' - -# Offense count: 1 -Lint/NonLocalExitFromIterator: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Lint/RedundantCopDisableDirective: - Exclude: - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 1 -# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. -Metrics/AbcSize: - Max: 21 - -# Offense count: 1 -# Configuration parameters: CountComments, CountAsOne. -Metrics/ClassLength: - Max: 129 - -# Offense count: 1 -# Configuration parameters: AllowedMethods, AllowedPatterns. -Metrics/CyclomaticComplexity: - Max: 8 - -# Offense count: 2 -# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. -Metrics/MethodLength: - Max: 23 - -# Offense count: 1 -# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms. -# CheckDefinitionPathHierarchyRoots: lib, spec, test, src -# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS -Naming/FileName: - Exclude: - - 'lib/graphql-anycable.rb' # Offense count: 6 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. @@ -101,13 +48,6 @@ RSpec/DescribeClass: RSpec/ExampleLength: Max: 35 -# Offense count: 1 -# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. -# Include: **/*_spec*rb*, **/spec/**/* -RSpec/FilePath: - Exclude: - - 'spec/graphql/anycable_spec.rb' - # Offense count: 20 # Configuration parameters: AllowSubject. RSpec/MultipleMemoizedHelpers: @@ -140,10 +80,3 @@ Style/Documentation: - 'lib/graphql/anycable/config.rb' - 'lib/graphql/anycable/railtie.rb' - 'lib/graphql/subscriptions/anycable_subscriptions.rb' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. -# URISchemes: http, https -Layout/LineLength: - Max: 145 diff --git a/Gemfile b/Gemfile index ce679a1..af6a52b 100644 --- a/Gemfile +++ b/Gemfile @@ -17,4 +17,10 @@ group :development, :test do gem "rubocop", "~> 1.50", ">= 1.50.2", require: false gem "rubocop-rspec", "~> 2.20", require: false + + gem "bundler", "~> 2.0" + gem "rack" + gem "railties" + gem "rake", ">= 12.3.3" + gem "rspec", "~> 3.0" end diff --git a/graphql-anycable.gemspec b/graphql-anycable.gemspec index aeb714d..df81606 100644 --- a/graphql-anycable.gemspec +++ b/graphql-anycable.gemspec @@ -26,16 +26,12 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] + spec.required_ruby_version = ">= 2.3.0" + spec.add_dependency "anycable", "~> 1.0" spec.add_dependency "anyway_config", ">= 1.3", "< 3" spec.add_dependency "graphql", ">= 1.11", "< 3" spec.add_dependency "redis", ">= 4.2.0" - spec.add_development_dependency "anycable-rails" - spec.add_development_dependency "bundler", "~> 2.0" - spec.add_development_dependency "rack" - spec.add_development_dependency "railties" - spec.add_development_dependency "rake", ">= 12.3.3" - spec.add_development_dependency "rspec", "~> 3.0" spec.metadata["rubygems_mfa_required"] = "true" end diff --git a/lib/graphql-anycable.rb b/lib/graphql-anycable.rb index 9055bcc..e6084d1 100644 --- a/lib/graphql-anycable.rb +++ b/lib/graphql-anycable.rb @@ -13,7 +13,8 @@ module AnyCable def self.use(schema, **options) if config.use_client_provided_uniq_id? warn "[Deprecated] Using client provided channel uniq IDs could lead to unexpected behaviour, " \ - "please, set GraphQL::AnyCable.config.use_client_provided_uniq_id = false or GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false, " \ + "please, set GraphQL::AnyCable.config.use_client_provided_uniq_id = false " \ + "or GRAPHQL_ANYCABLE_USE_CLIENT_PROVIDED_UNIQ_ID=false, " \ "and update the `#unsubscribed` callback code according to the latest docs." end diff --git a/lib/graphql/subscriptions/anycable_subscriptions.rb b/lib/graphql/subscriptions/anycable_subscriptions.rb index 59889c9..a28f0c9 100644 --- a/lib/graphql/subscriptions/anycable_subscriptions.rb +++ b/lib/graphql/subscriptions/anycable_subscriptions.rb @@ -4,7 +4,7 @@ require "graphql/subscriptions" require "graphql/anycable/errors" -# rubocop: disable Metrics/AbcSize, Metrics/LineLength, Metrics/MethodLength +# rubocop:disable Metrics/AbcSize, Metrics/LineLength, Metrics/MethodLength, Metrics/ClassLength # A subscriptions implementation that sends data as AnyCable broadcastings. # @@ -118,6 +118,7 @@ def deliver(stream_key, result) anycable.broadcast(stream_key, payload) end + # rubocop:disable Metrics/CyclomaticComplexity # Save query to "storage" (in redis) def write_subscription(query, events) context = query.context.to_h @@ -156,6 +157,7 @@ def write_subscription(query, events) pipeline.expire(SUBSCRIPTION_PREFIX + subscription_id, config.subscription_expiration_seconds) end end + # rubocop:enable Metrics/CyclomaticComplexity # Return the query from "storage" (in redis) def read_subscription(subscription_id) @@ -163,7 +165,7 @@ def read_subscription(subscription_id) "#{SUBSCRIPTION_PREFIX}#{subscription_id}", :query_string, :variables, :context, :operation_name, ).tap do |subscription| - return if subscription.values.all?(&:nil?) # Redis returns hash with all nils for missing key + break if subscription.values.all?(&:nil?) # Redis returns hash with all nils for missing key subscription[:context] = @serializer.load(subscription[:context]) subscription[:variables] = JSON.parse(subscription[:variables]) @@ -242,4 +244,4 @@ def fetch_channel_istate(channel) end end end -# rubocop: enable Metrics/AbcSize, Metrics/LineLength, Metrics/MethodLength +# rubocop:enable Metrics/AbcSize, Metrics/LineLength, Metrics/MethodLength, Metrics/ClassLength diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index 42ac485..4181526 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -35,7 +35,8 @@ end let(:fingerprint) do - ":productUpdated:/SomeSubscription/fBDZmJU1UGTorQWvOyUeaHVwUxJ3T9SEqnetj6SKGXc=/0/RBNvo1WzZ4oRRq0W9-hknpT7T8If536DEMBg9hyq_4o=" + ":productUpdated:/SomeSubscription/" \ + "fBDZmJU1UGTorQWvOyUeaHVwUxJ3T9SEqnetj6SKGXc=/0/RBNvo1WzZ4oRRq0W9-hknpT7T8If536DEMBg9hyq_4o=" end before do diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index 9722008..4bf3da3 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -46,6 +46,7 @@ def initialize(socket, identifiers: nil, subscriptions: nil) @subscriptions = subscriptions end + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def handle_channel_command(identifier, command, data) parsed_id = JSON.parse(identifier) @@ -74,6 +75,7 @@ def handle_channel_command(identifier, command, data) raise "Unknown command" end end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def transmit(data) socket.transmit data.to_json diff --git a/spec/integrations/rails_spec.rb b/spec/integrations/rails_spec.rb index 2a63782..3bc9163 100644 --- a/spec/integrations/rails_spec.rb +++ b/spec/integrations/rails_spec.rb @@ -34,6 +34,7 @@ def schema_class class GraphqlChannel < ActionCable::Channel::Base delegate :schema_class, to: :connection + # rubocop:disable Metrics/MethodLength def execute(data) result = schema_class.execute( @@ -50,6 +51,7 @@ def execute(data) }, ) end + # rubocop:enable Metrics/MethodLength def unsubscribed schema_class.subscriptions.delete_channel_subscriptions(self) From 569ad861a12bbe3bd90d6c0f967ea13c5a67f2c0 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 16:29:30 +0400 Subject: [PATCH 06/17] disable rubocop Gemspec/RequireMFA Co-authored-by: Andrey Novikov --- .rubocop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0322a9c..4940a04 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -65,7 +65,7 @@ Gemspec/DeprecatedAttributeAssignment: # new in 1.30 Gemspec/DevelopmentDependencies: # new in 1.44 Enabled: true Gemspec/RequireMFA: # new in 1.23 - Enabled: true + Enabled: false Layout/LineContinuationLeadingSpace: # new in 1.31 Enabled: true Layout/LineContinuationSpacing: # new in 1.31 From 6abc41d67b4fcf29c5061e770f8d76cbda971b70 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 16:30:51 +0400 Subject: [PATCH 07/17] remove rubygems_mfa_required --- graphql-anycable.gemspec | 2 -- 1 file changed, 2 deletions(-) diff --git a/graphql-anycable.gemspec b/graphql-anycable.gemspec index df81606..4a16e61 100644 --- a/graphql-anycable.gemspec +++ b/graphql-anycable.gemspec @@ -32,6 +32,4 @@ Gem::Specification.new do |spec| spec.add_dependency "anyway_config", ">= 1.3", "< 3" spec.add_dependency "graphql", ">= 1.11", "< 3" spec.add_dependency "redis", ">= 4.2.0" - - spec.metadata["rubygems_mfa_required"] = "true" end From 120f6aa59e94dbc6bbe8dc7860339834948912da Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Tue, 9 May 2023 16:43:21 +0400 Subject: [PATCH 08/17] remove support for ruby 2.3 --- .rubocop.yml | 2 +- graphql-anycable.gemspec | 2 +- lib/graphql/subscriptions/anycable_subscriptions.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4940a04..ae4bd67 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,7 +7,7 @@ require: - rubocop-rspec AllCops: - TargetRubyVersion: 2.3 + TargetRubyVersion: 2.7 Metrics/BlockLength: Exclude: diff --git a/graphql-anycable.gemspec b/graphql-anycable.gemspec index 4a16e61..d180e8e 100644 --- a/graphql-anycable.gemspec +++ b/graphql-anycable.gemspec @@ -26,7 +26,7 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.required_ruby_version = ">= 2.3.0" + spec.required_ruby_version = ">= 2.7.0" spec.add_dependency "anycable", "~> 1.0" spec.add_dependency "anyway_config", ">= 1.3", "< 3" diff --git a/lib/graphql/subscriptions/anycable_subscriptions.rb b/lib/graphql/subscriptions/anycable_subscriptions.rb index a28f0c9..b6844d5 100644 --- a/lib/graphql/subscriptions/anycable_subscriptions.rb +++ b/lib/graphql/subscriptions/anycable_subscriptions.rb @@ -86,7 +86,7 @@ def execute_all(event, object) end # Call to +trigger+ returns this. Convenient for playing in console - fingerprint_subscription_ids.map { |k, v| [k, v.size] }.to_h + fingerprint_subscription_ids.transform_values(&:size) end # The fingerprint has told us that this response should be shared by all subscribers, @@ -141,7 +141,7 @@ def write_subscription(query, events) variables: query.provided_variables.to_json, context: @serializer.dump(context.to_h), operation_name: query.operation_name, - events: events.map { |e| [e.topic, e.fingerprint] }.to_h.to_json, + events: events.to_h { |e| [e.topic, e.fingerprint] }.to_json, } redis.multi do |pipeline| From d4bdb4bbd97764e4bd2a2da526154f6b601fafd3 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 13:53:49 +0400 Subject: [PATCH 09/17] fix rubocop Naming/VariableNumber --- .rubocop_todo.yml | 10 ---------- .../broadcastable_subscriptions_spec.rb | 16 ++++++++-------- spec/integrations/rails_spec.rb | 18 +++++++++--------- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 748ce90..fa524bf 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -7,16 +7,6 @@ # versions of RuboCop, may require this file to be generated again. -# Offense count: 6 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 -Naming/VariableNumber: - Exclude: - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - 'spec/integrations/rails_spec.rb' - # Offense count: 2 RSpec/AnyInstance: Exclude: diff --git a/spec/integrations/broadcastable_subscriptions_spec.rb b/spec/integrations/broadcastable_subscriptions_spec.rb index fdeec4f..afc4bd6 100644 --- a/spec/integrations/broadcastable_subscriptions_spec.rb +++ b/spec/integrations/broadcastable_subscriptions_spec.rb @@ -112,13 +112,13 @@ expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - request_2 = request.dup + request2 = request.dup # update request context and channelId - request_2.connection_identifiers = identifiers.merge(current_user: "alice").to_json - request_2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json + request2.connection_identifiers = identifiers.merge(current_user: "alice").to_json + request2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json - response_2 = handler.handle(:command, request_2) + response2 = handler.handle(:command, request2) expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) @@ -141,11 +141,11 @@ schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice - second_state = response_2.istate + second_state = response2.istate - request_2.command = "unsubscribe" - request_2.data = "" - request_2.istate = second_state + request2.command = "unsubscribe" + request2.data = "" + request2.istate = second_state response = handler.handle(:command, request) expect(response).to be_success diff --git a/spec/integrations/rails_spec.rb b/spec/integrations/rails_spec.rb index 3bc9163..466b973 100644 --- a/spec/integrations/rails_spec.rb +++ b/spec/integrations/rails_spec.rb @@ -111,13 +111,13 @@ def context expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - request_2 = request.dup + request2 = request.dup # update request context and channelId - request_2.connection_identifiers = identifiers.merge(current_user: "alice").to_json - request_2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json + request2.connection_identifiers = identifiers.merge(current_user: "alice").to_json + request2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json - response_2 = handler.handle(:command, request_2) + response2 = handler.handle(:command, request2) expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) @@ -140,16 +140,16 @@ def context schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).twice - second_state = response_2.istate + second_state = response2.istate # Disconnect the second one via #disconnect call disconnect_request = AnyCable::DisconnectRequest.new( - identifiers: request_2.connection_identifiers, - subscriptions: [request_2.identifier], - env: request_2.env, + identifiers: request2.connection_identifiers, + subscriptions: [request2.identifier], + env: request2.env, ) - disconnect_request.istate[request_2.identifier] = second_state.to_h.to_json + disconnect_request.istate[request2.identifier] = second_state.to_h.to_json disconnect_response = handler.handle(:disconnect, disconnect_request) expect(disconnect_response).to be_success From 19d0758490f50fe4dced621ddb051045cf743d68 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 13:55:45 +0400 Subject: [PATCH 10/17] fix rubocop Naming/VariableNumber, second try --- .../per_client_subscriptions_spec.rb | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/integrations/per_client_subscriptions_spec.rb b/spec/integrations/per_client_subscriptions_spec.rb index 9343988..b2efed2 100644 --- a/spec/integrations/per_client_subscriptions_spec.rb +++ b/spec/integrations/per_client_subscriptions_spec.rb @@ -95,13 +95,13 @@ expect(redis.keys("graphql-subscription:*").size).to eq(1) expect(redis.keys("graphql-subscriptions:*").size).to eq(1) - request_2 = request.dup + request2 = request.dup # update request context and channelId - request_2.connection_identifiers = identifiers.merge(current_user: "alice").to_json - request_2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json + request2.connection_identifiers = identifiers.merge(current_user: "alice").to_json + request2.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json - response_2 = handler.handle(:command, request_2) + response2 = handler.handle(:command, request2) expect(redis.keys("graphql-subscription:*").size).to eq(2) expect(redis.keys("graphql-subscriptions:*").size).to eq(2) @@ -124,11 +124,11 @@ schema.subscriptions.trigger(:post_updated, { id: "a" }, POSTS.first) expect(AnyCable.broadcast_adapter).to have_received(:broadcast).thrice - second_state = response_2.istate + second_state = response2.istate - request_2.command = "unsubscribe" - request_2.data = "" - request_2.istate = second_state + request2.command = "unsubscribe" + request2.data = "" + request2.istate = second_state response = handler.handle(:command, request) expect(response).to be_success From 7aa49dbecbaea98aa63b469983ec7bec0e794938 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 14:06:08 +0400 Subject: [PATCH 11/17] fix rubocop RSpec/ContextWording --- .rubocop_todo.yml | 8 -------- spec/graphql/anycable_spec.rb | 4 ++-- spec/integration_helper.rb | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fa524bf..2e5b2e2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -12,14 +12,6 @@ RSpec/AnyInstance: Exclude: - 'spec/graphql/anycable_spec.rb' -# Offense count: 3 -# Configuration parameters: Prefixes, AllowedPatterns. -# Prefixes: when, with, without -RSpec/ContextWording: - Exclude: - - 'spec/graphql/anycable_spec.rb' - - 'spec/integration_helper.rb' - # Offense count: 3 # Configuration parameters: IgnoredMetadata. RSpec/DescribeClass: diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index 4181526..4f0f1b2 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -66,7 +66,7 @@ GRAPHQL end - context "triggering update event" do + context "with triggering update event" do it "broadcasts message only for update event" do subject AnycableSchema.subscriptions.trigger(:product_updated, {}, { id: 1, title: "foo" }) @@ -74,7 +74,7 @@ end end - context "triggering create event" do + context "with triggering create event" do let(:expected_result) do <<~JSON.strip {"result":{"data":{"productCreated":{"id":"1","title":"Gravizapa"}}},"more":true} diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index 4bf3da3..e93d0a5 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -3,7 +3,7 @@ require "anycable/rspec" require "rack" -RSpec.shared_context "rpc" do +RSpec.shared_context "with rpc" do include_context "anycable:rpc:command" let(:user) { "john" } @@ -102,5 +102,5 @@ def close metadata[:integration] = true end - config.include_context "rpc", integration: true + config.include_context "with rpc", integration: true end From 8f7edaef172b1f9d72ece8d885eac293acb23d5c Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 17:47:13 +0400 Subject: [PATCH 12/17] fix rubocop RSpec/DescribeClass --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 13 ------------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index ae4bd67..05b4f0f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,10 @@ require: AllCops: TargetRubyVersion: 2.7 +RSpec/DescribeClass: + Exclude: + - 'spec/integrations/**' + Metrics/BlockLength: Exclude: - "Gemfile" diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2e5b2e2..130948a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -12,19 +12,6 @@ RSpec/AnyInstance: Exclude: - 'spec/graphql/anycable_spec.rb' -# Offense count: 3 -# Configuration parameters: IgnoredMetadata. -RSpec/DescribeClass: - Exclude: - - '**/spec/features/**/*' - - '**/spec/requests/**/*' - - '**/spec/routing/**/*' - - '**/spec/system/**/*' - - '**/spec/views/**/*' - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - 'spec/integrations/rails_spec.rb' - # Offense count: 13 # Configuration parameters: CountAsOne. RSpec/ExampleLength: From e44bc37b7c674b72175cf543ebd3b356a495881b Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 18:33:14 +0400 Subject: [PATCH 13/17] fix rubocop RSpec/VerifiedDoubles --- .rubocop_todo.yml | 6 ------ spec/graphql/anycable_spec.rb | 12 +++++++++--- spec/graphql/broadcast_spec.rb | 8 ++++---- spec/integration_helper.rb | 4 ++++ 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 130948a..5ebab8a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -31,12 +31,6 @@ RSpec/NamedSubject: - 'spec/integrations/broadcastable_subscriptions_spec.rb' - 'spec/integrations/per_client_subscriptions_spec.rb' -# Offense count: 7 -# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. -RSpec/VerifiedDoubles: - Exclude: - - 'spec/graphql/anycable_spec.rb' - - 'spec/graphql/broadcast_spec.rb' # Offense count: 5 # Configuration parameters: AllowedConstants. diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index 4f0f1b2..5cd0fdd 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -23,9 +23,15 @@ end let(:channel) do - socket = double("Socket", istate: AnyCable::Socket::State.new({})) - connection = double("Connection", anycable_socket: socket) - double("Channel", id: "legacy_id", params: { "channelId" => "legacy_id" }, stream_from: nil, connection: connection) + socket = instance_double(AnyCable::Socket, istate: AnyCable::Socket::State.new({})) + connection = instance_double(FakeConnection, anycable_socket: socket) + instance_double( + FakeConnection::Channel, + id: "legacy_id", + params: { "channelId" => "legacy_id" }, + stream_from: nil, + connection: connection, + ) end let(:anycable) { AnyCable.broadcast_adapter } diff --git a/spec/graphql/broadcast_spec.rb b/spec/graphql/broadcast_spec.rb index fe5d485..ede37c2 100644 --- a/spec/graphql/broadcast_spec.rb +++ b/spec/graphql/broadcast_spec.rb @@ -11,13 +11,13 @@ def subscribe(query) end let(:channel) do - socket = double("Socket", istate: AnyCable::Socket::State.new({})) - connection = double("Connection", anycable_socket: socket) - double("Channel", connection: connection) + socket = instance_double(AnyCable::Socket, istate: AnyCable::Socket::State.new({})) + connection = instance_double(FakeConnection, anycable_socket: socket) + instance_double(FakeConnection::Channel, connection: connection) end let(:object) do - double("Post", id: 1, title: "Broadcasting…", actions: %w[Edit Delete]) + double(Post, id: 1, title: "Broadcasting…", actions: %w[Edit Delete]) # rubocop:disable RSpec/VerifiedDoubles end let(:query) do diff --git a/spec/integration_helper.rb b/spec/integration_helper.rb index e93d0a5..e340539 100644 --- a/spec/integration_helper.rb +++ b/spec/integration_helper.rb @@ -28,6 +28,10 @@ def initialize(connection, identifier, params) @params = params end + def id + @params["channelId"] + end + def stream_from(broadcasting) connection.socket.subscribe identifier, broadcasting end From 10c5a2ef97230f26951b0ab77147eb8de394baea Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 19:19:34 +0400 Subject: [PATCH 14/17] fix rubocop RSpec/NamedSubject --- .rubocop_todo.yml | 10 --------- spec/graphql/anycable_spec.rb | 22 +++++++++---------- .../broadcastable_subscriptions_spec.rb | 20 ++++++++--------- .../per_client_subscriptions_spec.rb | 20 ++++++++--------- spec/integrations/rails_spec.rb | 2 -- 5 files changed, 31 insertions(+), 43 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 5ebab8a..4c6b85d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -22,16 +22,6 @@ RSpec/ExampleLength: RSpec/MultipleMemoizedHelpers: Max: 8 -# Offense count: 25 -# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. -# SupportedStyles: always, named_only -RSpec/NamedSubject: - Exclude: - - 'spec/graphql/anycable_spec.rb' - - 'spec/integrations/broadcastable_subscriptions_spec.rb' - - 'spec/integrations/per_client_subscriptions_spec.rb' - - # Offense count: 5 # Configuration parameters: AllowedConstants. Style/Documentation: diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index 5cd0fdd..f498f2d 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe GraphQL::AnyCable do - subject do + subject(:execute_query) do AnycableSchema.execute( query: query, context: { channel: channel, subscription_id: subscription_id }, @@ -52,12 +52,12 @@ end it "subscribes channel to stream updates from GraphQL subscription" do - subject + execute_query expect(channel).to have_received(:stream_from).with("graphql-subscriptions:#{fingerprint}") end it "broadcasts message when event is being triggered" do - subject + execute_query AnycableSchema.subscriptions.trigger(:product_updated, {}, { id: 1, title: "foo" }) expect(anycable).to have_received(:broadcast).with("graphql-subscriptions:#{fingerprint}", expected_result) end @@ -74,7 +74,7 @@ context "with triggering update event" do it "broadcasts message only for update event" do - subject + execute_query AnycableSchema.subscriptions.trigger(:product_updated, {}, { id: 1, title: "foo" }) expect(anycable).to have_received(:broadcast).with("graphql-subscriptions:#{fingerprint}", expected_result) end @@ -88,7 +88,7 @@ end it "broadcasts message only for create event" do - subject + execute_query AnycableSchema.subscriptions.trigger(:product_created, {}, { id: 1, title: "Gravizapa" }) expect(anycable).to have_received(:broadcast).with("graphql-subscriptions:#{fingerprint}", expected_result) @@ -97,7 +97,7 @@ end describe ".delete_channel_subscriptions" do - subject do + subject(:delete_subscriptions) do AnycableSchema.subscriptions.delete_channel_subscriptions(channel) end @@ -121,7 +121,7 @@ expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be true expect(redis.exists?("graphql-channel:some-truly-random-number")).to be true expect(redis.exists?("graphql-fingerprints::productUpdated:")).to be true - subject + delete_subscriptions expect(redis.exists?("graphql-channel:some-truly-random-number")).to be false expect(redis.exists?("graphql-fingerprints::productUpdated:")).to be false expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be false @@ -129,7 +129,7 @@ end describe "legacy .delete_channel_subscriptions" do - subject do + subject(:delete_subscriptions) do AnycableSchema.subscriptions.delete_channel_subscriptions(channel.id) end @@ -153,7 +153,7 @@ expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be true expect(redis.exists?("graphql-channel:legacy_id")).to be true expect(redis.exists?("graphql-fingerprints::productUpdated:")).to be true - subject + delete_subscriptions expect(redis.exists?("graphql-channel:legacy_id")).to be false expect(redis.exists?("graphql-fingerprints::productUpdated:")).to be false expect(redis.exists?("graphql-subscription:some-truly-random-number")).to be false @@ -161,7 +161,7 @@ end describe "with missing channel instance in execution context" do - subject do + subject(:execute_query) do AnycableSchema.execute( query: query, context: {}, # Intentionally left blank @@ -177,7 +177,7 @@ end it "raises configuration error" do - expect { subject }.to raise_error( + expect { execute_query }.to raise_error( GraphQL::AnyCable::ChannelConfigurationError, /ActionCable channel wasn't provided in the context for GraphQL query execution!/, ) diff --git a/spec/integrations/broadcastable_subscriptions_spec.rb b/spec/integrations/broadcastable_subscriptions_spec.rb index afc4bd6..5c49633 100644 --- a/spec/integrations/broadcastable_subscriptions_spec.rb +++ b/spec/integrations/broadcastable_subscriptions_spec.rb @@ -3,7 +3,7 @@ require "integration_helper" RSpec.describe "broadcastable subscriptions" do - subject { handler.handle(:command, request) } + subject(:execute_request) { handler.handle(:command, request) } let(:schema) { BroadcastSchema } @@ -29,18 +29,18 @@ describe "execute" do it "responds with result" do - expect(subject).to be_success - expect(subject.transmissions.size).to eq 1 - expect(subject.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) - expect(subject.streams.size).to eq 1 - expect(subject.istate["sid"]).not_to be_nil + expect(execute_request).to be_success + expect(execute_request.transmissions.size).to eq 1 + expect(execute_request.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) + expect(execute_request.streams.size).to eq 1 + expect(execute_request.istate["sid"]).not_to be_nil end specify "streams depends only on query params and the same for equal subscriptions" do - expect(subject).to be_success - expect(subject.streams.size).to eq 1 + expect(execute_request).to be_success + expect(execute_request.streams.size).to eq 1 - stream_name = subject.streams.first + stream_name = execute_request.streams.first # update request context and channelId request.connection_identifiers = identifiers.merge(current_user: "alice").to_json @@ -203,7 +203,7 @@ let(:command) { "unsubscribe" } specify do - expect(subject).to be_success + expect(execute_request).to be_success end end end diff --git a/spec/integrations/per_client_subscriptions_spec.rb b/spec/integrations/per_client_subscriptions_spec.rb index b2efed2..57397a3 100644 --- a/spec/integrations/per_client_subscriptions_spec.rb +++ b/spec/integrations/per_client_subscriptions_spec.rb @@ -3,7 +3,7 @@ require "integration_helper" RSpec.describe "non-broadcastable subscriptions" do - subject { handler.handle(:command, request) } + subject(:execute_request) { handler.handle(:command, request) } let(:schema) { AnycableSchema } @@ -29,18 +29,18 @@ describe "execute" do it "responds with result" do - expect(subject).to be_success - expect(subject.transmissions.size).to eq 1 - expect(subject.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) - expect(subject.streams.size).to eq 1 - expect(subject.istate["sid"]).not_to be_nil + expect(execute_request).to be_success + expect(execute_request.transmissions.size).to eq 1 + expect(execute_request.transmissions.first).to eq({ result: { data: nil }, more: true }.to_json) + expect(execute_request.streams.size).to eq 1 + expect(execute_request.istate["sid"]).not_to be_nil end specify "creates uniq stream for each subscription" do - expect(subject).to be_success - expect(subject.streams.size).to eq 1 + expect(execute_request).to be_success + expect(execute_request.streams.size).to eq 1 - all_streams = Set.new(subject.streams) + all_streams = Set.new(execute_request.streams) # update request channelId request.identifier = channel_identifier.merge(channelId: rand(1000).to_s).to_json @@ -186,7 +186,7 @@ let(:command) { "unsubscribe" } specify do - expect(subject).to be_success + expect(execute_request).to be_success end end end diff --git a/spec/integrations/rails_spec.rb b/spec/integrations/rails_spec.rb index 466b973..4fe8a95 100644 --- a/spec/integrations/rails_spec.rb +++ b/spec/integrations/rails_spec.rb @@ -69,8 +69,6 @@ def context end RSpec.describe "Rails integration" do - subject { handler.handle(:command, request) } - let(:schema) { BroadcastSchema } let(:variables) { { id: "a" } } let(:subscription_payload) { { query: query, variables: variables } } From 1517e9a90d96247b399341b4868d73afa4645c20 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 19:22:46 +0400 Subject: [PATCH 15/17] fix rubocop RSpec/MultipleMemoizedHelpers --- .rubocop.yml | 3 +++ .rubocop_todo.yml | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 05b4f0f..4bf39ca 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,6 +9,9 @@ require: AllCops: TargetRubyVersion: 2.7 +RSpec/MultipleMemoizedHelpers: + Max: 8 + RSpec/DescribeClass: Exclude: - 'spec/integrations/**' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4c6b85d..cf2ec23 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -17,11 +17,6 @@ RSpec/AnyInstance: RSpec/ExampleLength: Max: 35 -# Offense count: 20 -# Configuration parameters: AllowSubject. -RSpec/MultipleMemoizedHelpers: - Max: 8 - # Offense count: 5 # Configuration parameters: AllowedConstants. Style/Documentation: From 036170aaba5ae0e7ce09e69e94284fd5af34301c Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 19:43:29 +0400 Subject: [PATCH 16/17] fix rubocop Style/Documentation RSpec/ExampleLength --- .rubocop.yml | 6 ++++++ .rubocop_todo.yml | 16 ---------------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4bf39ca..37ef7a8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -9,9 +9,15 @@ require: AllCops: TargetRubyVersion: 2.7 +Style/Documentation: + Enabled: false + RSpec/MultipleMemoizedHelpers: Max: 8 +RSpec/ExampleLength: + Max: 35 + RSpec/DescribeClass: Exclude: - 'spec/integrations/**' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index cf2ec23..24c6ae4 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -12,19 +12,3 @@ RSpec/AnyInstance: Exclude: - 'spec/graphql/anycable_spec.rb' -# Offense count: 13 -# Configuration parameters: CountAsOne. -RSpec/ExampleLength: - Max: 35 - -# Offense count: 5 -# Configuration parameters: AllowedConstants. -Style/Documentation: - Exclude: - - 'spec/**/*' - - 'test/**/*' - - 'lib/graphql-anycable.rb' - - 'lib/graphql/anycable/cleaner.rb' - - 'lib/graphql/anycable/config.rb' - - 'lib/graphql/anycable/railtie.rb' - - 'lib/graphql/subscriptions/anycable_subscriptions.rb' From 58058b6cc16ddea9ac4142d2a10ac4ca0e54d056 Mon Sep 17 00:00:00 2001 From: Vitalii Yulieff Date: Mon, 15 May 2023 19:53:02 +0400 Subject: [PATCH 17/17] fix rubocop RSpec/AnyInstance + small fixes --- .rubocop.yml | 11 +++-------- .rubocop_todo.yml | 14 -------------- spec/graphql/anycable_spec.rb | 4 ++-- 3 files changed, 5 insertions(+), 24 deletions(-) delete mode 100644 .rubocop_todo.yml diff --git a/.rubocop.yml b/.rubocop.yml index 37ef7a8..f5275e9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,8 +1,3 @@ ---- -inherit_from: .rubocop_todo.yml - - - require: - rubocop-rspec @@ -289,11 +284,11 @@ RSpec/SubjectDeclaration: # new in 2.5 Enabled: true RSpec/VerifiedDoubleReference: # new in 2.10.0 Enabled: true -RSpec/FactoryBot/ConsistentParenthesesStyle: # new in 2.14 +FactoryBot/ConsistentParenthesesStyle: # new in 2.14 Enabled: true -RSpec/FactoryBot/FactoryNameStyle: # new in 2.16 +FactoryBot/FactoryNameStyle: # new in 2.16 Enabled: true -RSpec/FactoryBot/SyntaxMethods: # new in 2.7 +FactoryBot/SyntaxMethods: # new in 2.7 Enabled: true RSpec/Rails/AvoidSetupHook: # new in 2.4 Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index 24c6ae4..0000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,14 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config` -# on 2023-05-09 11:37:51 UTC using RuboCop version 1.50.2. -# 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: 2 -RSpec/AnyInstance: - Exclude: - - 'spec/graphql/anycable_spec.rb' - diff --git a/spec/graphql/anycable_spec.rb b/spec/graphql/anycable_spec.rb index f498f2d..ecda276 100644 --- a/spec/graphql/anycable_spec.rb +++ b/spec/graphql/anycable_spec.rb @@ -47,8 +47,8 @@ before do allow(anycable).to receive(:broadcast) - allow_any_instance_of(GraphQL::Subscriptions::Event).to receive(:fingerprint).and_return(fingerprint) - allow_any_instance_of(GraphQL::Subscriptions).to receive(:build_id).and_return("ohmycables") + allow_any_instance_of(GraphQL::Subscriptions::Event).to receive(:fingerprint).and_return(fingerprint) # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(GraphQL::Subscriptions).to receive(:build_id).and_return("ohmycables") # rubocop:disable RSpec/AnyInstance end it "subscribes channel to stream updates from GraphQL subscription" do