diff --git a/test/UnitTest/SourceControl/Git/AbstractTest.cls b/test/UnitTest/SourceControl/Git/AbstractTest.cls new file mode 100644 index 00000000..5fa1e1f2 --- /dev/null +++ b/test/UnitTest/SourceControl/Git/AbstractTest.cls @@ -0,0 +1,40 @@ +Class UnitTest.SourceControl.Git.AbstractTest Extends %UnitTest.TestCase +{ + +Property InitialExtension As %String [ InitialExpression = {##class(%Studio.SourceControl.Interface).SourceControlClassGet()} ]; + +Property SourceControlGlobal [ MultiDimensional ]; + +Method %OnNew(initvalue) As %Status +{ + Merge ..SourceControlGlobal = ^SYS("SourceControl") + Kill ^SYS("SourceControl") + Set settings = ##class(SourceControl.Git.Settings).%New() + Set settings.namespaceTemp = ##class(%Library.File).TempFilename()_"dir" + Set settings.Mappings("CLS","*")="cls/" + Do settings.%Save() + Do ##class(%Studio.SourceControl.Interface).SourceControlClassSet("SourceControl.Git.Extension") + Quit ##super(initvalue) +} + +Method %OnClose() As %Status [ Private, ServerOnly = 1 ] +{ + Do ##class(%Studio.SourceControl.Interface).SourceControlClassSet(..InitialExtension) + Kill ^SYS("SourceControl") + Merge ^SYS("SourceControl") = ..SourceControlGlobal + Quit $$$OK +} + +ClassMethod WriteFile(filePath, contents) +{ + set dirPath = ##class(%File).GetDirectory(filePath) + if '##class(%File).CreateDirectoryChain(dirPath,.ret) { + $$$ThrowStatus($$$ERROR($$$GeneralError,"failed to create directory: "_ret)) + } + set fileStream = ##class(%Stream.FileCharacter).%OpenId(filePath,,.sc) + $$$ThrowOnError(sc) + do fileStream.Write(contents) + $$$ThrowOnError(fileStream.%Save()) +} + +} diff --git a/test/UnitTest/SourceControl/Git/Pull.cls b/test/UnitTest/SourceControl/Git/Pull.cls new file mode 100644 index 00000000..762a1631 --- /dev/null +++ b/test/UnitTest/SourceControl/Git/Pull.cls @@ -0,0 +1,40 @@ +Class UnitTest.SourceControl.Git.Pull Extends UnitTest.SourceControl.Git.AbstractTest +{ + +Method TestPull() +{ + // initialize remote repository on filesystem + set remoteDir = ##class(%Library.File).TempFilename()_"d" + if '##class(%File).CreateDirectoryChain(remoteDir_"/cls",.ret) { + $$$ThrowStatus($$$ERROR($$$GeneralError,"failed to create directory: "_ret)) + } + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass1.cls","Class TestGit.SampleClass1 {}") + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass2.cls","Class TestGit.SampleClass2 {}") + do $zf(-100,"/SHELL","git","init",remoteDir) + do $zf(-100,"/SHELL","git", "-C", remoteDir, "config", "user.email", "unittest@example.com") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "config", "user.name", "Unit Test") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "add", ".") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "commit", "-m", "initial commit in remote for unit test") + // initialize local repo, cloning remote. + $$$ThrowOnError(##class(SourceControl.Git.Utils).Clone(remoteDir_"/.git")) + // import all and confirm classes exist + do $System.OBJ.Delete("TestGit.SampleClass1,TestGit.SampleClass2") + $$$ThrowOnError(##class(SourceControl.Git.Utils).ImportAll(1)) + do $$$AssertTrue($$$comClassDefined("TestGit.SampleClass1")) + do $$$AssertTrue($$$comClassDefined("TestGit.SampleClass2")) + // delete, add, and modify classes on remote. add and commit them all on remote. + if '##class(%File).Delete(remoteDir_"/cls/TestGit/SampleClass1.cls",.ret) { + $$$ThrowStatus($$$ERROR($$$GeneralError,"failed to delete class file")) + } + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass2.cls","Class TestGit.SampleClass2 { Parameter foo = ""bar""; }") + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass3.cls","Class TestGit.SampleClass3 {}") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "add", ".") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "commit", "-m", "delete, modify, and add classes on remote") + // pull on local and confirm changes were loaded. + $$$ThrowOnError(##class(SourceControl.Git.API).Pull()) + do $$$AssertNotTrue($$$comClassDefined("TestGit.SampleClass1")) + do $$$AssertEquals(##class(TestGit.SampleClass2).#foo, "bar") + do $$$AssertTrue($$$comClassDefined("TestGit.SampleClass3")) +} + +} diff --git a/test/UnitTest/SourceControl/Git/Sync.cls b/test/UnitTest/SourceControl/Git/Sync.cls new file mode 100644 index 00000000..9464d5ee --- /dev/null +++ b/test/UnitTest/SourceControl/Git/Sync.cls @@ -0,0 +1,53 @@ +Class UnitTest.SourceControl.Git.Sync Extends UnitTest.SourceControl.Git.AbstractTest +{ + +Method TestSync() +{ + do $$$LogMessage("set up remote repo on filesystem") + set remoteDir = ##class(%Library.File).TempFilename()_"d" + if '##class(%File).CreateDirectoryChain(remoteDir,.ret) { + $$$ThrowStatus($$$ERROR($$$GeneralError,"failed to create directory: "_ret)) + } + do $zf(-100,"/SHELL","git","init",remoteDir) + do $zf(-100,"/SHELL","git", "-C", remoteDir, "config", "user.email", "unittest@example.com") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "config", "user.name", "Unit Test") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "checkout", "-b", "live") + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass1.cls","Class TestGit.SampleClass1 {}") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "add", ".") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "commit", "-m", "initial commit in remote for unit test") + do $$$LogMessage("initialize local repo cloning remote") + $$$ThrowOnError(##class(SourceControl.Git.Utils).Clone(remoteDir_"/.git")) + do $$$LogMessage("set default merge branch to live and enable basic mode") + set settings = ##class(SourceControl.Git.Settings).%New() + set settings.defaultMergeBranch = "live" + set settings.basicMode = "system" + set settings.systemBasicMode = 1 + $$$ThrowOnError(settings.%Save()) + do $$$LogMessage("check out live branch on local") + $$$ThrowOnError(##class(SourceControl.Git.Utils).SwitchBranch("live")) + do $$$LogMessage("create a class through IRIS, add it to source control, and sync") + do $System.OBJ.Delete("TestGit.SampleClass2") + set classDef = ##class(%Dictionary.ClassDefinition).%New("TestGit.SampleClass2") + $$$ThrowOnError(classDef.%Save()) + $$$ThrowOnError($System.OBJ.Compile("TestGit.SampleClass2")) + $$$ThrowOnError(##class(SourceControl.Git.Utils).AddToSourceControl("TestGit.SampleClass2.cls")) + $$$ThrowOnError(##class(SourceControl.Git.Utils).Sync("should not commit")) + do $$$LogMessage("sync should NOT have committed the new file since we are on the live branch.") + do $$$AssertTrue(##class(SourceControl.Git.Change).IsUncommitted(##class(SourceControl.Git.Utils).FullExternalName("TestGit.SampleClass2.cls"))) + do $$$LogMessage("now, check out an interface branch") + $$$ThrowOnError(##class(SourceControl.Git.Utils).NewBranch("interface")) + do $$$LogMessage("simulate another developer's change going live") + do ..WriteFile(remoteDir_"/cls/TestGit/SampleClass1.cls","Class TestGit.SampleClass1 { Parameter foo = ""bar""; }") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "add", ".") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "commit", "-m", "initial commit in remote for unit test") + do $$$LogMessage("check out an interface branch and sync") + $$$ThrowOnError(##class(SourceControl.Git.Utils).Sync("should commit")) + do $$$LogMessage("sync should have rebased the other developer's change, and committed the new file.") + do $$$AssertEquals(##class(TestGit.SampleClass1).#foo, "bar") + do $$$AssertNotTrue(##class(SourceControl.Git.Change).IsUncommitted(##class(SourceControl.Git.Utils).FullExternalName("TestGit.SampleClass2.cls"))) + do $$$LogMessage("simulate a merge request on the remote from the interface branch to live.") + do $zf(-100,"/SHELL","git", "-C", remoteDir, "merge", "interface") + do $$$AssertTrue(##class(%File).Exists(remoteDir_"/cls/TestGit/SampleClass2.cls")) +} + +}