Blame | Last modification | View Log | RSS feed
//---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include <vector>#include <map>#include "TestDirectorLogin.h"#include "TestDirectorImport.h"#include "DataModule.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma link "AdvMemo"#pragma resource "*.dfm"TTestDirectorImportForm *TestDirectorImportForm;//---------------------------------------------------------------------------static TestDirectorNodeList_t TestDirectorNodes;static TestDirectorNodeMap_t TestDirectorNodeMap;static TestDirectorNodeMap_t TestDirectorScenarioMap;//---------------------------------------------------------------------------__fastcall TTestDirectorImportForm::TTestDirectorImportForm(TComponent* Owner): TForm(Owner){}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::FormClose(TObject *Sender,TCloseAction &Action){TestDirectorConnection->Connected = false;}//---------------------------------------------------------------------------const bool TTestDirectorImportForm::isTestCase( const AnsiString & description ){const AnsiString code = description.SubString( 1, 3 );return ( ( code == "STC" ) || ( code == "SDD" ) || ( code == "SRQ" ) );}//---------------------------------------------------------------------------void TTestDirectorImportForm::ShowForm( const AnsiString &project, int iteration ){m_project = project;m_iteration = iteration;if (TestDirectorLoginForm->Login( TestDirectorConnection ) ){ShowModal();TestDirectorConnection->Connected = false; // Break Connectiontry{TestDirectorNodeList_t::iterator itr = TestDirectorNodes.begin();while (itr != TestDirectorNodes.end()){TestDirectorNode *td_node = (*itr);delete td_node;++itr;}}catch(...){}TestDirectorNodes.clear();TestDirectorNodeMap.clear();TestDirectorScenarioMap.clear();}else{MessageDlg("Failed to connect to Test Director", mtError, TMsgDlgButtons() << mbOK, 0);}}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::LoadTestDataScenarioData(unsigned int &root_node, AnsiString &root_node_name){TADOQuery *query = NULL;AnsiString sql_statement;try{query = new TADOQuery(this);query->Connection = TestDirectorConnection;// -----------------------------------------------------------------------sql_statement = "SELECT AL_ITEM_ID,AL_FATHER_ID,AL_DESCRIPTION,AL_MEMO,AL_NO_OF_SONS ""FROM TD.ALL_LISTS ""ORDER BY TD.AL_DESCRIPTION";query->SQL->Text = sql_statement;query->Open();if (query->RecordCount > 0){// int count_test_cases = query->RecordCount;while (!query->Eof){unsigned short item_id = query->FieldByName("AL_ITEM_ID")->AsInteger;unsigned short father_id = query->FieldByName("AL_FATHER_ID")->AsInteger;TestDirectorNode *td_node = new TestDirectorNode;TestDirectorNodes.push_back(td_node);td_node->nodetype = TESTCASE;td_node->name = query->FieldByName("AL_DESCRIPTION")->AsString;td_node->parentnode = father_id;td_node->subjectnode = item_id;td_node->text1 = query->FieldByName("AL_MEMO")->AsString;// Pick out the SQT node for the moment - TODO revisit thisif (td_node->name == "SQT"){root_node = item_id;root_node_name = td_node->name;}TestDirectorNodePair_t pair(item_id, td_node);TestDirectorNodeMap.insert( pair );query->Next();} // while// Build the Parent/Child linkagesTestDirectorNodeMap_t::iterator itr = TestDirectorNodeMap.begin();while (itr != TestDirectorNodeMap.end()){TestDirectorNode *td_node = (*itr).second;TestDirectorNodeMap_t::iterator parent_itr = TestDirectorNodeMap.find( td_node->parentnode );if (parent_itr != TestDirectorNodeMap.end()){TestDirectorNode *parent_td_node = (*parent_itr).second;td_node->parent = parent_td_node;parent_td_node->children.push_back( td_node );}++itr;} // while}// -----------------------------------------------------------------------}catch(...){}delete query;}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::LoadTestScenarios(TestDirectorNode *parent_td_node){TADOQuery *query = NULL;AnsiString sql_statement;try{query = new TADOQuery(this);query->Connection = TestDirectorConnection;// Load Test Scenariossql_statement.sprintf("SELECT TS_TEST_ID,TS_SUBJECT,TS_NAME,TS_DESCRIPTION ""FROM TD.TEST ""WHERE TS_SUBJECT=%d ""ORDER BY TS_NAME",parent_td_node->subjectnode);query->SQL->Text = sql_statement;query->Open();// int count_test_scenarios = query->RecordCount;while (!query->Eof){AnsiString name = query->FieldByName("TS_NAME")->AsString;AnsiString description = query->FieldByName("TS_DESCRIPTION")->AsString;// unsigned int subject_id = query->FieldByName("TS_SUBJECT")->AsInteger;unsigned int test_id = query->FieldByName("TS_TEST_ID")->AsInteger;TestDirectorNode *td_node = new TestDirectorNode;TestDirectorNodes.push_back(td_node);td_node->nodetype = SCENARIO;td_node->name = name;td_node->subjectnode = test_id;td_node->text1 = description;TestDirectorNodePair_t pair(test_id, td_node);TestDirectorScenarioMap.insert( pair );td_node->parent = parent_td_node;parent_td_node->children.push_back( td_node );query->Next();} // whilequery->Close();}catch(...){}delete query;}void __fastcall TTestDirectorImportForm::LoadTestSteps(TestDirectorNode *parent_td_node){TADOQuery *query = NULL;AnsiString sql_statement;try{query = new TADOQuery(this);query->Connection = TestDirectorConnection;// Load the Test Scenario Stepssql_statement.sprintf("SELECT DS_TEST_ID,DS_STEP_NAME,DS_DESCRIPTION,DS_EXPECTED ""FROM TD.DESSTEPS ""WHERE DS_TEST_ID=%d ""ORDER BY DS_STEP_ORDER",parent_td_node->subjectnode);query->SQL->Text = sql_statement;query->Open();// int count_test_steps = query->RecordCount;while (!query->Eof){int step_test_id = query->FieldByName("DS_TEST_ID")->AsInteger;AnsiString step_name = query->FieldByName("DS_STEP_NAME")->AsString;AnsiString step_description = query->FieldByName("DS_DESCRIPTION")->AsString;AnsiString step_expected = query->FieldByName("DS_EXPECTED")->AsString;TestDirectorNode *td_node = new TestDirectorNode;TestDirectorNodes.push_back(td_node);td_node->nodetype = TESTSTEP;td_node->name = step_name;td_node->subjectnode = step_test_id;td_node->text1 = step_description;td_node->text2 = step_expected;td_node->parent = parent_td_node;parent_td_node->test_steps.push_back( td_node );query->Next();} // while}catch(...){}delete query;}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::FormShow(TObject *Sender){TCursor Save_Cursor = Screen->Cursor;Screen->Cursor = crHourGlass; // Show hourglass cursortry{AnsiString root_node_name;unsigned int root_node = 0;LoadTestDataScenarioData(root_node, root_node_name);TTreeNode *node = NULL;TestCaseTreeView->Items->Clear();node = TestCaseTreeView->Items->Add(NULL, root_node_name);node->ImageIndex = 0;node->SelectedIndex = 1;DrawSubTree(TestCaseTreeView, node, TESTCASE, root_node); // Start at the Subject Root}__finally{Screen->Cursor = Save_Cursor; // always restore the cursor}}//---------------------------------------------------------------------------void TTestDirectorImportForm::DrawSubTree(TTreeView *tree, TTreeNode *node, int nodetype, int parent_id){if (nodetype == TESTSTEP){TestDirectorNodeMap_t::iterator itr = TestDirectorScenarioMap.find( parent_id );if (itr != TestDirectorScenarioMap.end()){TestDirectorNode *scenario_node = (*itr).second;DrawScenarioSteps(scenario_node);}}else{TestDirectorNodeMap_t::iterator itr = TestDirectorNodeMap.find( parent_id );if (itr != TestDirectorNodeMap.end()){if ((*itr).second->children.size() > 0){TestDirectorNodeList_t::iterator child_itr = (*itr).second->children.begin();while (child_itr != (*itr).second->children.end()){TestDirectorNode *td_node = (*child_itr);if (td_node->nodetype == nodetype){switch(td_node->nodetype){case TESTCASE:{TTreeNode *subtree = tree->Items->AddChildObject(node, td_node->name, (TObject *)td_node);subtree->ImageIndex = 0;subtree->SelectedIndex = 1;DrawSubTree(tree, subtree, nodetype, td_node->subjectnode);}break;case SCENARIO:{/*TTreeNode *subtree =*/ tree->Items->AddChildObject(node, td_node->name, (TObject *)td_node);}break;} // switch}++child_itr;} // for}}}}//---------------------------------------------------------------------------void TTestDirectorImportForm::DrawScenarioSteps(TestDirectorNode *scenario_node){TTreeNode *node = NULL;TestStepTreeView->Items->Clear();node = TestStepTreeView->Items->Add(NULL, "Test Steps");node->ImageIndex = 0;node->SelectedIndex = 1;TestDirectorNodeList_t::iterator itr = scenario_node->test_steps.begin();while (itr != scenario_node->test_steps.end()){TestDirectorNode *td_node = (*itr);/*TTreeNode *step_node = */TestStepTreeView->Items->AddChildObject(node, td_node->name, (TObject *)td_node);++itr;}node->Expand(true);}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::TestCaseTreeViewChange(TObject *Sender, TTreeNode *Node){TCursor Save_Cursor = Screen->Cursor;Screen->Cursor = crHourGlass; // Show hourglass cursortry{TestCaseMemo->Clear();TestScenarioMemo->Clear();TestDirectorNode *td_node = (TestDirectorNode *)(Node->Data);if (td_node != NULL){TestScenarioPanel->Caption = td_node->name;TestCaseMemo->Lines->Text = td_node->text1;TestCaseMemo->WordWrap = wwRightMargin;TestCaseMemo->Update();if (td_node->children.size() == 0){LoadTestScenarios(td_node);}TTreeNode *node = NULL;TestScenarioTreeView->Items->Clear();TestStepTreeView->Items->Clear();node = TestScenarioTreeView->Items->Add(NULL, "Test Scenarios");node->ImageIndex = 0;node->SelectedIndex = 1;DrawSubTree(TestScenarioTreeView, node, SCENARIO, td_node->subjectnode);node->Expand(true);}}__finally{Screen->Cursor = Save_Cursor; // always restore the cursor}}//---------------------------------------------------------------------------AnsiString TTestDirectorImportForm::ProcessQuotedString(const AnsiString &source){AnsiString result;const char *p = source.c_str();for (int i=0; i<source.Length(); i++){if (*p == '\''){result += *p;}if (*p == '\"'){result += "''";}else{result += *p;}p++;}return result;}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::ImportFromTestDirector1Click(TObject *Sender){TADOQuery *query = NULL;TCursor Save_Cursor = Screen->Cursor;Screen->Cursor = crHourGlass; // Show hourglass cursortry{query = new TADOQuery(this);query->Connection = Data_Module->IntegrationDBConnection;Data_Module->IntegrationDBConnection->BeginTrans();for (unsigned i=0; i<TestCaseTreeView->SelectionCount; i++){TTreeNode *selected_node = TestCaseTreeView->Selections[i];AnsiString current_text_case_level;ProcessSubtree(TestCaseTreeView, selected_node, query, current_text_case_level);}// Process ChildrenTTreeNode *scenario_root_node = TestScenarioTreeView->TopItem;if (scenario_root_node != NULL){AnsiString current_text_case_level;ProcessSubtree(TestScenarioTreeView, scenario_root_node, query, current_text_case_level);}if (Data_Module->IntegrationDBConnection->InTransaction){Data_Module->IntegrationDBConnection->CommitTrans();}}__finally{delete query;if (Data_Module->IntegrationDBConnection->InTransaction){Data_Module->IntegrationDBConnection->RollbackTrans();}Screen->Cursor = Save_Cursor;}}//---------------------------------------------------------------------------void TTestDirectorImportForm::ProcessSubtree(TTreeView *treeview, TTreeNode *node, TADOQuery *query, AnsiString current_text_case_level){ProcessTDNode(node, query, current_text_case_level);// Process ChildrenTTreeNode *child_node = node->getFirstChild();if (child_node != NULL){do{ProcessSubtree(treeview, child_node, query, current_text_case_level);child_node = node->GetNextChild(child_node);} while (child_node != NULL);}}//---------------------------------------------------------------------------void TTestDirectorImportForm::ProcessTDNode(TTreeNode *selected_node, TADOQuery *query, AnsiString ¤t_text_case_level){AnsiString sql_statement;TestDirectorNode *td_node = (TestDirectorNode *)(selected_node->Data);if(td_node != NULL){switch(td_node->nodetype){case SUBJECT:// Do nothingbreak;case TESTCASE:{AnsiString usecase_id = td_node->name.SubString(1, td_node->name.Pos(" ")-1);if ( (!usecase_id.IsEmpty() && isTestCase( usecase_id )) ||!current_text_case_level.IsEmpty() ){AnsiString tc_name;if (!usecase_id.IsEmpty() && isTestCase( usecase_id )){tc_name = td_node->name.SubString(td_node->name.Pos(" ")+1, td_node->name.Length());current_text_case_level = usecase_id;sql_statement="";sql_statement.sprintf("SELECT NAME, DESCRIPTION FROM TESTCASES ""WHERE USECASE_ID='%s'",usecase_id.c_str());query->SQL->Text = sql_statement;query->Open();if (query->RecordCount == 0) // Test Case not found .. Insert it{sql_statement="";sql_statement.sprintf("INSERT INTO TESTCASES (USECASE_ID, NAME, TESTCASE_ID, DESCRIPTION) ""VALUES ('%s','%s','%s','%s')",usecase_id.c_str(),tc_name.c_str(),usecase_id.c_str(),ProcessQuotedString(td_node->text1).c_str());query->SQL->Text = sql_statement;query->ExecSQL();}else{// Existing Test Case found .. Update itAnsiString desc = ProcessQuotedString(td_node->text1);if ( (query->FieldByName("NAME")->AsString != tc_name) ||(query->FieldByName("DESCRIPTION")->AsString != desc) ){sql_statement="";sql_statement.sprintf("UPDATE TESTCASES SET NAME='%s',DESCRIPTION='%s' ""WHERE USECASE_ID='%s'",tc_name.c_str(),desc.c_str(),usecase_id.c_str());query->SQL->Text = sql_statement;query->ExecSQL();}}}}}break;case SCENARIO:{TestDirectorNode *testcase_node = (TestDirectorNode *)(td_node->parent);TestDirectorNode *parent_testcase_node = (TestDirectorNode *)(td_node->parent->parent);AnsiString usecase_id = testcase_node->name.SubString(1, testcase_node->name.Pos(" ")-1);AnsiString parent_usecase_id = parent_testcase_node->name.SubString(1, parent_testcase_node->name.Pos(" ")-1);if ( (!usecase_id.IsEmpty() && isTestCase( usecase_id )) ||(!parent_usecase_id.IsEmpty() && isTestCase( parent_usecase_id )) ){AnsiString tc_id = td_node->name.SubString(1, td_node->name.Pos(" ")-1);AnsiString tc_name = td_node->name.SubString(td_node->name.Pos(" ")+1, td_node->name.Length());current_text_case_level = tc_id;const char *p = tc_id.c_str();AnsiString tc_scenario_seqno;// Skip to '.'while ( (*p != '.') && (*p != '\0') ){p++;}if (*p == '.'){p++;while ( (*p != '.') && (*p != '\0') ){tc_scenario_seqno += *p;p++;}}if ( (usecase_id.IsEmpty() || !isTestCase( usecase_id )) ){usecase_id = parent_usecase_id;}// Do we already have a matching TEST_SCENARIOS (examine Project,Iteration,TestCase_ID and Name) ?sql_statement="";sql_statement.sprintf("SELECT TESTCASE_SEQNO FROM TEST_SCENARIOS ""WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTCASE_ID='%s' AND NAME='%s'",m_project.c_str(),m_iteration,usecase_id.c_str(),tc_name.c_str());query->SQL->Text = sql_statement;query->Open();if (query->RecordCount == 0) // Scenario not found{int next_testcase_seqno = 0;if (tc_scenario_seqno.IsEmpty()){sql_statement="";sql_statement.sprintf("SELECT MAX(TESTCASE_SEQNO) MAX_SEQNO FROM TEST_SCENARIOS ""WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTCASE_ID='%s'",m_project.c_str(),m_iteration,usecase_id.c_str());query->SQL->Text = sql_statement;query->Open();next_testcase_seqno = query->FieldByName("MAX_SEQNO")->AsInteger;next_testcase_seqno++;}else{next_testcase_seqno = atoi(tc_scenario_seqno.c_str());}sql_statement="";sql_statement.sprintf("INSERT INTO TEST_SCENARIOS (PROJECT_CODE,ITERATION,TESTCASE_ID,USECASE,NAME,DESCRIPTION,TESTCASE_SEQNO) ""VALUES ('%s',%d,'%s','%s','%s','%s',%d)",m_project.c_str(),m_iteration,usecase_id.c_str(),usecase_id.c_str(),tc_name.c_str(),ProcessQuotedString(td_node->text1).c_str(),next_testcase_seqno);query->SQL->Text = sql_statement;query->ExecSQL();}else{int next_testcase_seqno = 0;if (tc_scenario_seqno.IsEmpty()){next_testcase_seqno = query->FieldByName("TESTCASE_SEQNO")->AsInteger;}else{next_testcase_seqno = atoi(tc_scenario_seqno.c_str());}sql_statement="";sql_statement.sprintf("UPDATE TEST_SCENARIOS SET DESCRIPTION='%s',TESTCASE_SEQNO=%d ""WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTCASE_ID='%s' AND NAME='%s'",ProcessQuotedString(td_node->text1).c_str(),next_testcase_seqno,m_project.c_str(),m_iteration,usecase_id.c_str(),tc_name.c_str());query->SQL->Text = sql_statement;query->ExecSQL();}}}break;case TESTSTEP:{TestDirectorNode *testcase_node = (TestDirectorNode *)(selected_node->Parent->Parent->Data);AnsiString usecase_id = testcase_node->name.SubString(1, testcase_node->name.Pos(" ")-1);TestDirectorNode *ts_node = (TestDirectorNode *)(selected_node->Parent->Data);if ( !usecase_id.IsEmpty() && isTestCase( usecase_id ) ){AnsiString ts_name = ts_node->name.SubString(ts_node->name.Pos(" ")+1, ts_node->name.Length());sql_statement="";sql_statement.sprintf("SELECT TESTSCENARIO_NO FROM TEST_SCENARIOS ""WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTCASE_ID='%s' AND NAME='%s'",m_project.c_str(),m_iteration,usecase_id.c_str(),ts_name.c_str());query->SQL->Text = sql_statement;query->Open();if (query->RecordCount == 1){int testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger;sql_statement="";sql_statement.sprintf("DELETE FROM TXNSPEC_STEPS WHERE TESTSCENARIO_NO=%d AND NAME='%s'",testscenario_no,td_node->name.c_str());query->SQL->Text = sql_statement;query->ExecSQL();sql_statement="";sql_statement.sprintf("INSERT INTO TXNSPEC_STEPS (TESTSCENARIO_NO,NAME,DESCRIPTION,EXPECTED_RESULT) ""VALUES (%d,'%s','%s','%s')",testscenario_no,td_node->name.c_str(),ProcessQuotedString(td_node->text1).c_str(),ProcessQuotedString(td_node->text2).c_str());query->SQL->Text = sql_statement;query->ExecSQL();}}}break;} // switch}}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::TestScenarioTreeViewChange(TObject *Sender, TTreeNode *Node){TCursor Save_Cursor = Screen->Cursor;Screen->Cursor = crHourGlass; // Show hourglass cursortry{TestStepMemo->Clear();TestStepOutcomeMemo->Clear();TestScenarioMemo->Clear();TestDirectorNode *td_node = (TestDirectorNode *)(Node->Data);if (td_node != NULL){TestStepPanel->Caption = td_node->name;TestScenarioMemo->Lines->Text = td_node->text1;TestScenarioMemo->WordWrap = wwRightMargin;TestScenarioMemo->Update();if (td_node->test_steps.size() == 0){LoadTestSteps(td_node);}TTreeNode *node = NULL;TestStepTreeView->Items->Clear();node = TestStepTreeView->Items->Add(NULL, "Test Steps");node->ImageIndex = 0;node->SelectedIndex = 1;DrawSubTree(TestStepTreeView, node, TESTSTEP, td_node->subjectnode);node->Expand(true);}}__finally{Screen->Cursor = Save_Cursor; // always restore the cursor}}//---------------------------------------------------------------------------void __fastcall TTestDirectorImportForm::TestStepTreeViewChange(TObject *Sender, TTreeNode *Node){TCursor Save_Cursor = Screen->Cursor;Screen->Cursor = crHourGlass; // Show hourglass cursortry{TestStepMemo->Clear();TestStepOutcomeMemo->Clear();TestDirectorNode *td_node = (TestDirectorNode *)(Node->Data);if (td_node != NULL){TestStepMemo->Lines->Text = td_node->text1;TestStepMemo->WordWrap = wwRightMargin;TestStepMemo->Update();TestStepOutcomeMemo->Lines->Text = td_node->text2;TestStepOutcomeMemo->WordWrap = wwRightMargin;TestStepOutcomeMemo->Update();}}__finally{Screen->Cursor = Save_Cursor; // always restore the cursor}}//---------------------------------------------------------------------------