summaryrefslogtreecommitdiff
path: root/spec/support/matchers
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2018-06-27 16:15:06 +0800
committerLin Jen-Shin <godfat@godfat.org>2018-06-27 16:15:06 +0800
commit849f9995d97c85d88b36a40ee563f7dd51fdc3f1 (patch)
tree3523089d253b001f7e3b029266399e497407441b /spec/support/matchers
parentef6b3e0271d226462bed5f899f3964cf5652978c (diff)
parent87f7597a4fb7852fc81f830158cdfd5fdec8fac4 (diff)
downloadgitlab-ce-849f9995d97c85d88b36a40ee563f7dd51fdc3f1.tar.gz
Merge remote-tracking branch 'upstream/master' into 14995-custom_wiki_sidebar
* upstream/master: (4180 commits) Enable frozen string literals for app/workers/*.rb Resolve "Search dropdown hides & shows when typing" Revert merge request widget button max height Update CHANGELOG.md for 11.0.2 Update external link icon in header user dropdown Added Diff Viewer to new VUE based MR page Fixed eslint failure in IDE spec helpers Use refs instead of querySelector. Show file in tree on WebIDE open Resolve "Remove unused bootstrap component CSS" Resolve "Explain what Groups are in the New Group page" [QA] Make sure we wait for the deploy key list to load Update _scopes_form.html.haml to remove duplicate information Use the branch instead of the tag to install port the EE changes Add index on deployable_type/id for deployments Add a helper to rename a column using a background migration Fix performance bottleneck when rendering large wiki pages Port Namespace#root_ancestor to CE Remove duplicate spec ...
Diffstat (limited to 'spec/support/matchers')
-rw-r--r--spec/support/matchers/background_migrations_matchers.rb26
-rw-r--r--spec/support/matchers/email_matchers.rb5
-rw-r--r--spec/support/matchers/exceed_query_limit.rb99
-rw-r--r--spec/support/matchers/graphql_matchers.rb46
-rw-r--r--spec/support/matchers/have_emoji.rb5
-rw-r--r--spec/support/matchers/issuable_matchers.rb11
-rw-r--r--spec/support/matchers/match_ids.rb7
7 files changed, 194 insertions, 5 deletions
diff --git a/spec/support/matchers/background_migrations_matchers.rb b/spec/support/matchers/background_migrations_matchers.rb
new file mode 100644
index 00000000000..f4127efc6ae
--- /dev/null
+++ b/spec/support/matchers/background_migrations_matchers.rb
@@ -0,0 +1,26 @@
+RSpec::Matchers.define :be_scheduled_delayed_migration do |delay, *expected|
+ match do |migration|
+ BackgroundMigrationWorker.jobs.any? do |job|
+ job['args'] == [migration, expected] &&
+ job['at'].to_i == (delay.to_i + Time.now.to_i)
+ end
+ end
+
+ failure_message do |migration|
+ "Migration `#{migration}` with args `#{expected.inspect}` " \
+ 'not scheduled in expected time!'
+ end
+end
+
+RSpec::Matchers.define :be_scheduled_migration do |*expected|
+ match do |migration|
+ BackgroundMigrationWorker.jobs.any? do |job|
+ args = job['args'].size == 1 ? [BackgroundMigrationWorker.jobs[0]['args'][0], []] : job['args']
+ args == [migration, expected]
+ end
+ end
+
+ failure_message do |migration|
+ "Migration `#{migration}` with args `#{expected.inspect}` not scheduled!"
+ end
+end
diff --git a/spec/support/matchers/email_matchers.rb b/spec/support/matchers/email_matchers.rb
deleted file mode 100644
index d9d59ec12ec..00000000000
--- a/spec/support/matchers/email_matchers.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-RSpec::Matchers.define :have_html_escaped_body_text do |expected|
- match do |actual|
- expect(actual).to have_body_text(ERB::Util.html_escape(expected))
- end
-end
diff --git a/spec/support/matchers/exceed_query_limit.rb b/spec/support/matchers/exceed_query_limit.rb
new file mode 100644
index 00000000000..cd042401f3a
--- /dev/null
+++ b/spec/support/matchers/exceed_query_limit.rb
@@ -0,0 +1,99 @@
+module ExceedQueryLimitHelpers
+ def with_threshold(threshold)
+ @threshold = threshold
+ self
+ end
+
+ def for_query(query)
+ @query = query
+ self
+ end
+
+ def threshold
+ @threshold.to_i
+ end
+
+ def expected_count
+ if expected.is_a?(ActiveRecord::QueryRecorder)
+ expected.count
+ else
+ expected
+ end
+ end
+
+ def actual_count
+ @actual_count ||= if @query
+ recorder.log.select { |recorded| recorded =~ @query }.size
+ else
+ recorder.count
+ end
+ end
+
+ def recorder
+ @recorder ||= ActiveRecord::QueryRecorder.new(skip_cached: skip_cached, &@subject_block)
+ end
+
+ def count_queries(queries)
+ queries.each_with_object(Hash.new(0)) { |query, counts| counts[query] += 1 }
+ end
+
+ def log_message
+ if expected.is_a?(ActiveRecord::QueryRecorder)
+ counts = count_queries(expected.log)
+ extra_queries = @recorder.log.reject { |query| counts[query] -= 1 unless counts[query].zero? }
+ extra_queries_display = count_queries(extra_queries).map { |query, count| "[#{count}] #{query}" }
+
+ (['Extra queries:'] + extra_queries_display).join("\n\n")
+ else
+ @recorder.log_message
+ end
+ end
+
+ def skip_cached
+ true
+ end
+
+ def verify_count(&block)
+ @subject_block = block
+ actual_count > expected_count + threshold
+ end
+
+ def failure_message
+ threshold_message = threshold > 0 ? " (+#{@threshold})" : ''
+ counts = "#{expected_count}#{threshold_message}"
+ "Expected a maximum of #{counts} queries, got #{actual_count}:\n\n#{log_message}"
+ end
+end
+
+RSpec::Matchers.define :exceed_all_query_limit do |expected|
+ supports_block_expectations
+
+ include ExceedQueryLimitHelpers
+
+ match do |block|
+ verify_count(&block)
+ end
+
+ failure_message_when_negated do |actual|
+ failure_message
+ end
+
+ def skip_cached
+ false
+ end
+end
+
+# Excludes cached methods from the query count
+RSpec::Matchers.define :exceed_query_limit do |expected|
+ supports_block_expectations
+
+ include ExceedQueryLimitHelpers
+
+ match do |block|
+ verify_count(&block)
+ end
+
+ failure_message_when_negated do |actual|
+ failure_message
+ end
+end
diff --git a/spec/support/matchers/graphql_matchers.rb b/spec/support/matchers/graphql_matchers.rb
new file mode 100644
index 00000000000..d23cbaf4beb
--- /dev/null
+++ b/spec/support/matchers/graphql_matchers.rb
@@ -0,0 +1,46 @@
+RSpec::Matchers.define :require_graphql_authorizations do |*expected|
+ match do |field|
+ field_definition = field.metadata[:type_class]
+ expect(field_definition).to respond_to(:required_permissions)
+ expect(field_definition.required_permissions).to contain_exactly(*expected)
+ end
+end
+
+RSpec::Matchers.define :have_graphql_fields do |*expected|
+ match do |kls|
+ field_names = expected.map { |name| GraphqlHelpers.fieldnamerize(name) }
+ expect(kls.fields.keys).to contain_exactly(*field_names)
+ end
+end
+
+RSpec::Matchers.define :have_graphql_field do |field_name|
+ match do |kls|
+ expect(kls.fields.keys).to include(GraphqlHelpers.fieldnamerize(field_name))
+ end
+end
+
+RSpec::Matchers.define :have_graphql_arguments do |*expected|
+ include GraphqlHelpers
+
+ match do |field|
+ argument_names = expected.map { |name| GraphqlHelpers.fieldnamerize(name) }
+ expect(field.arguments.keys).to contain_exactly(*argument_names)
+ end
+end
+
+RSpec::Matchers.define :have_graphql_type do |expected|
+ match do |field|
+ expect(field.type).to eq(expected.to_graphql)
+ end
+end
+
+RSpec::Matchers.define :have_graphql_resolver do |expected|
+ match do |field|
+ case expected
+ when Method
+ expect(field.metadata[:type_class].resolve_proc).to eq(expected)
+ else
+ expect(field.metadata[:type_class].resolver).to eq(expected)
+ end
+ end
+end
diff --git a/spec/support/matchers/have_emoji.rb b/spec/support/matchers/have_emoji.rb
new file mode 100644
index 00000000000..23fb8e9c1c4
--- /dev/null
+++ b/spec/support/matchers/have_emoji.rb
@@ -0,0 +1,5 @@
+RSpec::Matchers.define :have_emoji do |emoji_name|
+ match do |actual|
+ expect(actual).to have_selector("gl-emoji[data-name='#{emoji_name}']")
+ end
+end
diff --git a/spec/support/matchers/issuable_matchers.rb b/spec/support/matchers/issuable_matchers.rb
new file mode 100644
index 00000000000..f5d9a97051a
--- /dev/null
+++ b/spec/support/matchers/issuable_matchers.rb
@@ -0,0 +1,11 @@
+RSpec::Matchers.define :have_header_with_correct_id_and_link do |level, text, id, parent = ".wiki"|
+ match do |actual|
+ node = find("#{parent} h#{level} a#user-content-#{id}")
+
+ expect(node[:href]).to end_with("##{id}")
+
+ # Work around a weird Capybara behavior where calling `parent` on a node
+ # returns the whole document, not the node's actual parent element
+ expect(find(:xpath, "#{node.path}/..").text).to eq(text)
+ end
+end
diff --git a/spec/support/matchers/match_ids.rb b/spec/support/matchers/match_ids.rb
index d8424405b96..1cb6b74acac 100644
--- a/spec/support/matchers/match_ids.rb
+++ b/spec/support/matchers/match_ids.rb
@@ -10,6 +10,13 @@ RSpec::Matchers.define :match_ids do |*expected|
'matches elements by ids'
end
+ failure_message do
+ actual_ids = map_ids(actual)
+ expected_ids = map_ids(expected)
+
+ "expected IDs #{actual_ids} in:\n\n #{actual.inspect}\n\nto match IDs #{expected_ids} in:\n\n #{expected.inspect}"
+ end
+
def map_ids(elements)
elements = elements.flatten if elements.respond_to?(:flatten)