@@ -211,15 +211,16 @@ def run_comparison(specs, adapters, reference_name, options)
211211 matched = 0
212212 skipped = 0
213213 checked = 0
214+ variants = expand_error_mode_variants ( specs , adapters )
214215
215216 max_failures = options [ :max_failures ]
216217 verbose = options [ :verbose ]
217218
218- print ( "Running #{ specs . size } specs: " )
219+ print ( "Running #{ variants . size } specs: " )
219220 $stdout. flush
220221
221222 TimeFreezer . freeze_spec_time do
222- specs . each do |spec |
223+ variants . each do |spec |
223224 # Run on ALL adapters that can run this spec
224225 outputs = { }
225226 adapters . each do |name , adapter |
@@ -296,11 +297,41 @@ def run_comparison(specs, adapters, reference_name, options)
296297
297298 # Print results (limited by max_failures for display only)
298299 print_results_v2 ( differences , adapters , options , max_failures )
299- print_summary ( matched , differences . size , skipped , checked , specs . size , adapters )
300+ print_summary ( matched , differences . size , skipped , checked , variants . size , adapters )
300301
301302 exit ( 1 ) if differences . any?
302303 end
303304
305+ # Matrix executes each explicit compatible parse mode independently.
306+ # Ordinary specs use strict2, the harness-wide default, so adapters
307+ # that only implement strict/lax are not compared against a different
308+ # parser contract by accident.
309+ def expand_error_mode_variants ( specs , adapters )
310+ supported = LiquidSpec ::PARSE_ERROR_MODES . select do |mode |
311+ feature = :"#{ mode } _parsing"
312+ adapters . values . any? { |adapter | !adapter . missing_features . include? ( feature ) }
313+ end
314+
315+ specs . flat_map do |spec |
316+ declared = declared_error_modes ( spec )
317+ modes = if declared . empty?
318+ supported . include? ( :strict2 ) ? [ :strict2 ] : [ supported . first ] . compact
319+ else
320+ LiquidSpec ::PARSE_ERROR_MODES . select { |mode | declared . include? ( mode ) && supported . include? ( mode ) }
321+ end
322+
323+ modes . map { |mode | spec . with_error_mode ( mode , label : declared . length > 1 ) }
324+ end
325+ end
326+
327+ def declared_error_modes ( spec )
328+ return spec . error_modes unless spec . error_modes . empty?
329+
330+ LiquidSpec ::PARSE_ERROR_MODES . select do |mode |
331+ spec . features . include? ( :"#{ mode } _parsing" )
332+ end
333+ end
334+
304335
305336
306337
0 commit comments