google-docs-mcp / src /tools /docs /cloneTable.test.ts
iFightDucks's picture
Initial HF Space deploy: a-bonus/google-docs-mcp with HF metadata
7dc28be
import { describe, expect, it } from 'vitest';
import { extractTableSnapshot, findTableNearestStartIndex } from './structureHelpers.js';
import { readFileSync } from 'node:fs';
const mockDocument = {
body: {
content: [
{
startIndex: 10,
endIndex: 100,
table: {
rows: 2,
columns: 2,
tableStyle: {
tableColumnProperties: [
{ widthType: 'FIXED_WIDTH', width: { magnitude: 60, unit: 'PT' } },
{ widthType: 'FIXED_WIDTH', width: { magnitude: 180, unit: 'PT' } },
],
},
tableRows: [
{
tableRowStyle: {
minRowHeight: { magnitude: 24, unit: 'PT' },
tableHeader: true,
},
tableCells: [
{
startIndex: 15,
endIndex: 25,
tableCellStyle: {
backgroundColor: { color: { rgbColor: { red: 0.85, green: 0.9, blue: 0.95 } } },
contentAlignment: 'MIDDLE',
paddingTop: { magnitude: 6, unit: 'PT' },
},
content: [
{
paragraph: {
elements: [
{
startIndex: 16,
endIndex: 19,
textRun: {
content: 'No.\n',
textStyle: { bold: true },
},
},
],
},
},
],
},
{
startIndex: 25,
endIndex: 45,
content: [
{
paragraph: {
elements: [
{
startIndex: 26,
endIndex: 30,
textRun: {
content: '課題名\n',
textStyle: { bold: true },
},
},
],
},
},
],
},
],
},
{
tableCells: [
{
startIndex: 45,
endIndex: 55,
content: [
{
paragraph: {
elements: [{ startIndex: 46, endIndex: 47, textRun: { content: '1\n' } }],
},
},
],
},
{
startIndex: 55,
endIndex: 95,
content: [
{
paragraph: {
elements: [
{
startIndex: 56,
endIndex: 69,
textRun: { content: 'SHIN-2870 調査\n' },
},
],
},
},
],
},
],
},
],
},
},
{
startIndex: 120,
endIndex: 180,
table: {
rows: 1,
columns: 1,
tableRows: [
{
tableCells: [
{
startIndex: 125,
endIndex: 135,
content: [
{
paragraph: {
elements: [{ startIndex: 126, endIndex: 130, textRun: { content: 'X\n' } }],
},
},
],
},
],
},
],
},
},
],
},
} as any;
describe('table snapshot helpers', () => {
it('extracts a reusable table snapshot with styles', () => {
const snapshot = extractTableSnapshot(mockDocument, 'table:body:0');
expect(snapshot).toMatchObject({
tableId: 'table:body:0',
rowCount: 2,
columnCount: 2,
pinnedHeaderRowsCount: 1,
data: [
['No.', '課題名'],
['1', 'SHIN-2870 調査'],
],
columnStyles: [
{ columnIndex: 0, widthPt: 60, widthType: 'FIXED_WIDTH' },
{ columnIndex: 1, widthPt: 180, widthType: 'FIXED_WIDTH' },
],
});
expect(snapshot?.rowStyles[0]).toMatchObject({
rowIndex: 0,
minRowHeightPt: 24,
tableHeader: true,
});
expect(snapshot?.cellStyles[0]).toMatchObject({
rowIndex: 0,
columnIndex: 0,
contentAlignment: 'MIDDLE',
paddingTopPt: 6,
hasBoldText: true,
});
});
it('finds the table nearest to an insertion index', () => {
const table = findTableNearestStartIndex(mockDocument, 100);
expect(table?.tableId).toBe('table:body:1');
});
it('requests tab table text and contentAlignment with the same structure as body tables', () => {
const source = readFileSync(new URL('./cloneTable.ts', import.meta.url), 'utf8');
expect(source).toContain(
'contentAlignment,paddingTop,paddingBottom,paddingLeft,paddingRight,rowSpan,columnSpan),content(paragraph('
);
});
});