old_contents: import collections
  import io
  import json
  
  import os
  import pytest
  import glob
  import subprocess
  
  import thinglang
  from thinglang import run, utils
  
  SEARCH_PATTERN = os.path.join(os.path.dirname(os.path.abspath(__file__)),  '**/*.thing')
  
  TestCase = collections.namedtuple('TestCase', ['code', 'metadata', 'name', 'bytecode_target'])
  EXECUTABLE = r"C:\Users\Yotam\Development\thinglang\cmake-build-debug\thingc.exe"
  
  
  def collect_tests():
      for path in glob.glob(SEARCH_PATTERN, recursive=True):
          with open(path, 'r') as f:
              contents = f.read()
              metadata_start = contents.index('/*') + 2
              metadata_end = contents.index('*/')
              metadata = json.loads(contents[metadata_start:metadata_end])
              yield TestCase(
                  contents[metadata_end + 2:],
                  metadata,
                  metadata.get('test_name') or '.'.join(path.replace('.thing', '').split(os.sep)[-2:]),
                  path + 'c'
              )
  
  
  def split_lines(param):
      return param.replace('\r', '').split('\n')
  
  
  @pytest.mark.parametrize('test_file', collect_tests(), ids=lambda x: x.name)
  def test_thing_program(test_file):
      expected_output = test_file.metadata['expected_output']
  
      utils.print_header("Bytecode generation")
      bytecode = thinglang.compiler(test_file.code).compile().finalize()
      print(bytecode)
  
      utils.print_header('VM execution')
  
      with open(test_file.bytecode_target, 'wb') as f:
          f.write(bytecode)
  
      vm = subprocess.Popen([EXECUTABLE, test_file.bytecode_target], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      stdout, stderr = (stream.decode('utf-8').strip() for stream in vm.communicate())
      print(stderr)
  
      utils.print_header('VM output')
      print(stdout)
  
      local = thinglang.run(test_file.code).output
  
      if not isinstance(expected_output, str):
          stdout = split_lines(stdout)
          local = split_lines(local)
  
      assert vm.returncode == 0, 'VM process crashed'
      assert local == expected_output, 'Execution engine output did not match expected output'
      assert stdout == expected_output, 'VM output did not match expected output'
  
  
  
  
  
new_contents: import collections
  import io
  import json
  
  import os
  import pytest
  import glob
  import subprocess
  
  import thinglang
  from thinglang import run, utils
  
  BASE_PATH = os.path.dirname(os.path.abspath(__file__))
  
  SEARCH_PATTERN = os.path.join(BASE_PATH, '**/*.thing')
  
  TestCase = collections.namedtuple('TestCase', ['code', 'metadata', 'name', 'bytecode_target'])
  
  
  def collect_tests():
      for path in glob.glob(SEARCH_PATTERN, recursive=True):
          with open(path, 'r') as f:
              contents = f.read()
              metadata_start = contents.index('/*') + 2
              metadata_end = contents.index('*/')
              metadata = json.loads(contents[metadata_start:metadata_end])
              yield TestCase(
                  contents[metadata_end + 2:],
                  metadata,
                  metadata.get('test_name') or '.'.join(path.replace('.thing', '').split(os.sep)[-2:]),
                  path + 'c'
              )
  
  
  def split_lines(param):
      return param.replace('\r', '').split('\n')
  
  
  @pytest.mark.parametrize('test_file', collect_tests(), ids=lambda x: x.name)
  def test_thing_program(test_file):
      expected_output = test_file.metadata['expected_output']
  
      utils.print_header("Bytecode generation")
      bytecode = thinglang.compiler(test_file.code).compile().finalize()
      print(bytecode)
  
      utils.print_header('VM execution')
  
      with open(test_file.bytecode_target, 'wb') as f:
          f.write(bytecode)
  
      vm = subprocess.Popen(["thinglang", test_file.bytecode_target], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      stdout, stderr = (stream.decode('utf-8').strip() for stream in vm.communicate())
      print(stderr)
  
      utils.print_header('VM output')
      print(stdout)
  
      local = thinglang.run(test_file.code).output
  
      if not isinstance(expected_output, str):
          stdout = split_lines(stdout)
          local = split_lines(local)
  
      assert vm.returncode == 0, 'VM process crashed'
      assert local == expected_output, 'Execution engine output did not match expected output'
      assert stdout == expected_output, 'VM output did not match expected output'
  
  
  
  
  
subject: Fix thinglang VM executable path