From 54b397f3a5010b67e0a7adb682be7f4c02849594 Mon Sep 17 00:00:00 2001 From: Alex Pop Date: Wed, 11 May 2016 11:58:58 +0100 Subject: [PATCH] fix contain_match, add none_match update matchers doc and add more integration tests allow non-string data types and non-arrays --- docs/matchers.rst | 64 +++++++++++++++++++++++++++++ lib/matchers/matchers.rb | 18 ++++---- test/integration/default/matcher.rb | 48 ++++++++++++++++++++-- 3 files changed, 120 insertions(+), 10 deletions(-) diff --git a/docs/matchers.rst b/docs/matchers.rst index 5be8ffdd9..7a0e2d1a9 100644 --- a/docs/matchers.rst +++ b/docs/matchers.rst @@ -10,6 +10,7 @@ Inspec uses matchers to help compare resource values to expectations. The follow * `eq` * `include` * `match` +* Array matchers: `contain_match`, `all_match`, `none_match`, `contain_duplicates` be @@ -135,3 +136,66 @@ Check if a string matches a regular expression. describe sshd_config do its('Ciphers') { should_not match /cbc/ } end + + +Array Matchers +===================================================== + +The following matchers are designed to work with arrays: + + +contain_match +----------------------------------------------------- + +Check if an array contains at least one item that matches the regex: + +.. code-block:: ruby + + describe ['lemon', 'ginger', 'grapes'] do + it { should contain_match /^gin/} + end + describe port(25) do + its('addresses') it { should_not contain_match /0\.0\.0\.0/} + end + + +all_match +----------------------------------------------------- + +Check if all items of an array match the regex: + +.. code-block:: ruby + + describe ['grapefruit', 'grapes'] do + it { should all_match /^grape.+/} + end + + +none_match +----------------------------------------------------- + +Check if all items of an array match the regex: + +.. code-block:: ruby + + describe ['ginger', 'grapefruit'] do + it { should none_match /^sugar$/} + end + describe port(25) do + its('addresses') it { should none_match /^0\.0\.0\.0$/ } + end + + +contain_duplicates +----------------------------------------------------- + +Check if an array contains duplicate items: + +.. code-block:: ruby + + describe [80, 443, 80] do + it { should contain_duplicates } + end + describe ['ginger', 'grapefruit'] do + it { should_not contain_duplicates } + end diff --git a/lib/matchers/matchers.rb b/lib/matchers/matchers.rb index bfa6eccbb..f5ffa0d49 100644 --- a/lib/matchers/matchers.rb +++ b/lib/matchers/matchers.rb @@ -74,26 +74,30 @@ RSpec::Matchers.define :contain_legacy_plus do end end -# matcher to check that all entries match the regex +# verifies that all entries match the regex RSpec::Matchers.define :all_match do |regex| match do |arr| - arr.all? { |element| element.match(regex) } + Array(arr).all? { |element| element.to_s.match(regex) } + end +end + +# verifies that all entries don't match a regex +RSpec::Matchers.define :none_match do |regex| + match do |arr| + Array(arr).all? { |element| !element.to_s.match(regex) } end end # verifies that no entry in an array contains a value RSpec::Matchers.define :contain_match do |regex| match do |arr| - arr.inject { |result, i| - result = i.match(regex) - result || i.match(/$/) - } + Array(arr).one? { |element| element.to_s.match(regex) } end end RSpec::Matchers.define :contain_duplicates do match do |arr| - dup = arr.select { |element| arr.count(element) > 1 } + dup = Array(arr).select { |element| arr.count(element) > 1 } !dup.uniq.empty? end end diff --git a/test/integration/default/matcher.rb b/test/integration/default/matcher.rb index 23cd558ca..bb0197543 100644 --- a/test/integration/default/matcher.rb +++ b/test/integration/default/matcher.rb @@ -1,9 +1,51 @@ # encoding: utf-8 +# 'all_match' matcher tests describe ['ananas', 'apples', 'oranges', 'air', 'alot'] do - it { should all_match /[a]./} + it { should all_match /[a]./} +end +describe ['ananas', 'apples', 'oranges', 'melons', 'air'] do + it { should_not all_match /[a]./} +end +describe [true, true, true] do + it { should all_match /^true$/} end -describe ['ananas', 'apples', 'oranges', 'air', 'melons'] do - it { should_not all_match /[a]./} + +# 'none_match' matcher tests +describe ['kiwi', 'avocado', 'grapefruit'] do + it { should none_match /xyz/} +end +describe ['kiwi', 'avocado', 'grapefruit'] do + it { should_not none_match /^avo/} +end +describe 999 do + it { should none_match /^666/} +end + + +# 'contain_match' matcher tests +describe ['lemon', 'ginger', 'grapes'] do + it { should contain_match /^gin/} +end +describe ['lemon', 'ginger', 'gra(pes'] do + it { should contain_match 'gra\(pe' } +end +describe ['lemon', 'ginger', 'grapes'] do + it { should_not contain_match /^chocolate/} +end +describe 'kiwi' do + it { should contain_match /^kiw/} +end + + +# 'contain_duplicates' matcher tests +describe ['onion', 'carrot', 'onion'] do + it { should contain_duplicates } +end +describe ['onion', 'carrot', 'brocoli'] do + it { should_not contain_duplicates } +end +describe [80, 443] do + it { should_not contain_duplicates } end