diff --git a/auto/generate_test_runner.rb b/auto/generate_test_runner.rb index 9401ad88..e35b69a3 100644 --- a/auto/generate_test_runner.rb +++ b/auto/generate_test_runner.rb @@ -129,8 +129,10 @@ def find_tests(source) .map { |line| line.gsub(substring_unre, substring_unsubs) } # unhide the problematic characters previously removed lines.each_with_index do |line, _index| + tests_regex_string = /\s*(?:TEST_CASE|TEST_RANGE|TEST_MATRIX)\s*\(.*?\)\s*/.source + # find tests - next unless line =~ /^((?:\s*(?:TEST_CASE|TEST_RANGE)\s*\(.*?\)\s*)*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/m + next unless line =~ /^((?:#{tests_regex_string})*)\s*void\s+((?:#{@options[:test_prefix]}).*)\s*\(\s*(.*)\s*\)/m arguments = Regexp.last_match(1) name = Regexp.last_match(2) @@ -140,10 +142,10 @@ def find_tests(source) if @options[:use_param_tests] && !arguments.empty? args = [] - arguments.scan(/\s*TEST_CASE\s*\((.*)\)\s*$/) { |a| args << a[0] } + arguments.scan(/\s*TEST_CASE\s*\(((?:(?!#{tests_regex_string}).)*)\)\s*$/m) { |a| args << a[0] } - arguments.scan(/\s*TEST_RANGE\s*\((.*)\)\s*$/).flatten.each do |range_str| - args += range_str.scan(/\[\s*(-?\d+.?\d*),\s*(-?\d+.?\d*),\s*(-?\d+.?\d*)\s*\]/).map do |arg_values_str| + arguments.scan(/\s*TEST_RANGE\s*\(((?:(?!#{tests_regex_string}).)*)\)\s*$/m).flatten.each do |range_str| + args += range_str.scan(/\[\s*(-?\d+.?\d*),\s*(-?\d+.?\d*),\s*(-?\d+.?\d*)\s*\]/m).map do |arg_values_str| arg_values_str.map do |arg_value_str| arg_value_str.include?('.') ? arg_value_str.to_f : arg_value_str.to_i end @@ -155,6 +157,34 @@ def find_tests(source) arg_combinations.flatten.join(', ') end end + + # Based on: + ## https://en.cppreference.com/w/cpp/language/integer_literal + ## https://en.cppreference.com/w/cpp/language/character_literal + ## https://en.cppreference.com/w/cpp/language/string_literal + ## https://en.cppreference.com/w/cpp/language/floating_literal + ## https://en.cppreference.com/w/cpp/language/escape + ## Strings & chars with '[', ']', '(', ')' + ## Empty args + ## Args with spaces (not strings or char sequences) + ## String concatenations: "Hello" "World" + # Not supported: array addressing (with []) + + one_number_or_text_regex_string = /[^"',\s\]](?:['\s]*[^"',\s\]])*/.source + one_string_regex_string = /"(?:[^"\\]|\\.)*"/.source + one_char_regex_string = /'(?:[^'\\]|\\.)*'/.source + one_arg_regex_string = /(?:(?:(?:#{one_number_or_text_regex_string}\s*)?#{one_string_regex_string})+|(?:#{one_number_or_text_regex_string}\s*)?#{one_char_regex_string}|(?:#{one_number_or_text_regex_string}))/.source + + arguments.scan(/\s*TEST_MATRIX\s*\(((?:(?!#{tests_regex_string}).)*)\)\s*$/m).flatten.each do |values| + args += values.scan(/\[\s*((?:#{one_arg_regex_string}\s*,\s*)*#{one_arg_regex_string})\s*\]/m).flatten.map do |one_arg_values| + # Force appending comma for usual regular matching + (one_arg_values + ',').scan(/(#{one_arg_regex_string})\s*,/m) + end.reduce do |result, arg_range_expanded| + result.product(arg_range_expanded) + end.map do |arg_combinations| + arg_combinations.flatten.join(', ') + end + end end tests_and_line_numbers << { test: name, args: args, call: call, params: params, line_number: 0 }