feat(core): markdown-diff & patch apply (#12844)

## New Features
- **Markdown diff**: 
- Introduced block-level diffing for markdown content, enabling
detection of insertions, deletions, and replacements between document
versions.
  - Generate patch operations from markdown diff.
- **Patch Renderer**: Transfer patch operations to a render diff which
can be rendered into page body.
- **Patch apply**:Added functionality to apply patch operations to
documents, supporting block insertion, deletion, and content
replacement.

## Refactors
* Move `affine/shared/__tests__/utils` to
`blocksuite/affine-shared/test-utils`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Introduced utilities for declarative creation and testing of document
structures using template literals.
* Added new functions and types for block-level markdown diffing and
patch application.
* Provided a utility to generate structured render diffs for markdown
blocks.
* Added a unified test-utils entry point for easier access to testing
helpers.

* **Bug Fixes**
* Updated import paths in test files to use the new test-utils location.

* **Documentation**
* Improved example usage in documentation to reflect the new import
paths for test utilities.

* **Tests**
* Added comprehensive test suites for markdown diffing, patch
application, and render diff utilities.

* **Chores**
* Updated package dependencies and export maps to expose new test
utilities.
* Refactored internal test utilities organization for clarity and
maintainability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

> CLOSE AI-271 AI-272 AI-273
This commit is contained in:
德布劳外 · 贾贵
2025-07-04 18:48:49 +08:00
committed by GitHub
parent 5da56b5b04
commit c882a8c5da
23 changed files with 1346 additions and 314 deletions
@@ -0,0 +1,79 @@
# AFFiNE Test Tools
## Structured Document Creation
`affine-template.ts` provides a concise way to create test documents, using a html-like syntax.
### Basic Usage
```typescript
import { affine } from '@blocksuite/affine-shared/test-utils';
// Create a simple document
const doc = affine`
<affine-page>
<affine-note>
<affine-paragraph>Hello, World!</affine-paragraph>
</affine-note>
</affine-page>
`;
```
### Complex Structure Example
```typescript
// Create a document with multiple notes and paragraphs
const doc = affine`
<affine-page title="My Test Page">
<affine-note>
<affine-paragraph>First paragraph</affine-paragraph>
<affine-paragraph>Second paragraph</affine-paragraph>
</affine-note>
<affine-note>
<affine-paragraph>Another note</affine-paragraph>
</affine-note>
</affine-page>
`;
```
### Application in Tests
This tool is particularly suitable for creating documents with specific structures in test cases:
```typescript
import { describe, expect, it } from 'vitest';
import { affine } from '../__tests__/utils/affine-template';
describe('My Test', () => {
it('should correctly handle document structure', () => {
const doc = affine`
<affine-page>
<affine-note>
<affine-paragraph>Test content</affine-paragraph>
</affine-note>
</affine-page>
`;
// Get blocks
const pages = doc.getBlocksByFlavour('affine:page');
const notes = doc.getBlocksByFlavour('affine:note');
const paragraphs = doc.getBlocksByFlavour('affine:paragraph');
expect(pages.length).toBe(1);
expect(notes.length).toBe(1);
expect(paragraphs.length).toBe(1);
// Perform more tests here...
});
});
```
### Supported Block Types
Currently supports the following block types:
- `affine-page``affine:page`
- `affine-note``affine:note`
- `affine-paragraph``affine:paragraph`
- `affine-list``affine:list`
- `affine-image``affine:image`