import pytest
from unittest.mock import patch, MagicMock

def test_shader_manager_initialization_and_compilation():
 # Import inside test to allow patching OpenGL before import if needed
 # In this case, we patch the OpenGL.GL functions used by ShaderManager
 with patch("src.shader_manager.gl") as mock_gl:
  mock_gl.glCreateProgram.return_value = 1
  mock_gl.glCreateShader.return_value = 2
  mock_gl.glGetShaderiv.return_value = mock_gl.GL_TRUE
  mock_gl.glGetProgramiv.return_value = mock_gl.GL_TRUE
  
  from src.shader_manager import ShaderManager
  
  manager = ShaderManager()
  
  # Basic vertex and fragment shader source
  vert_src = "void main() {}"
  frag_src = "void main() {}"
  
  program_id = manager.compile_shader(vert_src, frag_src)
  
  assert program_id == 1
  assert mock_gl.glCreateProgram.called
  assert mock_gl.glCreateShader.called

def test_shader_manager_uniform_update():
 # Mock OpenGL.GL functions
 with patch("src.shader_manager.gl") as mock_gl:
  from src.shader_manager import ShaderManager
  manager = ShaderManager()
  # Set a mock program ID
  manager.program = 1
  
  # Mock glGetUniformLocation to return some valid locations
  # u_time -> 10, u_resolution -> 20
  def mock_get_loc(prog, name):
   if name == "u_time": return 10
   if name == "u_resolution": return 20
   return -1
   
  mock_gl.glGetUniformLocation.side_effect = mock_get_loc
  
  # Call the method
  manager.update_uniforms({"u_time": 1.5, "u_resolution": (800, 600)})
  
  # Assert calls
  mock_gl.glGetUniformLocation.assert_any_call(1, "u_time")
  mock_gl.glGetUniformLocation.assert_any_call(1, "u_resolution")
  mock_gl.glUniform1f.assert_called_once_with(10, 1.5)
  mock_gl.glUniform2f.assert_called_once_with(20, 800, 600)
