Skip to content

Commit

Permalink
Changed the way we match mappings in NameToInternalName, modified and…
Browse files Browse the repository at this point in the history
… added new testcases (#199)

* Changed the way we match mappings in NameToInternalName, modified and added tests.

* Verbose output when getting the InternalName in AddToSourceControl

* Add more negative test cases to the unit test

Co-authored-by: Sarmishta Velury <isc-svelury@users.noreply.github.com>
  • Loading branch information
isc-svelury and isc-svelury authored Jun 2, 2022
1 parent 6027043 commit 31c652e
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 25 deletions.
82 changes: 73 additions & 9 deletions cls/SourceControl/Git/Utils.cls
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ ClassMethod AddToSourceControl(InternalName As %String) As %Status
set ec = $$$ADDSC(ec, sc)
}
for i=1:1:filenames{
set FileInternalName = ##class(SourceControl.Git.Utils).NormalizeExtension(##class(SourceControl.Git.Utils).NameToInternalName(filenames(i), 0))
set FileInternalName = ##class(SourceControl.Git.Utils).NormalizeExtension(##class(SourceControl.Git.Utils).NameToInternalName(filenames(i), 0,,1))
set FileType = ##class(SourceControl.Git.Utils).Type(FileInternalName)

set @..#Storage@("items", FileInternalName) = ""
Expand Down Expand Up @@ -1530,7 +1530,7 @@ ClassMethod Name(InternalName As %String, ByRef MappingExists As %Boolean) As %S
NameToInternalName(name): given a Unix-style slash path relative to repo root,
returns the internal name for that file (e.g., cls/SourceControl/Git/Utils.cls -> SourceControl.Git.Utils.CLS)
*/
ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) As %String
ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1, Verbose As %Boolean = 0) As %String
{
set InternalName=""
set Deleted = 0
Expand All @@ -1556,21 +1556,73 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
if (InternalName="") {
set name=$extract(Name,$length($$$SourceRoot)+1,*)
set name=$replace(name,"\","/") // standardize slash direction
//file is in a subdirectory under the ^Sources root

set nam = name

set queryary=$query($$$SourceMapping(""),-1,dir), mappingsSubscript = $qsubscript(queryary,4), subscript=$qsubscript(queryary,5)
set queryary=$query($$$SourceMapping(""),-1,dir), mappingsSubscript = $qsubscript(queryary,4)
set subscript=$qsubscript(queryary,5), coverage = $qsubscript(queryary, 6)
set bestMatch = $lb(subscript, coverage, dir)
set bestScore = 0
set currScore = 0
while (queryary'="")&&(mappingsSubscript="mappings") {
if (dir["/")&&(dir=$extract(name, 1, $length(dir))) {
set ext=subscript
set nam = $extract(name, $length(dir)+1, *)
quit
set nam = $extract(name, $length(dir)+1, *)
if ($zconvert(subscript, "U") = $zconvert($piece(name, ".", *), "U")){
set extScore = 1
} else {
set extScore = 0
}

if ((dir["/")&&(dir=$extract(name, 1, $length(dir)))){
set pathScore = 1
} else {
set pathScore = 0
}

if (coverage = "*"){
set covScore = 1
} elseif ($extract($translate(nam, "/", "."), 1, ($length(coverage)+1)) = (coverage_".")) {
set covScore = 2
} else {
set covScore = 0
}

set currScore = (extScore*100) + (pathScore*10) + covScore

if (currScore > bestScore){
set bestScore = currScore
set bestMatch = $lb(subscript, coverage, dir)
} elseif ((currScore = bestScore) && currScore>=111) {
// There are 4 cases here -
// 1. Coverage is more specific in one and Path is the same.
// 2. Path is more specific in one and Coverage is the same.
// 3. Coverage is more specific in one while Path is more specific in the other.
// 4. Both are more specific in one.
// Coverage has higher priority.
// Note that a file extension has no notion of specificity.
// Specificity, for both Coverage and Path, is defined as being directly proportional to the length of the string.

set covSpecific = 0, pathSpecific = 0

if ($length(coverage) > $length($listget(bestMatch, 2))){
set bestMatch = $lb(subscript, coverage, dir)
} elseif ($length(coverage) = $length($listget(bestMatch, 2))){
if ($length(dir) > $length($listget(bestMatch, 3))){
set bestMatch = $lb(subscript, coverage, dir)
}
}
}

set queryary=$query(@queryary,-1,dir)
if (queryary="") {
quit
}
set mappingsSubscript = $qsubscript(queryary,4), subscript=$qsubscript(queryary,5)
set mappingsSubscript = $qsubscript(queryary,4), subscript=$qsubscript(queryary,5), coverage = $qsubscript(queryary, 6)
}

if (bestScore >= 111){
set ext = $listget(bestMatch,1)
set dir = $listget(bestMatch, 3)
set nam = $extract(name, $length(dir)+1, *)
}

if ($get(ext)="/CSP/") {
Expand All @@ -1595,6 +1647,18 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
}
}
if $data(ext)=0 {
if (Verbose){
write !
if (bestScore#100 = 0){
write !, "No mapping with a matching coverage found for file "_name
}
if (((bestScore\10)#10) = 0){
write !, "No mapping with a matching path found for file "_name
}
if ((bestScore\100) = 0){
write !, "No mapping with a matching extension found for file "_name
}
}
quit ""
}
set fileExt=$zconvert(ext,"L")
Expand Down
57 changes: 41 additions & 16 deletions test/UnitTest/SourceControl/Git/NameToInternalNameTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,66 @@ Property OldNamespaceTemp As %String;
Method TestRegularClassNames()
{
// Regular class that exists
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\Utils.cls"),"SourceControl.Git.Utils.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\SourceControl\Git\Utils.cls"),"SourceControl.Git.Utils.CLS")
// Regular class that doesn't exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls"),"")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls"),"")
// Regular class that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls", 1, 0),"SourceControl.Git.DoesNotExist.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls", 1, 0),"SourceControl.Git.DoesNotExist.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("test\UnitTest\Git\DoesNotExist.cls", 1, 0),"UnitTest.Git.DoesNotExist.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("foo\UnitTest\Foo\Git\DoesNotExist.cls", 1, 0),"UnitTest.Foo.Git.DoesNotExist.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("foo\UnitTest\Foo\Git\DoesNotExist.foo", 1, 0),"UnitTest.Foo.Git.DoesNotExist.FOO")
}

Method TestPercentClassNames()
{
// % class that exists but we ignore % classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\Base.cls"),"")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\Base.cls"),"")
// % class that exists and we don't ignore % classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\Base.cls", 0),"%Studio.Extension.Base.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\Base.cls", 0),"%Studio.Extension.Base.CLS")
// % class that doesn't exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\DoesNotExist.cls", 0),"")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\DoesNotExist.cls", 0),"")
// % class that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\DoesNotExist.cls", 0, 0),"%Studio.Extension.DoesNotExist.CLS")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("cls\"_##class(SourceControl.Git.Utils).PercentClassReplace()_"Studio\Extension\DoesNotExist.cls", 0, 0),"%Studio.Extension.DoesNotExist.CLS")
}

Method TestAbstractDocumentClassNames()
{
// %Studio.AbstractDocument type that exists
do ##class(%RoutineMgr).Delete("test2.pivot.DFI")
do $$$AssertEquals(##class(Utils).NameToInternalName("test\_resources\dfi\test2.pivot.dfi"),"")
do $$$AssertStatusOK(##class(Utils).ImportItem("test2.pivot.DFI",1))
do $$$AssertEquals(##class(Utils).NameToInternalName("test\_resources\dfi\test2.pivot.dfi"),"test2.pivot.DFI")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("test\_resources\dfi\test2.pivot.dfi"),"")
do $$$AssertStatusOK(##class(SourceControl.Git.Utils).ImportItem("test2.pivot.DFI",1))
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("test\_resources\dfi\test2.pivot.dfi"),"test2.pivot.DFI")
// %Studio.AbstractDocument type that does not exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("test\_resources\dfi\DoesNotExist.dfi"),"")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("test\_resources\dfi\DoesNotExist.dfi"),"")
// %Studio.AbstractDocument type that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("test\_resources\dfi\DoesNotExist.dfi", 1, 0),"DoesNotExist.DFI")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("test\_resources\dfi\DoesNotExist.dfi", 1, 0),"DoesNotExist.DFI")
}

Method TestStaticFileNames()
{
// Static file that shouldn't be on the server
do $$$AssertEquals(##class(Utils).NameToInternalName("git-webui\src\js\git-webui.js"),"")
// Static file that shouldn't be on the server but we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("git-webui\src\js\git-webui.js", 1, 0),"")
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("git-webui\src\js\git-webui.js"),"")
// Static file that shouldn't be on the server but we don't ignore non-existent classes (000 composite score)
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("git-webui\src\js\git-webui.js", 1, 0, 1),"")
}

Method TestNegative()
{
// Based on composite scores

// 000 is covered in TestStaticFileNames()
// 001 and 002
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("barq\MyBarFile1.barq", 1, 0, 1),"")
// 010
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("bar\NotMyBarFile1.barq", 1, 0, 1),"")
// 011 and 012
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("bar\MyBarFile1.barq", 1, 0, 1),"")
// 100
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("barq\NotMyBarFile1.bar", 1, 0, 1),"")
// 101 and 102
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("barq\MyBarFile1.bar", 1, 0, 1),"")
// 110
do $$$AssertEquals(##class(SourceControl.Git.Utils).NameToInternalName("bar\NotMyBarFile1.bar", 1, 0, 1),"")
}

Method OnBeforeAllTests() As %Status
Expand All @@ -61,6 +83,10 @@ Method OnBeforeAllTests() As %Status
merge ..Mappings = @##class(SourceControl.Git.Utils).MappingsNode()
kill @##class(SourceControl.Git.Utils).MappingsNode()
set $$$SourceMapping("CLS", "*") = "cls/"
set $$$SourceMapping("CLS", "UnitTest") = "test/"
set $$$SourceMapping("CLS", "UnitTest.Foo") = "foo/"
set $$$SourceMapping("FOO", "*") = "foo/"
set $$$SourceMapping("BAR", "MyBarFile") = "bar/"
set $$$SourceMapping("DFI", "*", "NoFolders") = 1
set $$$SourceMapping("DFI", "*") = "test/_resources/dfi/"
quit $$$OK
Expand All @@ -77,4 +103,3 @@ Method %OnClose() As %Status
}

}

0 comments on commit 31c652e

Please sign in to comment.