<commit_before>#require 'pathname'
#p Pathname(caller.last.split(':').first)
require 'ostruct'

class Tryouts
  @debug = false
  @container = Class.new
  @cases = []
  class << self
    attr_accessor :debug, :container
    attr_reader :cases
    
    def run_all *paths
      container.send(:eval, "def foo() 1 end")
      
      batches = paths.collect do |path|
        run path
      end
      msg
      all, skipped, failed_batches, failed_tests = 0, 0, 0, 0
      batches.each do |batch|
        failed_batches += 1 if batch.failed?
        batch.each do |t|
          
          all += 1
          skipped += 1 unless t.run?

          if t.failed?
            msg if (failed_tests += 1) == 1
            msg t.test.path
            msg Console.color(:red, '-'*40)
            msg Console.color(:red, t.inspect)
          end
        end
      end
      if batches.size > 1
        msg cformat('batches', batches.size-failed_batches, batches.size, :passed)
      end
      
      msg cformat(all-failed_tests, all, 'tests passed') if all-skipped > 0
      msg cformat(skipped, all, 'tests skipped') if skipped > 0
      
      failed_batches == 0
    end
    
    def cformat(*args)
      Console.bright '%3d of %d %s' % args
    end
    
    def run path
      batch = parse path
      batch.run
      batch
    end
    
    def parse path
      debug "Loading #{path}"
      lines = File.readlines path
      skip_ahead = 0
      batch = TestBatch.new path, lines
      lines.size.times do |idx|
        skip_ahead -= 1 and next if skip_ahead > 0
        line = lines[idx].chomp
        #debug('%-4d %s' % [idx, line])
        if expectation? line
          offset = 0
          exps = Section.new(path, idx+1)
          exps << line.chomp
          while (idx+offset < lines.size)
            offset += 1
            this_line = lines[idx+offset]
            break if ignore?(this_line)
            if expectation?(this_line)
              exps << this_line
              skip_ahead += 1
            end
            exps.last += 1
          end
          
          offset = 0
          buffer, desc = Section.new(path), Section.new(path)
          test = Section.new(path, idx)  # test start the line before the exp. 
          while (idx-offset >= 0)
            offset += 1
            this_line = lines[idx-offset].chomp
            test.unshift this_line if ignore?(this_line)
            buffer.unshift this_line if comment?(this_line)
            if test?(this_line)
              test.unshift(*buffer) && buffer.clear
              test.unshift this_line
            end
            if test_begin?(this_line) || expectation?(this_line) || idx-offset == 0
              test.first = idx-offset+buffer.size+1
              desc.unshift *buffer
              desc.last = test.first-1
              desc.first = desc.last-desc.size+1
              break 
            end
          end
          
          batch << TestCase.new(desc, test, exps)
        end
      end
      batch
    end
    
    def print str
      STDOUT.print str
      STDOUT.flush
    end
    
    def msg *msg
      STDOUT.puts *msg
    end
    
    def err *msg
      msg.each do |line|
        STDERR.puts Console.color :red, line
      end
    end
    
    def debug *msg
      STDERR.puts *msg if @debug
    end
    
    def eval(str, path, line)
      begin
        Kernel.eval str, @container.send(:binding), path, line
      rescue SyntaxError, LoadError => ex
        Tryouts.err Console.color(:red, ex.message),
                    Console.color(:red, ex.backtrace.first)
        nil
      end
    end
    
    private
    
    def expectation? str
      !ignore?(str) && str.strip.match(/^\#\s*=>/)
    end
    
    def comment? str
      !str.strip.match(/^\#+/).nil? && !expectation?(str)
    end
    
    def test? str
      !ignore?(str) && !expectation?(str) && !comment?(str)
    end
    
    def ignore? str
      str.to_s.strip.chomp.empty?
    end
    
    def test_begin? str
      !str.strip.match(/^\#+\s*TEST/i).nil?
    end

    
  end
  
  class TestBatch < Array
    class Container
      def metaclass
        class << self; end
      end
    end
    attr_reader :path
    attr_reader :failed
    attr_reader :lines
    def initialize(p,l)
      @path, @lines = p, l
      @container = Container.new.metaclass
    end
    def run
      setup
      ret = self.select { |tc| !tc.run } # select failed
      @failed = ret.size unless ret.empty?
      clean
      !failed?
    end
    def failed?
       !@failed.nil? && @failed > 0
    end
    def setup
      start = first.desc.nil? first.test.first : first.desc.first-1
      Tryouts.eval lines[0..start-1].join, path, 0 if start > 0
    end
    def clean
      last = first.exps.last+1
      if last < lines.size
        Tryouts.eval lines[last..-1].join, path, last
      end
    end
    def run?
      !@failed.nil?
    end
  end
  class TestCase
    attr_reader :desc, :test, :exps
    def initialize(d,t,e)
      @desc, @test, @exps, @path = d,t,e
    end
    def inspect
      [@desc.inspect, @test.inspect, @exps.inspect].join
    end
    def to_s
      [@desc.to_s, @test.to_s, @exps.to_s].join
    end
    def test_proc
      create_proc @test.join("#{$/}  "), @test.path, @test.first
    end
    def exps_procs
      list = []<commit_msg>All steps pass<commit_after>#require 'pathname'
#p Pathname(caller.last.split(':').first)
require 'ostruct'

class Tryouts
  @debug = false
  @container = Class.new
  @cases = []
  class << self
    attr_accessor :debug, :container
    attr_reader :cases
    
    def run_all *paths
      container.send(:eval, "def foo() 1 end")
      
      batches = paths.collect do |path|
        run path
      end
      msg
      all, skipped, failed_batches, failed_tests = 0, 0, 0, 0
      batches.each do |batch|
        failed_batches += 1 if batch.failed?
        batch.each do |t|
          
          all += 1
          skipped += 1 unless t.run?

          if t.failed?
            msg if (failed_tests += 1) == 1
            msg t.test.path
            msg Console.color(:red, '-'*40)
            msg Console.color(:red, t.inspect)
          end
        end
      end
      if batches.size > 1
        msg cformat(batches.size-failed_batches, batches.size, 'batches passed')
      end
      
      msg cformat(all-failed_tests, all, 'tests passed') if all-skipped > 0
      msg cformat(skipped, all, 'tests skipped') if skipped > 0
      
      failed_batches == 0
    end
    
    def cformat(*args)
      Console.bright '%3d of %d %s' % args
    end
    
    def run path
      batch = parse path
      batch.run
      batch
    end
    
    def parse path
      debug "Loading #{path}"
      lines = File.readlines path
      skip_ahead = 0
      batch = TestBatch.new path, lines
      lines.size.times do |idx|
        skip_ahead -= 1 and next if skip_ahead > 0
        line = lines[idx].chomp
        #debug('%-4d %s' % [idx, line])
        if expectation? line
          offset = 0
          exps = Section.new(path, idx+1)
          exps << line.chomp
          while (idx+offset < lines.size)
            offset += 1
            this_line = lines[idx+offset]
            break if ignore?(this_line)
            if expectation?(this_line)
              exps << this_line
              skip_ahead += 1
            end
            exps.last += 1
          end
          
          offset = 0
          buffer, desc = Section.new(path), Section.new(path)
          test = Section.new(path, idx)  # test start the line before the exp. 
          while (idx-offset >= 0)
            offset += 1
            this_line = lines[idx-offset].chomp
            test.unshift this_line if ignore?(this_line)
            buffer.unshift this_line if comment?(this_line)
            if test?(this_line)
              test.unshift(*buffer) && buffer.clear
              test.unshift this_line
            end
            if test_begin?(this_line) || expectation?(this_line) || idx-offset == 0
              test.first = idx-offset+buffer.size+1
              desc.unshift *buffer
              desc.last = test.first-1
              desc.first = desc.last-desc.size+1
              break 
            end
          end
          
          batch << TestCase.new(desc, test, exps)
        end
      end
      batch
    end
    
    def print str
      STDOUT.print str
      STDOUT.flush
    end
    
    def msg *msg
      STDOUT.puts *msg
    end
    
    def err *msg
      msg.each do |line|
        STDERR.puts Console.color :red, line
      end
    end
    
    def debug *msg
      STDERR.puts *msg if @debug
    end
    
    def eval(str, path, line)
      begin
        Kernel.eval str, @container.send(:binding), path, line
      rescue SyntaxError, LoadError => ex
        Tryouts.err Console.color(:red, ex.message),
                    Console.color(:red, ex.backtrace.first)
        nil
      end
    end
    
    private
    
    def expectation? str
      !ignore?(str) && str.strip.match(/^\#\s*=>/)
    end
    
    def comment? str
      !str.strip.match(/^\#+/).nil? && !expectation?(str)
    end
    
    def test? str
      !ignore?(str) && !expectation?(str) && !comment?(str)
    end
    
    def ignore? str
      str.to_s.strip.chomp.empty?
    end
    
    def test_begin? str
      !str.strip.match(/^\#+\s*TEST/i).nil?
    end

    
  end
  
  class TestBatch < Array
    class Container
      def metaclass
        class << self; end
      end
    end
    attr_reader :path
    attr_reader :failed
    attr_reader :lines
    def initialize(p,l)
      @path, @lines = p, l
      @container = Container.new.metaclass
    end
    def run
      setup
      ret = self.select { |tc| !tc.run } # select failed
      @failed = ret.size unless ret.empty?
      clean
      !failed?
    end
    def failed?
       !@failed.nil? && @failed > 0
    end
    def setup
      return if empty?
      start = first.desc.nil? ? first.test.first : first.desc.first-1
      Tryouts.eval lines[0..start-1].join, path, 0 if start > 0
    end
    def clean
      return if empty?
      last = first.exps.last+1
      if last < lines.size
        Tryouts.eval lines[last..-1].join, path, last
      end
    end
    def run?
      !@failed.nil?
    end
  end
  class TestCase
    attr_reader :desc, :test, :exps
    def initialize(d,t,e)
      @desc, @test, @exps, @path = d,t,e
    end
    def inspect
      [@desc.inspect, @test.inspect, @exps.inspect].join
    end
    def to_s
      [@desc.to_s, @test.to_s, @exps.to_s].join
    end
    def test_proc
      create_proc @test.join("#{$/}  "), @test.path, @test.first
    end
    def exps_procs
      list = []
{'fraction_non_alphanumeric': 0.10621543076778851, 'fraction_numerical': 0.00768725977313209, 'mean_word_length': 1.5968841285296982, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3340444', 'n_tokens_mistral': 3472, 'n_tokens_neox': 3387, 'n_words': 908}