test(parser/diff): add myers diff test
This commit is contained in:
		
							parent
							
								
									60d9e1b215
								
							
						
					
					
						commit
						b8c233b1bb
					
				
							
								
								
									
										69
									
								
								internal/parser/diff/diff_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								internal/parser/diff/diff_test.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | ||||||
|  | package diff | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestMyersDiff(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name         string | ||||||
|  | 		src          []string | ||||||
|  | 		dst          []string | ||||||
|  | 		compareSpace bool | ||||||
|  | 		expected     []operation | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name:         "Insert operation", | ||||||
|  | 			src:          []string{"a", "b"}, | ||||||
|  | 			dst:          []string{"a", "b", "c"}, | ||||||
|  | 			compareSpace: true, | ||||||
|  | 			expected:     []operation{MOVE, MOVE, INSERT}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Delete operation", | ||||||
|  | 			src:          []string{"a", "b", "c"}, | ||||||
|  | 			dst:          []string{"a", "b"}, | ||||||
|  | 			compareSpace: true, | ||||||
|  | 			expected:     []operation{MOVE, MOVE, DELETE}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "No changes", | ||||||
|  | 			src:          []string{"a", "b", "c"}, | ||||||
|  | 			dst:          []string{"a", "b", "c"}, | ||||||
|  | 			compareSpace: true, | ||||||
|  | 			expected:     []operation{MOVE, MOVE, MOVE}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Move operation", | ||||||
|  | 			src:          []string{"a", "b", "c"}, | ||||||
|  | 			dst:          []string{"c", "a", "b"}, | ||||||
|  | 			compareSpace: true, | ||||||
|  | 			expected:     []operation{INSERT, MOVE, MOVE, DELETE}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Ignore whitespace differences", | ||||||
|  | 			src:          []string{"a ", "b"}, | ||||||
|  | 			dst:          []string{"a", "b"}, | ||||||
|  | 			compareSpace: false, | ||||||
|  | 			expected:     []operation{MOVE, MOVE}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			name:         "Consider whitespace differences", | ||||||
|  | 			src:          []string{"a ", "b"}, | ||||||
|  | 			dst:          []string{"a", "b"}, | ||||||
|  | 			compareSpace: true, | ||||||
|  | 			expected:     []operation{DELETE, INSERT, MOVE}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, test := range tests { | ||||||
|  | 		t.Run(test.name, func(t *testing.T) { | ||||||
|  | 			result := myersDiff(test.src, test.dst, test.compareSpace) | ||||||
|  | 			if !reflect.DeepEqual(result, test.expected) { | ||||||
|  | 				t.Errorf("myersDiff(%v, %v, %v) = %v; want %v", | ||||||
|  | 					test.src, test.dst, test.compareSpace, result, test.expected) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -64,7 +64,7 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 				"actual length", len(result.Files[output.FileName]), | 				"actual length", len(result.Files[output.FileName]), | ||||||
| 				"answer length", len(string(answer))) | 				"answer length", len(string(answer))) | ||||||
| 			// If no difference, assign score
 | 			// If no difference, assign score
 | ||||||
| 			if compareChars(string(answer), result.Files[output.FileName], | 			if compareStrings(string(answer), result.Files[output.FileName], | ||||||
| 				output.CompareSpace) { | 				output.CompareSpace) { | ||||||
| 				score += output.Score | 				score += output.Score | ||||||
| 				comment += conf.PassComment | 				comment += conf.PassComment | ||||||
|  | @ -82,7 +82,8 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 						result.Files[output.FileName], "\n") | 						result.Files[output.FileName], "\n") | ||||||
| 
 | 
 | ||||||
| 					// Generate Myers diff
 | 					// Generate Myers diff
 | ||||||
| 					diffOps := myersDiff(stdoutLines, resultLines) | 					diffOps := myersDiff(stdoutLines, resultLines, | ||||||
|  | 						output.CompareSpace) | ||||||
| 					if output.MaxDiffLength == 0 { // real default value
 | 					if output.MaxDiffLength == 0 { // real default value
 | ||||||
| 						output.MaxDiffLength = 2048 | 						output.MaxDiffLength = 2048 | ||||||
| 					} | 					} | ||||||
|  | @ -108,13 +109,13 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 	return res, forceQuit, nil | 	return res, forceQuit, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // compareChars compares two strings character by character, optionally ignoring whitespace.
 | // compareStrings compares two strings character by character, optionally ignoring whitespace.
 | ||||||
| func compareChars(stdout, result string, compareSpace bool) bool { | func compareStrings(str1, str2 string, compareSpace bool) bool { | ||||||
| 	if !compareSpace { | 	if !compareSpace { | ||||||
| 		stdout = removeSpace(stdout) | 		str1 = removeSpace(str1) | ||||||
| 		result = removeSpace(result) | 		str2 = removeSpace(str2) | ||||||
| 	} | 	} | ||||||
| 	return stdout == result | 	return str1 == str2 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // removeSpace removes all whitespace characters from the string.
 | // removeSpace removes all whitespace characters from the string.
 | ||||||
|  | @ -130,7 +131,7 @@ func removeSpace(s string) string { | ||||||
| 
 | 
 | ||||||
| // myersDiff computes the Myers' diff between two slices of strings.
 | // myersDiff computes the Myers' diff between two slices of strings.
 | ||||||
| // src: https://github.com/cj1128/myers-diff/blob/master/main.go
 | // src: https://github.com/cj1128/myers-diff/blob/master/main.go
 | ||||||
| func myersDiff(src, dst []string) []operation { | func myersDiff(src, dst []string, compareSpace bool) []operation { | ||||||
| 	n := len(src) | 	n := len(src) | ||||||
| 	m := len(dst) | 	m := len(dst) | ||||||
| 	max := n + m | 	max := n + m | ||||||
|  | @ -144,7 +145,9 @@ loop: | ||||||
| 
 | 
 | ||||||
| 		if d == 0 { | 		if d == 0 { | ||||||
| 			t := 0 | 			t := 0 | ||||||
| 			for len(src) > t && len(dst) > t && src[t] == dst[t] { | 			for len(src) > t && | ||||||
|  | 				len(dst) > t && | ||||||
|  | 				compareStrings(src[t], dst[t], compareSpace) { | ||||||
| 				t += 1 | 				t += 1 | ||||||
| 			} | 			} | ||||||
| 			v[0] = t | 			v[0] = t | ||||||
|  | @ -165,7 +168,7 @@ loop: | ||||||
| 
 | 
 | ||||||
| 			y = x - k | 			y = x - k | ||||||
| 
 | 
 | ||||||
| 			for x < n && y < m && src[x] == dst[y] { | 			for x < n && y < m && compareStrings(src[x], dst[y], compareSpace) { | ||||||
| 				x, y = x+1, y+1 | 				x, y = x+1, y+1 | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user