aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/test/diff_format.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-06-01 00:19:33 -0700
committerGravatar GitHub <noreply@github.com> 2023-06-01 00:19:33 -0700
commita4ccd4e0b4cc19f534bf639f30b7e4218400e1e8 (patch)
tree250f89bddd6e6c920645db2ad39bb7edf576edf0 /src/bun.js/test/diff_format.zig
parentcb0f76aa73f6b85667b57015a77ac39d9c78aa0b (diff)
parent689434e012a47b9be897f6d90d6aa211b13dfc19 (diff)
downloadbun-a4ccd4e0b4cc19f534bf639f30b7e4218400e1e8.tar.gz
bun-a4ccd4e0b4cc19f534bf639f30b7e4218400e1e8.tar.zst
bun-a4ccd4e0b4cc19f534bf639f30b7e4218400e1e8.zip
Merge branch 'main' into jarred/portjarred/port
Diffstat (limited to 'src/bun.js/test/diff_format.zig')
-rw-r--r--src/bun.js/test/diff_format.zig293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/bun.js/test/diff_format.zig b/src/bun.js/test/diff_format.zig
new file mode 100644
index 000000000..4558a5f39
--- /dev/null
+++ b/src/bun.js/test/diff_format.zig
@@ -0,0 +1,293 @@
+const std = @import("std");
+const bun = @import("root").bun;
+const MutableString = bun.MutableString;
+const Output = bun.Output;
+const default_allocator = bun.default_allocator;
+const string = bun.string;
+const JSC = bun.JSC;
+const JSValue = JSC.JSValue;
+const JSGlobalObject = JSC.JSGlobalObject;
+const ZigConsoleClient = JSC.ZigConsoleClient;
+const DiffMatchPatch = @import("../../deps/diffz/DiffMatchPatch.zig");
+
+pub const DiffFormatter = struct {
+ received_string: ?string = null,
+ expected_string: ?string = null,
+ received: ?JSValue = null,
+ expected: ?JSValue = null,
+ globalObject: *JSGlobalObject,
+ not: bool = false,
+
+ pub fn format(this: DiffFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
+ if (this.expected_string != null and this.received_string != null) {
+ const received = this.received_string.?;
+ const expected = this.expected_string.?;
+
+ var dmp = DiffMatchPatch.default;
+ dmp.diff_timeout = 200;
+ var diffs = try dmp.diff(default_allocator, received, expected, false);
+ defer diffs.deinit(default_allocator);
+
+ const equal_fmt = "<d>{s}<r>";
+ const delete_fmt = "<red>{s}<r>";
+ const insert_fmt = "<green>{s}<r>";
+
+ try writer.writeAll("Expected: ");
+ for (diffs.items) |df| {
+ switch (df.operation) {
+ .delete => continue,
+ .insert => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(insert_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(insert_fmt, false), .{df.text});
+ }
+ },
+ .equal => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(equal_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(equal_fmt, false), .{df.text});
+ }
+ },
+ }
+ }
+
+ try writer.writeAll("\nReceived: ");
+ for (diffs.items) |df| {
+ switch (df.operation) {
+ .insert => continue,
+ .delete => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(delete_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(delete_fmt, false), .{df.text});
+ }
+ },
+ .equal => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(equal_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(equal_fmt, false), .{df.text});
+ }
+ },
+ }
+ }
+ return;
+ }
+
+ if (this.received == null or this.expected == null) return;
+
+ const received = this.received.?;
+ const expected = this.expected.?;
+ var received_buf = MutableString.init(default_allocator, 0) catch unreachable;
+ var expected_buf = MutableString.init(default_allocator, 0) catch unreachable;
+ defer {
+ received_buf.deinit();
+ expected_buf.deinit();
+ }
+
+ {
+ var buffered_writer_ = MutableString.BufferedWriter{ .context = &received_buf };
+ var buffered_writer = &buffered_writer_;
+
+ var buf_writer = buffered_writer.writer();
+ const Writer = @TypeOf(buf_writer);
+
+ const fmt_options = ZigConsoleClient.FormatOptions{
+ .enable_colors = false,
+ .add_newline = false,
+ .flush = false,
+ .ordered_properties = true,
+ .quote_strings = true,
+ };
+ ZigConsoleClient.format(
+ .Debug,
+ this.globalObject,
+ @ptrCast([*]const JSValue, &received),
+ 1,
+ Writer,
+ Writer,
+ buf_writer,
+ fmt_options,
+ );
+ buffered_writer.flush() catch unreachable;
+
+ buffered_writer_.context = &expected_buf;
+
+ ZigConsoleClient.format(
+ .Debug,
+ this.globalObject,
+ @ptrCast([*]const JSValue, &this.expected),
+ 1,
+ Writer,
+ Writer,
+ buf_writer,
+ fmt_options,
+ );
+ buffered_writer.flush() catch unreachable;
+ }
+
+ const received_slice = received_buf.toOwnedSliceLeaky();
+ const expected_slice = expected_buf.toOwnedSliceLeaky();
+
+ if (this.not) {
+ const not_fmt = "Expected: not <green>{s}<r>";
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(not_fmt, true), .{expected_slice});
+ } else {
+ try writer.print(Output.prettyFmt(not_fmt, false), .{expected_slice});
+ }
+ return;
+ }
+
+ switch (received.determineDiffMethod(expected, this.globalObject)) {
+ .none => {
+ const fmt = "Expected: <green>{any}<r>\nReceived: <red>{any}<r>";
+ var formatter = ZigConsoleClient.Formatter{ .globalThis = this.globalObject, .quote_strings = true };
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(fmt, true), .{
+ expected.toFmt(this.globalObject, &formatter),
+ received.toFmt(this.globalObject, &formatter),
+ });
+ return;
+ }
+
+ try writer.print(Output.prettyFmt(fmt, true), .{
+ expected.toFmt(this.globalObject, &formatter),
+ received.toFmt(this.globalObject, &formatter),
+ });
+ return;
+ },
+ .character => {
+ var dmp = DiffMatchPatch.default;
+ dmp.diff_timeout = 200;
+ var diffs = try dmp.diff(default_allocator, received_slice, expected_slice, false);
+ defer diffs.deinit(default_allocator);
+
+ const equal_fmt = "<d>{s}<r>";
+ const delete_fmt = "<red>{s}<r>";
+ const insert_fmt = "<green>{s}<r>";
+
+ try writer.writeAll("Expected: ");
+ for (diffs.items) |df| {
+ switch (df.operation) {
+ .delete => continue,
+ .insert => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(insert_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(insert_fmt, false), .{df.text});
+ }
+ },
+ .equal => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(equal_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(equal_fmt, false), .{df.text});
+ }
+ },
+ }
+ }
+
+ try writer.writeAll("\nReceived: ");
+ for (diffs.items) |df| {
+ switch (df.operation) {
+ .insert => continue,
+ .delete => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(delete_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(delete_fmt, false), .{df.text});
+ }
+ },
+ .equal => {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(equal_fmt, true), .{df.text});
+ } else {
+ try writer.print(Output.prettyFmt(equal_fmt, false), .{df.text});
+ }
+ },
+ }
+ }
+ return;
+ },
+ .line => {
+ var dmp = DiffMatchPatch.default;
+ dmp.diff_timeout = 200;
+ var diffs = try dmp.diffLines(default_allocator, received_slice, expected_slice);
+ defer diffs.deinit(default_allocator);
+
+ const equal_fmt = "<d> {s}<r>";
+ const delete_fmt = "<red>+ {s}<r>";
+ const insert_fmt = "<green>- {s}<r>";
+
+ var insert_count: usize = 0;
+ var delete_count: usize = 0;
+
+ for (diffs.items) |df| {
+ var prev: usize = 0;
+ var curr: usize = 0;
+ switch (df.operation) {
+ .equal => {
+ while (curr < df.text.len) {
+ if (curr == df.text.len - 1 or df.text[curr] == '\n' and curr != 0) {
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(equal_fmt, true), .{df.text[prev .. curr + 1]});
+ } else {
+ try writer.print(Output.prettyFmt(equal_fmt, false), .{df.text[prev .. curr + 1]});
+ }
+ prev = curr + 1;
+ }
+ curr += 1;
+ }
+ },
+ .insert => {
+ while (curr < df.text.len) {
+ if (curr == df.text.len - 1 or df.text[curr] == '\n' and curr != 0) {
+ insert_count += 1;
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(insert_fmt, true), .{df.text[prev .. curr + 1]});
+ } else {
+ try writer.print(Output.prettyFmt(insert_fmt, false), .{df.text[prev .. curr + 1]});
+ }
+ prev = curr + 1;
+ }
+ curr += 1;
+ }
+ },
+ .delete => {
+ while (curr < df.text.len) {
+ if (curr == df.text.len - 1 or df.text[curr] == '\n' and curr != 0) {
+ delete_count += 1;
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt(delete_fmt, true), .{df.text[prev .. curr + 1]});
+ } else {
+ try writer.print(Output.prettyFmt(delete_fmt, false), .{df.text[prev .. curr + 1]});
+ }
+ prev = curr + 1;
+ }
+ curr += 1;
+ }
+ },
+ }
+ if (df.text[df.text.len - 1] != '\n') try writer.writeAll("\n");
+ }
+
+ if (Output.enable_ansi_colors) {
+ try writer.print(Output.prettyFmt("\n<green>- Expected - {d}<r>\n", true), .{insert_count});
+ try writer.print(Output.prettyFmt("<red>+ Received + {d}<r>", true), .{delete_count});
+ return;
+ }
+ try writer.print("\n- Expected - {d}\n", .{insert_count});
+ try writer.print("+ Received + {d}", .{delete_count});
+ return;
+ },
+ .word => {
+ // not implemented
+ // https://github.com/google/diff-match-patch/wiki/Line-or-Word-Diffs#word-mode
+ },
+ }
+ return;
+ }
+};