1// Copyright 2007-2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#ifdef ENABLE_DEBUGGER_SUPPORT 29 30#include <stdlib.h> 31 32#include "v8.h" 33 34#include "liveedit.h" 35#include "cctest.h" 36 37 38using namespace v8::internal; 39 40// Anonymous namespace. 41namespace { 42 43class StringCompareInput : public Comparator::Input { 44 public: 45 StringCompareInput(const char* s1, const char* s2) : s1_(s1), s2_(s2) { 46 } 47 int GetLength1() { 48 return StrLength(s1_); 49 } 50 int GetLength2() { 51 return StrLength(s2_); 52 } 53 bool Equals(int index1, int index2) { 54 return s1_[index1] == s2_[index2]; 55 } 56 57 private: 58 const char* s1_; 59 const char* s2_; 60}; 61 62 63class DiffChunkStruct : public ZoneObject { 64 public: 65 DiffChunkStruct(int pos1_param, int pos2_param, 66 int len1_param, int len2_param) 67 : pos1(pos1_param), pos2(pos2_param), 68 len1(len1_param), len2(len2_param), next(NULL) {} 69 int pos1; 70 int pos2; 71 int len1; 72 int len2; 73 DiffChunkStruct* next; 74}; 75 76 77class ListDiffOutputWriter : public Comparator::Output { 78 public: 79 explicit ListDiffOutputWriter(DiffChunkStruct** next_chunk_pointer) 80 : next_chunk_pointer_(next_chunk_pointer) { 81 (*next_chunk_pointer_) = NULL; 82 } 83 void AddChunk(int pos1, int pos2, int len1, int len2) { 84 current_chunk_ = new DiffChunkStruct(pos1, pos2, len1, len2); 85 (*next_chunk_pointer_) = current_chunk_; 86 next_chunk_pointer_ = ¤t_chunk_->next; 87 } 88 private: 89 DiffChunkStruct** next_chunk_pointer_; 90 DiffChunkStruct* current_chunk_; 91}; 92 93 94void CompareStringsOneWay(const char* s1, const char* s2, 95 int expected_diff_parameter = -1) { 96 StringCompareInput input(s1, s2); 97 98 ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT); 99 100 DiffChunkStruct* first_chunk; 101 ListDiffOutputWriter writer(&first_chunk); 102 103 Comparator::CalculateDifference(&input, &writer); 104 105 int len1 = StrLength(s1); 106 int len2 = StrLength(s2); 107 108 int pos1 = 0; 109 int pos2 = 0; 110 111 int diff_parameter = 0; 112 113 for (DiffChunkStruct* chunk = first_chunk; 114 chunk != NULL; 115 chunk = chunk->next) { 116 int diff_pos1 = chunk->pos1; 117 int similar_part_length = diff_pos1 - pos1; 118 int diff_pos2 = pos2 + similar_part_length; 119 120 ASSERT_EQ(diff_pos2, chunk->pos2); 121 122 for (int j = 0; j < similar_part_length; j++) { 123 ASSERT(pos1 + j < len1); 124 ASSERT(pos2 + j < len2); 125 ASSERT_EQ(s1[pos1 + j], s2[pos2 + j]); 126 } 127 diff_parameter += chunk->len1 + chunk->len2; 128 pos1 = diff_pos1 + chunk->len1; 129 pos2 = diff_pos2 + chunk->len2; 130 } 131 { 132 // After last chunk. 133 int similar_part_length = len1 - pos1; 134 ASSERT_EQ(similar_part_length, len2 - pos2); 135 USE(len2); 136 for (int j = 0; j < similar_part_length; j++) { 137 ASSERT(pos1 + j < len1); 138 ASSERT(pos2 + j < len2); 139 ASSERT_EQ(s1[pos1 + j], s2[pos2 + j]); 140 } 141 } 142 143 if (expected_diff_parameter != -1) { 144 ASSERT_EQ(expected_diff_parameter, diff_parameter); 145 } 146} 147 148 149void CompareStrings(const char* s1, const char* s2, 150 int expected_diff_parameter = -1) { 151 CompareStringsOneWay(s1, s2, expected_diff_parameter); 152 CompareStringsOneWay(s2, s1, expected_diff_parameter); 153} 154 155} // Anonymous namespace. 156 157 158// --- T h e A c t u a l T e s t s 159 160TEST(LiveEditDiffer) { 161 v8::internal::V8::Initialize(NULL); 162 CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6); 163 CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9); 164 CompareStrings("123456789", "987654321", 16); 165 CompareStrings("zzz", "yyy", 6); 166 CompareStrings("zzz", "zzz12", 2); 167 CompareStrings("zzz", "21zzz", 2); 168 CompareStrings("cat", "cut", 2); 169 CompareStrings("ct", "cut", 1); 170 CompareStrings("cat", "ct", 1); 171 CompareStrings("cat", "cat", 0); 172 CompareStrings("", "", 0); 173 CompareStrings("cat", "", 3); 174 CompareStrings("a cat", "a capybara", 7); 175 CompareStrings("abbabababababaaabbabababababbabbbbbbbababa", 176 "bbbbabababbbabababbbabababababbabbababa"); 177} 178 179#endif // ENABLE_DEBUGGER_SUPPORT 180