| // Copyright (C) 2025 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import {formatAsJSON, formatAsMarkdown, formatAsTSV} from './export_formatters'; |
| |
| describe('export_formatters', () => { |
| describe('formatAsTSV', () => { |
| it('formats simple data as TSV', () => { |
| const columns = ['colA', 'colB', 'colC']; |
| const columnNames = {colA: 'colA', colB: 'colB', colC: 'colC'}; |
| const rows = [ |
| {colA: '1', colB: 'foo', colC: 'null'}, |
| {colA: '2', colB: 'bar', colC: '123.4'}, |
| {colA: '3', colB: 'baz', colC: '1'}, |
| ]; |
| |
| const expected = |
| 'colA\tcolB\tcolC\n1\tfoo\tnull\n2\tbar\t123.4\n3\tbaz\t1'; |
| expect(formatAsTSV(columns, columnNames, rows)).toEqual(expected); |
| }); |
| |
| it('uses column names for headers', () => { |
| const columns = ['id', 'name']; |
| const columnNames = {id: 'ID', name: 'Name'}; |
| const rows = [{id: '1', name: 'Alice'}]; |
| |
| const expected = 'ID\tName\n1\tAlice'; |
| expect(formatAsTSV(columns, columnNames, rows)).toEqual(expected); |
| }); |
| |
| it('handles empty rows', () => { |
| const columns = ['a', 'b']; |
| const columnNames = {a: 'a', b: 'b'}; |
| const rows: Array<Record<string, string>> = []; |
| |
| const expected = 'a\tb'; |
| expect(formatAsTSV(columns, columnNames, rows)).toEqual(expected); |
| }); |
| |
| it('handles empty columns', () => { |
| const columns: string[] = []; |
| const columnNames = {}; |
| const rows: Array<Record<string, string>> = []; |
| |
| const expected = ''; |
| expect(formatAsTSV(columns, columnNames, rows)).toEqual(expected); |
| }); |
| |
| it('escapes tabs and newlines in cell values', () => { |
| const columns = ['col']; |
| const columnNames = {col: 'col'}; |
| const rows = [ |
| {col: 'has\ttab'}, |
| {col: 'has\nnewline'}, |
| {col: 'has\r\nwindows newline'}, |
| {col: 'normal'}, |
| ]; |
| |
| const result = formatAsTSV(columns, columnNames, rows); |
| // Tabs and newlines should be replaced with spaces |
| expect(result).not.toContain('\t\t'); // No double tabs (one is separator) |
| expect(result).toContain('has tab'); |
| expect(result).toContain('has newline'); |
| expect(result).toContain('has windows newline'); |
| expect(result).toContain('normal'); |
| }); |
| }); |
| |
| describe('formatAsJSON', () => { |
| it('formats data as JSON', () => { |
| const columns = ['colA', 'colB', 'colC']; |
| const columnNames = { |
| colA: 'Column A', |
| colB: 'Column B', |
| colC: 'Column C', |
| }; |
| const rows = [ |
| {colA: '1', colB: 'foo', colC: 'null'}, |
| {colA: '2', colB: 'bar', colC: '123.4'}, |
| ]; |
| |
| const expectedRows = [ |
| {'Column A': '1', 'Column B': 'foo', 'Column C': 'null'}, |
| {'Column A': '2', 'Column B': 'bar', 'Column C': '123.4'}, |
| ]; |
| |
| const result = formatAsJSON(columns, columnNames, rows); |
| const parsed = JSON.parse(result); |
| expect(parsed).toEqual(expectedRows); |
| }); |
| |
| it('formats empty array', () => { |
| const columns = ['a', 'b']; |
| const columnNames = {a: 'a', b: 'b'}; |
| const rows: Array<Record<string, string>> = []; |
| const expected = '[]'; |
| expect(formatAsJSON(columns, columnNames, rows)).toEqual(expected); |
| }); |
| |
| it('formats with indentation', () => { |
| const columns = ['a']; |
| const columnNames = {a: 'a'}; |
| const rows = [{a: '1'}]; |
| const result = formatAsJSON(columns, columnNames, rows); |
| expect(result).toContain('\n'); // Should be pretty-printed |
| }); |
| }); |
| |
| describe('formatAsMarkdown', () => { |
| it('formats data as markdown table', () => { |
| const columns = ['colA', 'colB', 'colC']; |
| const columnNames = {colA: 'colA', colB: 'colB', colC: 'colC'}; |
| const rows = [ |
| {colA: '1', colB: 'foo', colC: 'null'}, |
| {colA: '2', colB: 'bar', colC: '123.4'}, |
| {colA: '3', colB: 'baz', colC: '1'}, |
| ]; |
| |
| const result = formatAsMarkdown(columns, columnNames, rows); |
| expect(result).toContain('| colA | colB | colC |'); |
| expect(result).toContain('| --- | --- | --- |'); |
| expect(result).toContain('| 1 | foo | null |'); |
| expect(result).toContain('| 2 | bar | 123.4 |'); |
| expect(result).toContain('| 3 | baz | 1 |'); |
| }); |
| |
| it('escapes pipe characters', () => { |
| const columns = ['col']; |
| const columnNames = {col: 'col'}; |
| const rows = [{col: 'a|b'}]; |
| |
| const result = formatAsMarkdown(columns, columnNames, rows); |
| expect(result).toContain('a\\|b'); |
| }); |
| |
| it('escapes backslashes', () => { |
| const columns = ['col']; |
| const columnNames = {col: 'col'}; |
| const rows = [{col: 'a\\b'}]; |
| |
| const result = formatAsMarkdown(columns, columnNames, rows); |
| expect(result).toContain('a\\\\b'); |
| }); |
| |
| it('replaces newlines with spaces', () => { |
| const columns = ['col']; |
| const columnNames = {col: 'col'}; |
| const rows = [{col: 'has\nnewline'}, {col: 'has\r\nwindows'}]; |
| |
| const result = formatAsMarkdown(columns, columnNames, rows); |
| expect(result).not.toContain('\n\n'); // No double newlines |
| expect(result).toContain('has newline'); |
| expect(result).toContain('has windows'); |
| }); |
| |
| it('handles empty rows', () => { |
| const columns = ['a', 'b']; |
| const columnNames = {a: 'a', b: 'b'}; |
| const rows: Array<Record<string, string>> = []; |
| |
| const result = formatAsMarkdown(columns, columnNames, rows); |
| expect(result).toContain('| a | b |'); |
| expect(result).toContain('| --- | --- |'); |
| }); |
| |
| it('handles empty columns', () => { |
| const columns: string[] = []; |
| const columnNames = {}; |
| const rows: Array<Record<string, string>> = []; |
| |
| const expected = ''; |
| expect(formatAsMarkdown(columns, columnNames, rows)).toEqual(expected); |
| }); |
| }); |
| }); |