Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split up tests #191

Closed
wants to merge 6 commits into from
Closed

Split up tests #191

wants to merge 6 commits into from

Conversation

KyGost
Copy link
Contributor

@KyGost KyGost commented Mar 30, 2021

This PR makes it easier to have foldered tests by adding the build_suite!() macro.

@panarch panarch self-requested a review March 30, 2021 10:48
@panarch
Copy link
Member

panarch commented Mar 30, 2021

Ok, new test_case! macro only allows to have a single test case per file.
I don't think it's good to remove this kind of flexibility.

One example good to look would be rename test case in tests/alter_table.rs.
original code is this

test_case!(rename, async move {                                           
    let test_cases = vec![                                                
        ("CREATE TABLE Foo (id INTEGER);", Ok(Payload::Create)),          
        (                                                                 
            "INSERT INTO Foo VALUES (1), (2), (3);",                      
            Ok(Payload::Insert(3)),                                       
        ),                                                                
        ("SELECT id FROM Foo", Ok(select!(id; I64; 1; 2; 3))),            
        (                                                                 
            "ALTER TABLE Foo2 RENAME TO Bar;",                            
            Err(AlterTableError::TableNotFound("Foo2".to_owned()).into()),
        ),                                                                
        ("ALTER TABLE Foo RENAME TO Bar;", Ok(Payload::AlterTable)),      
        ("SELECT id FROM Bar", Ok(select!(id; I64; 1; 2; 3))),            
        (                                                                 
            "ALTER TABLE Bar RENAME COLUMN id TO new_id",                 
            Ok(Payload::AlterTable),                                      
        ),                                                                
        ("SELECT new_id FROM Bar", Ok(select!(new_id; I64; 1; 2; 3))),    
        (                                                                 
            "ALTER TABLE Bar RENAME COLUMN hello TO idid",                
            Err(AlterTableError::RenamingColumnNotFound.into()),          
        ),                                                                
    ];                                                                    
                                                                          
    for (sql, expected) in test_cases.into_iter() {                       
        test!(expected, sql);                                             
    }                                                                     
});                                                                       

This actually contains two independent tests.

  • Rename table
  • Rename column

Therefore, it might be better with separated ones.

test_case!(rename_table, async move {                                     
    let test_cases = vec![                                                
        ("CREATE TABLE Foo (id INTEGER);", Ok(Payload::Create)),          
        (                                                                 
            "INSERT INTO Foo VALUES (1), (2), (3);",                      
            Ok(Payload::Insert(3)),                                       
        ),                                                                
        (                                                                 
            "ALTER TABLE Foo2 RENAME TO Bar;",                            
            Err(AlterTableError::TableNotFound("Foo2".to_owned()).into()),
        ),                                                                
        ("ALTER TABLE Foo RENAME TO Bar;", Ok(Payload::AlterTable)),      
        ("SELECT id FROM Bar", Ok(select!(id; I64; 1; 2; 3))),            
    ];                                                                    
                                                                          
    for (sql, expected) in test_cases.into_iter() {                       
        test!(expected, sql);                                             
    }                                                                     
});                                                                       
                                                                          
test_case!(rename_column, async move {                                    
    let test_cases = vec![                                                
        ("CREATE TABLE Foo (id INTEGER);", Ok(Payload::Create)),          
        (                                                                 
            "INSERT INTO Foo VALUES (1), (2), (3);",                      
            Ok(Payload::Insert(3)),                                       
        ),                                                                
        (                                                                 
            "ALTER TABLE Foo RENAME COLUMN id TO new_id",                 
            Ok(Payload::AlterTable),                                      
        ),                                                                
        ("SELECT new_id FROM Foo", Ok(select!(new_id; I64; 1; 2; 3))),    
        (                                                                 
            "ALTER TABLE Foo RENAME COLUMN hello TO idid",                
            Err(AlterTableError::RenamingColumnNotFound.into()),          
        ),                                                                
    ];                                                                    
                                                                          
    for (sql, expected) in test_cases.into_iter() {                       
        test!(expected, sql);                                             
    }                                                                     
});

And then, if we even make an another helper macro to omit this kind of repetition codes (below), codes lines will even become less.

    for (sql, expected) in test_cases.into_iter() {                       
        test!(expected, sql);                                             
    }                                                                     

I don't think it is good to have two files which each one has only around 10 lines of codes.
So.. the point is, I think that new test_case! macro can bother us to write more explicit integration tests.

@KyGost
Copy link
Contributor Author

KyGost commented Mar 30, 2021

@panarch

I don't think it is good to have two files which each one has only around 10 lines of codes.

Could you elaborate on this?
Why not?

@panarch
Copy link
Member

panarch commented Mar 30, 2021

@KyGost ok, I think that is more efficient because we can scan the whole file without tab switching or scrolling, and these two files share the same parent category, alter table.
However, once we split into files, then we cannot do that.

It is basically similar behavior with what we do on Rust codes.
Once, we start with a single file, then it becomes too big then we split into modules.
We can apply same approach to tests, starting with a single file and expanding it.

@KyGost
Copy link
Contributor Author

KyGost commented Mar 30, 2021

Hmmm...

I tend to like splitting whenever there's a difference in context, including for code.
I think we've run into this a little in past in splitting the code.

I think us using different editors might contribute to this.

I've just realised-- can't we just do:

mod rename_table {
  test_case!(async move {                                     
      let test_cases = vec![                                                
          ("CREATE TABLE Foo (id INTEGER);", Ok(Payload::Create)),          
          (                                                                 
              "INSERT INTO Foo VALUES (1), (2), (3);",                      
              Ok(Payload::Insert(3)),                                       
          ),                                                                
          (                                                                 
              "ALTER TABLE Foo2 RENAME TO Bar;",                            
              Err(AlterTableError::TableNotFound("Foo2".to_owned()).into()),
          ),                                                                
          ("ALTER TABLE Foo RENAME TO Bar;", Ok(Payload::AlterTable)),      
          ("SELECT id FROM Bar", Ok(select!(id; I64; 1; 2; 3))),            
      ];                                                                    
                                                                            
      for (sql, expected) in test_cases.into_iter() {                       
          test!(expected, sql);                                             
      }                                                                     
  });
}                                                           
           
mod rename_column {                                                    
  test_case!(async move {                                    
      let test_cases = vec![                                                
          ("CREATE TABLE Foo (id INTEGER);", Ok(Payload::Create)),          
          (                                                                 
              "INSERT INTO Foo VALUES (1), (2), (3);",                      
              Ok(Payload::Insert(3)),                                       
          ),                                                                
          (                                                                 
              "ALTER TABLE Foo RENAME COLUMN id TO new_id",                 
              Ok(Payload::AlterTable),                                      
          ),                                                                
          ("SELECT new_id FROM Foo", Ok(select!(new_id; I64; 1; 2; 3))),    
          (                                                                 
              "ALTER TABLE Foo RENAME COLUMN hello TO idid",                
              Err(AlterTableError::RenamingColumnNotFound.into()),          
          ),                                                                
      ];                                                                    
                                                                            
      for (sql, expected) in test_cases.into_iter() {                       
          test!(expected, sql);                                             
      }                                                                     
  });
}

@panarch
Copy link
Member

panarch commented Mar 30, 2021

I tend to like splitting whenever there's a difference in context, including for code.

I also agree with splitting for different context, but it doesn't need to be as a file.
If we can reduce use of tabs, it would be better I think.
Usual UI of tabs are aligned as horizontal direction.
It is easier to expand vertically than horizontally.

but, what is better than before?

before

test_case!(rename_table, async move { .. });

new

mod rename_table {
  test_case!(async move { .. })
}

@KyGost
Copy link
Contributor Author

KyGost commented Mar 30, 2021

@panarch

Usual UI of tabs are aligned as horizontal direction.
It is easier to expand vertically than horizontally.

I don't think it's as simple as expansion, splitting files makes it a lot easier to locate where each thing is.
Once again though, this might just relate to editors; here's an example for why I like to split files:
image
If I want to pay attention to the validation of types, I can open up the tests/validate/types.rs file at the click of a button, if it is a small file I can immediately see all the code I need to without scrolling. I can then jump to another file with another click of a button.

I digress however; this is not an important point.

but, what is better than before?

What is better is that the files are much easier to manage, we use the mod.rs and folders to collate them and having the mod makes it so that it is very clear that they aren't interacting with eachother.

@panarch
Copy link
Member

panarch commented Mar 30, 2021

Ok I use vim and too many tabs are quite bothering, harder to move and I cannot read the full tab names.
image


mod rename_table {
  test_case!(async move { .. })
}

Ok the point was, if you intend to use mod then it should be possible to gather multiple test cases.
test_case! already exports async pub fn so there's no meaning to wrap using mod.

@KyGost
Copy link
Contributor Author

KyGost commented Mar 30, 2021

Ok the point was, if you intend to use mod then it should be possible to gather multiple test cases.
test_case! already exports async pub fn so there's no meaning to wrap using mod.

The wrap with module is because normally it they don't have seperate names (anymore), seperate function names is a bit tedious.

@panarch
Copy link
Member

panarch commented Mar 30, 2021

mod rename_table {
  test_case!(async move { .. })
}

this will become

mod rename_table {
  pub async fn rename_table( .. ) { .. }
}

original one simply generates

pub async fn rename_table( .. ) { .. }

This is not the matter of preference, there's really no meaning of module in this case.
mod simply makes us to write rename_table::rename_table which was enough with rename_table.

If the file module name is rename and there exists rename_table and rename_column, then it makes sense.
However, current rename_table module can only have rename_table function.

@KyGost
Copy link
Contributor Author

KyGost commented Mar 30, 2021

mod rename_table {
  test_case!(async move { .. })
}

this will become

mod rename_table {
  pub async fn rename_table( .. ) { .. }
}

original one simply generates

pub async fn rename_table( .. ) { .. }

This is not the matter of preference, there's really no meaning of module in this case.
mod simply makes us to write rename_table::rename_table which was enough with rename_table.

If the file module name is rename and there exists rename_table and rename_column, then it makes sense.
However, current rename_table module can only have rename_table function.

With the code, as it is now, it would become:

mod rename_table {
  pub async fn test( .. ) { .. }
}

as stated I removed the individual function names.

Saying that, however, I'm considering bringing them back for secondary functions.

@panarch
Copy link
Member

panarch commented Mar 30, 2021

mod rename_table {
  pub async fn test( .. ) { .. }
}

ok, it's better than having fn rename_table inside.
However, still we need to attach test which were not required to use.

mod rename_table {
  pub async fn test( .. ) { .. }

  pub async fn test_something_different( .. ) { .. }

  pub async fn test_something_another( .. ) { .. }
}

In this above example, it makes sense to have a module because it contains multiple different methods.

The reason I mentioned there's no meaning is because mod rename_table only has a single function and it is actually same as using a function. So function is better because it has more smaller and explicit meaning.

@KyGost KyGost changed the title Clean up tests and add tests for INSERTs Split up tests Apr 1, 2021
@KyGost
Copy link
Contributor Author

KyGost commented Apr 1, 2021

nb. above was discussed in a voice chat.

@KyGost KyGost marked this pull request as ready for review April 1, 2021 06:24
@panarch
Copy link
Member

panarch commented Apr 1, 2021

Ok, please give me some time to show what I plan to make the current test system better, I think it would be better with using real implementation codes.
It may took some time for me, I'll share with you right after.

@panarch
Copy link
Member

panarch commented Apr 24, 2021

Closing PRs which are merged and working well in the fork.

@panarch panarch closed this Apr 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants