diff --git a/coopy/Coopy.hx b/coopy/Coopy.hx index 7405ec7..fa341fa 100644 --- a/coopy/Coopy.hx +++ b/coopy/Coopy.hx @@ -1166,16 +1166,12 @@ class Coopy { * It is a thin wrapper around the `coopyhx` method. * */ - public static function main() : Int { + public static function main() : Void { #if coopyhx_util var io = new TableIO(); var coopy = new Coopy(); var ret = coopy.coopyhx(io); if (ret!=0) Sys.exit(ret); - return ret; -#else - // do nothing - return 0; #end } diff --git a/coopy/DiffRender.hx b/coopy/DiffRender.hx index ab51a7b..b05bd58 100644 --- a/coopy/DiffRender.hx +++ b/coopy/DiffRender.hx @@ -239,8 +239,24 @@ class DiffRender { pretty_tokens[0] = markSpaces(ref,tokens[2]); pretty_tokens[2] = markSpaces(tokens[2],ref); } - cell.pretty_separator = String.fromCharCode(8594); cell.pretty_value = pretty_tokens.join(cell.pretty_separator); + if (cell.pretty_value == "-+->") { + cell.pretty_separator = String.fromCharCode(10565); + cat = "add_some"; + } else if (cell.pretty_value == "-/->") { + cell.pretty_separator = String.fromCharCode(8603); + cat = "remove_some"; + } else { + cell.pretty_separator = String.fromCharCode(8594); + cat = "modify"; + } + + cell.pretty_value = pretty_tokens.join(cell.pretty_separator); + if (cell.pretty_value.length > 1 && StringTools.endsWith(cell.pretty_value, "→")) { + cat = "remove_some"; + } else if (cell.pretty_value.length > 1 && StringTools.startsWith(cell.pretty_value, "→")) { + cat = "add_some"; + } cell.category_given_tr = cell.category = cat; var offset : Int = cell.conflicted?1:0; cell.lvalue = tokens[offset]; @@ -409,7 +425,12 @@ class DiffRender { .highlighter .remove { background-color: #ff7f7f; } - +.highlighter td.add_some { + background-color: #7fff7f; +} +.highlighter td.remove_some { + background-color: #ff7f7f; +} .highlighter td.modify { background-color: #7f7fff; } diff --git a/coopy/DiffSummary.hx b/coopy/DiffSummary.hx index bf9b31c..c306c9f 100644 --- a/coopy/DiffSummary.hx +++ b/coopy/DiffSummary.hx @@ -22,6 +22,9 @@ class DiffSummary { public var col_renames : Int; public var col_reorders : Int; + public var column_units_updates : Map>; + public var column_units_updated : Map; + public var row_count_initial_with_header : Int; public var row_count_final_with_header : Int; public var row_count_initial : Int; diff --git a/coopy/TableDiff.hx b/coopy/TableDiff.hx index c27bbc4..bb84b11 100644 --- a/coopy/TableDiff.hx +++ b/coopy/TableDiff.hx @@ -73,6 +73,7 @@ class TableDiff { private var col_updates : Int; private var col_renames : Int; private var col_reorders : Int; + private var column_units_updates : Map>; private var column_units_updated : Map; private var nested : Bool; @@ -266,6 +267,7 @@ class TableDiff { col_renames = 0; col_reorders = 0; column_units_updated = new Map(); + column_units_updates = new Map>(); } private function setupTables() : Void { @@ -689,6 +691,24 @@ class TableDiff { return txt; } + private function isEmpty(v: View, val: Dynamic) : Bool { + + return (Type.typeof(val) == TNull || Type.typeof(val) == TUnknown || isEqual(v, v.toString(val), "")); + } + private function getChangeType(v: View, aa: Dynamic, bb: Dynamic) : String { + var isEmptyA = isEmpty(v, aa); + var isEmptyB = isEmpty(v, bb); + if (isEqual(v,aa,bb) || (isEmptyA && isEmptyB)) { + return "="; + } + if (isEmptyA && !isEmptyB) { + return "+"; + } + if (!isEmptyA && isEmptyB) { + return "-"; + } + return "!="; + } private function isEqual(v: View, aa: Dynamic, bb: Dynamic) : Bool { // Check if we need to apply an exception for comparing floating // point numbers. @@ -799,6 +819,9 @@ class TableDiff { */ private function scanRow(unit: Unit, output: Table, at: Int, i: Int, out: Int) { var row_update : Bool = false; + var has_additions : Bool = false; + var has_deletions : Bool = false; + var has_updates : Bool = false; for (j in 0...column_units.length) { var cunit : Unit = column_units[j]; var pp : Dynamic = null; @@ -951,8 +974,34 @@ class TableDiff { output.setCell(j+1,at,cell); } } - } + var column_name : String = p.getCell(j, 0); + var changeType = getChangeType(v, ll, rr); + if (changeType == "+") { + has_additions = true; +// sep = "-+->"; + } else if (changeType == "-") { + has_deletions = true; +// sep = "-/->"; + } else if (changeType == "!=") { + has_updates = true; + } + if (!column_units_updates.exists(column_name)) { + column_units_updates.set(column_name,[changeType => 1]); + } else { + var specific_update = column_units_updates.get(column_name); + var update_count = 1; + if (specific_update.exists(changeType)) { + update_count = specific_update.get(changeType) + 1; + } + specific_update.set(changeType, update_count); + } + } + if (has_additions && !has_deletions && !has_updates && act != "+++" && act != "---") { + act = "-+->"; + } else if (!has_additions && has_deletions && !has_updates && act != "+++" && act != "---") { + act = "-/->"; + } if (publish) { output.setCell(0,at,builder.marker(act)); row_map.set(at,unit); @@ -1033,6 +1082,7 @@ class TableDiff { var showed_dummy : Bool = false; var l : Int = -1; var r : Int = -1; + column_units_updates = new Map>(); for (i in 0...row_units.length) { var unit : Unit = row_units[i]; var reordered : Bool = false; @@ -1184,6 +1234,8 @@ class TableDiff { ds.col_updates = col_updates; ds.col_renames = col_renames; ds.col_reorders = col_reorders; + ds.column_units_updated = column_units_updated; + ds.column_units_updates = column_units_updates; ds.row_count_initial_with_header = align.getSource().height; ds.row_count_final_with_header = align.getTarget().height; ds.row_count_initial = align.getSource().height - align.getSourceHeader() - 1; diff --git a/harness/BasicTest.hx b/harness/BasicTest.hx index bfc9d90..e221c45 100644 --- a/harness/BasicTest.hx +++ b/harness/BasicTest.hx @@ -64,6 +64,12 @@ class BasicTest extends haxe.unit.TestCase { assertEquals(summary.col_deletes,0); assertEquals(summary.col_inserts,1); assertEquals(summary.col_updates,1); + // TODO: add tests for column_units_updates + assertEquals(summary.col_updates,1); + assertEquals(summary.col_updates,1); + assertEquals(summary.col_updates,1); + assertEquals(summary.col_updates,1); + assertEquals(summary.col_updates,1); assertEquals(summary.row_count_initial_with_header,4); assertEquals(summary.row_count_final_with_header,5); assertEquals(summary.row_count_initial,3); diff --git a/test/test_column_diff_summary2.js b/test/test_column_diff_summary2.js new file mode 100644 index 0000000..bcc3866 --- /dev/null +++ b/test/test_column_diff_summary2.js @@ -0,0 +1,62 @@ +var daff = require('../lib/daff.js'); +var assert = require('assert'); + + +var tableA = [ + { "Name": "", "Number": '14', "Color": "green" }, + { "Name": "John1", "Number": '88', "Color": "red" }, + { "Name": "John1", "Number": '88', "Color": "red" }, + { "Name": "John2", "Number": '99', "Color": '22' }, + { "Name": "John3", "Number": '99', "Color": '23' }, + { "Name": "John4", "Number": '99', "Color": '' }, + { "Name": "John5", "Number": '99', "Color": '25' }, + { "Name": "John43", "Number": '99', "Color": '28' }, + { "Name": "John5", "Number": '991', "Color": '28' }, + { "Name": "John6", "Number": '992', "Color": '281' }, + { "Name": "John7", "Number": '993', "Color": '282' }, + { "Name": "John8", "Number": '994', "Color": '283' }, +]; + +var tableB = [ + { "Name": "Jane", "Number": '14', "Color": "green" }, + { "Name": "John1", "Number": '88', "Color": "red" }, + { "Name": "John2", "Number": '99', "Color": '22' }, + { "Name": "John3", "Number": '99', "Color": '23' }, + { "Name": "John4", "Number": '99', "Color": '28' }, + { "Name": "", "Number": '99', "Color": '25' }, + { "Name": "John43", "Number": '99', "Color": '28' }, + { "Name": "John55", "Number": '991', "Color": '28' }, + { "Name": "John6", "Number": '992', "Color": '281' }, + { "Name": "", "Number": '993', "Color": '282' }, + { "Name": "John8", "Number": '994', "Color": '283' }, + { "Name": "John8", "Number": '994', "Color": '283' }, +]; + +const daffTableA = new daff.NdjsonTable(tableA); +const daffTableB = new daff.NdjsonTable(tableB); +var dataDiff = []; +var tableDiff = new daff.TableView(dataDiff); + +var alignment = daff.compareTables(daffTableA, daffTableB).align(); + +var flags = new daff.CompareFlags(); +flags.allow_nested_cells = true; +flags.ignore_whitespace = true; +flags.always_show_order = false; +flags.never_show_order = true; + + +var highlighter = new daff.TableDiff(alignment, flags); +highlighter.hilite(tableDiff); + + +var diff2html = new daff.DiffRender(); +diff2html.render(tableDiff); +require('fs').writeFileSync('./test-diff.html', + + '' + + '
' + JSON.stringify(highlighter.getSummary(), null, 2)+ '
' + + '
' + diff2html.html() + '
' + + , { encoding: 'utf8' }); +