Files
I150/srcs/RobotNet10/RobotApp/Communication/CeresSharp.Test/QUERY_METHODS_EXPLANATION.md
2026-07-03 16:37:12 +07:00

9.0 KiB

Problem Query Methods - Giải Thích

"Problem Query Methods" là gì?

Problem Query Methods là các methods trong class Problem dùng để query (truy vấn) thông tin về Problem, thay vì thay đổi trạng thái của Problem.

Ví dụ:

  • Non-query methods (thay đổi trạng thái):

    • AddParameterBlock() - thêm parameter block
    • SetParameterBlockConstant() - đặt parameter block thành constant
    • SetManifold() - gán manifold cho parameter block
  • Query methods (chỉ đọc thông tin):

    • HasParameterBlock() - kiểm tra parameter block có tồn tại không
    • GetParameterBlockSize() - lấy kích thước của parameter block
    • IsParameterBlockConstant() - kiểm tra parameter block có constant không
    • HasManifold() - kiểm tra parameter block có manifold không
    • GetManifoldHandle() - lấy manifold handle của parameter block

So Sánh: C Test vs C# Test

C Test (test_problem_query_methods) - Test 11

C test có explicit tests cho tất cả query methods:

// Test has_parameter_block
int has_block = ceres_wrapper_problem_has_parameter_block(problem, params);
TEST_ASSERT(has_block == 1, "Has parameter block");

// Test get_parameter_block_size
int size = ceres_wrapper_problem_get_parameter_block_size(problem, params);
TEST_ASSERT(size == 3, "Get parameter block size");

// Test is_parameter_block_constant
int is_constant = ceres_wrapper_problem_is_parameter_block_constant(problem, params);
TEST_ASSERT(is_constant == 0, "Parameter block is variable");

// Test has_manifold
int has_manifold = ceres_wrapper_problem_has_manifold(problem, params);
TEST_ASSERT(has_manifold == 0, "No manifold initially");

// Test get_manifold
ceres_manifold_t* manifold = ceres_wrapper_problem_get_manifold(problem, params);
TEST_ASSERT(manifold == NULL, "Get manifold returns NULL when no manifold");

// Test với non-existent parameter block
double fake_params[2] = {99.0, 99.0};
has_block = ceres_wrapper_problem_has_parameter_block(problem, fake_params);
TEST_ASSERT(has_block == 0, "Non-existent parameter block");

size = ceres_wrapper_problem_get_parameter_block_size(problem, fake_params);
TEST_ASSERT(size == -1, "Get size returns -1 for non-existent block");

C# Test - Hiện Tại

C# test chỉ có tests cho:

  • IsParameterBlockConstant() - có 2 tests
    • IsParameterBlockConstant_ShouldReturnFalse_WhenVariable
    • IsParameterBlockConstant_ShouldReturnTrue_WhenConstant

Thiếu tests cho:

  • HasParameterBlock() - chưa có test
  • GetParameterBlockSize() - chưa có test
  • HasManifold() - chưa có test
  • GetManifoldHandle() - chưa có test
  • GetParameterBlockTangentSize() - chưa có test

Tại Sao Cần Test Query Methods?

1. Verify API Works Correctly

Đảm bảo các methods trả về đúng giá trị:

  • HasParameterBlock() trả về true khi parameter block tồn tại
  • GetParameterBlockSize() trả về đúng kích thước
  • HasManifold() trả về true sau khi set manifold

2. Edge Cases

Test các trường hợp đặc biệt:

  • Query parameter block không tồn tại → trả về false hoặc -1
  • Query manifold khi chưa set → trả về false hoặc IntPtr.Zero
  • Query size của non-existent block → trả về -1

3. Integration với Other Operations

Verify query methods hoạt động đúng sau các operations:

  • Sau AddParameterBlock()HasParameterBlock() = true
  • Sau SetManifold()HasManifold() = true
  • Sau SetParameterBlockConstant()IsParameterBlockConstant() = true

Các Methods Cần Test

1. HasParameterBlock(double[] parameters)

Mục đích: Kiểm tra parameter block có tồn tại trong Problem không

Test cases cần có:

[Test]
public void HasParameterBlock_ShouldReturnTrue_WhenExists()
{
    using var problem = new Problem();
    var parameters = new double[] { 1.0, 2.0 };
    problem.AddParameterBlock(parameters, parameters.Length);
    
    var hasBlock = problem.HasParameterBlock(parameters);
    
    Assert.That(hasBlock, Is.True);
}

[Test]
public void HasParameterBlock_ShouldReturnFalse_WhenNotExists()
{
    using var problem = new Problem();
    var parameters = new double[] { 1.0, 2.0 };
    var fakeParams = new double[] { 99.0, 99.0 };
    
    problem.AddParameterBlock(parameters, parameters.Length);
    
    var hasBlock = problem.HasParameterBlock(fakeParams);
    
    Assert.That(hasBlock, Is.False);
}

2. GetParameterBlockSize(double[] parameters)

Mục đích: Lấy kích thước của parameter block

Test cases cần có:

[Test]
public void GetParameterBlockSize_ShouldReturnCorrectSize()
{
    using var problem = new Problem();
    var parameters = new double[] { 1.0, 2.0, 3.0 };
    problem.AddParameterBlock(parameters, parameters.Length);
    
    var size = problem.GetParameterBlockSize(parameters);
    
    Assert.That(size, Is.EqualTo(3));
}

[Test]
public void GetParameterBlockSize_ShouldReturnMinusOne_WhenNotExists()
{
    using var problem = new Problem();
    var fakeParams = new double[] { 99.0, 99.0 };
    
    var size = problem.GetParameterBlockSize(fakeParams);
    
    Assert.That(size, Is.EqualTo(-1));
}

3. HasManifold(double[] parameters)

Mục đích: Kiểm tra parameter block có manifold không

Test cases cần có:

[Test]
public void HasManifold_ShouldReturnFalse_WhenNoManifold()
{
    using var problem = new Problem();
    var parameters = new double[] { 1.0, 2.0, 3.0, 4.0 };
    problem.AddParameterBlock(parameters, parameters.Length);
    
    var hasManifold = problem.HasManifold(parameters);
    
    Assert.That(hasManifold, Is.False);
}

[Test]
public void HasManifold_ShouldReturnTrue_WhenManifoldSet()
{
    using var problem = new Problem();
    var quaternion = new double[] { 0.0, 0.0, 0.0, 1.0 };
    problem.AddParameterBlock(quaternion, quaternion.Length);
    
    using var manifold = new QuaternionManifold();
    problem.SetManifold(quaternion, manifold);
    
    var hasManifold = problem.HasManifold(quaternion);
    
    Assert.That(hasManifold, Is.True);
}

4. GetManifoldHandle(double[] parameters)

Mục đích: Lấy native handle của manifold (trả về IntPtr.Zero nếu không có)

Test cases cần có:

[Test]
public void GetManifoldHandle_ShouldReturnZero_WhenNoManifold()
{
    using var problem = new Problem();
    var parameters = new double[] { 1.0, 2.0 };
    problem.AddParameterBlock(parameters, parameters.Length);
    
    var handle = problem.GetManifoldHandle(parameters);
    
    Assert.That(handle, Is.EqualTo(IntPtr.Zero));
}

[Test]
public void GetManifoldHandle_ShouldReturnNonZero_WhenManifoldSet()
{
    using var problem = new Problem();
    var quaternion = new double[] { 0.0, 0.0, 0.0, 1.0 };
    problem.AddParameterBlock(quaternion, quaternion.Length);
    
    using var manifold = new QuaternionManifold();
    problem.SetManifold(quaternion, manifold);
    
    var handle = problem.GetManifoldHandle(quaternion);
    
    Assert.That(handle, Is.Not.EqualTo(IntPtr.Zero));
}

5. GetParameterBlockTangentSize(double[] parameters)

Mục đích: Lấy tangent size của parameter block (khi có manifold)

Test cases cần có:

[Test]
public void GetParameterBlockTangentSize_ShouldReturnTangentSize_WithManifold()
{
    using var problem = new Problem();
    var quaternion = new double[] { 0.0, 0.0, 0.0, 1.0 }; // 4D ambient
    problem.AddParameterBlock(quaternion, quaternion.Length);
    
    using var manifold = new QuaternionManifold(); // 3D tangent
    problem.SetManifold(quaternion, manifold);
    
    var tangentSize = problem.GetParameterBlockTangentSize(quaternion);
    
    Assert.That(tangentSize, Is.EqualTo(3)); // Quaternion: 4D ambient → 3D tangent
}

Kết Luận

Hiện Tại

  • C# API đã implement tất cả query methods
  • C# test đã có test cho IsParameterBlockConstant()
  • C# test thiếu tests cho 5 methods còn lại

Khuyến Nghị

  1. Nên thêm tests cho các query methods để:

    • Đảm bảo API hoạt động đúng
    • Test edge cases (non-existent blocks, null parameters)
    • Verify integration với các operations khác
  2. Priority:

    • High: HasParameterBlock(), GetParameterBlockSize() - thường dùng
    • Medium: HasManifold(), GetManifoldHandle() - dùng khi làm việc với manifolds
    • Low: GetParameterBlockTangentSize() - ít dùng, nhưng nên có test
  3. Impact:

    • Không ảnh hưởng đến production (API đã implement đúng)
    • Nhưng thiếu tests có thể dẫn đến bugs không được phát hiện khi refactor

Last Updated: 2024-12-19