Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]
branches:
- main

jobs:
build-and-test:
Expand All @@ -26,4 +25,4 @@ jobs:
run: npm run build

- name: Run tests (local Node.js + mocks)
run: npm test
run: npm test
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.preferences.tsconfigPath": "tsconfig.test.json"
}
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

---
## [2.1.0] – 2025-06-26

## [Unreleased]
### Added
- **`ExcelAppender` color map support**: The `getInstance` method now accepts a color map, allowing users to specify custom font colors for different log levels. The default color map is exposed as a public property, enabling users to reference or modify it for their own configurations.
- **Additional documentation**: Added `git-basics.md`, providing concise, project-specific instructions and best practices for using Git effectively within this repository.

### Changed
- Ensured cross-platform compatibility: Adjustments were made to guarantee the framework works in both Node.js/TypeScript and Office Scripts environments. To pass all tests, `setTimeout` was used in some cases to handle the asynchronous nature of Office Scripts.
- **VSCode configuration improvements**: The project now uses a dedicated `types` folder to include all `*.d.ts` files, such as Office Scripts declarations and global variable definitions. This streamlines type management and ensures accurate IntelliSense and type checking within VSCode.

---

## [2.0.0] – 2025-06-19

### Added
- **AssertionError**: Introduced a new error class for clearer assertion failure reporting in the unit test framework (`unit-test-framework.ts`).
- **`AssertionError**`:** Introduced a new error class for clearer assertion failure reporting in the unit test framework (`unit-test-framework.ts`).
- **Assert enhancements**: Added new convenience methods to the `Assert` class, making test writing more robust and expressive (`unit-test-framework.ts`).
- **New interfaces and types**: Introduced `Logger`, `Layout`, and `LogEvent` interfaces, as well as the `LogEventFactory` type, to enhance extensibility and type safety (`logger.ts`).
- **New classes**: Added `LoggerImpl`, `Utility`, `LayoutImpl`, `LogEventImpl` (`logger.ts`), and `AssertionError` (`unit-test-framework.ts`) to provide a more modular, extensible, and testable architecture.
Expand Down
63 changes: 53 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ Logger.addAppender(ConsoleAppender.getInstance()) // Add console appender
## Basic Usage Examples

```typescript
Logger.info("Script started") // [INFO] Script started.
Logger.warn("This might be a problem") // [WARN] This might be a problem.
Logger.error("A fatal error occurred") // [ERROR] A fatal error occurred
Logger.trace("Step-by-step details") // [TRACE] Step-by-step details
Logger.info("Script started") // [2025-06-25 23:41:10,585] [INFO] Script started.
Logger.warn("This might be a problem") // [2025-06-25 23:41:10,585] [WARN] This might be a problem.
Logger.error("A fatal error occurred") // [2025-06-25 23:41:10,585] [ERROR] A fatal error occurred
Logger.trace("Step-by-step details") // [2025-06-25 23:41:10,585] [TRACE] Step-by-step details
```

> Output as shown above uses the short layout. With the default layout, a timestamp and brackets are included.
> Output as shown above uses the default layout. With the short layout, a timestamp and brackets are excluded.

### Logging to Excel Cell

Expand All @@ -57,8 +57,8 @@ function main(workbook: ExcelScript.Workbook) {
Logger.getInstance(Logger.LEVEL.INFO, Logger.ACTION.CONTINUE)
Logger.addAppender(ExcelAppender.getInstance(cell))

Logger.info("Log written to Excel!") // Output in cell B1: [INFO] Log written to Excel! (green text)
Logger.trace("Trace event in cell") // Output in cell B1: [TRACE] Trace event in cell (gray text)
Logger.info("Log written to Excel!") // Output in cell B1: [2025-06-25 23:41:10,586] [INFO] Log written to Excel! (green text)
Logger.trace("Trace event in cell") // Output in cell B1: [2025-06-25 23:41:10,586] [TRACE] Trace event in cell (gray text)
}
```

Expand Down Expand Up @@ -222,6 +222,7 @@ You can pass an object with arbitrary key-value pairs as the `extrafields` argum

#### Example: Adding custom fields to a log entry

Following examples assumed a short layout configuration.
```typescript
Logger.info("Processing started", { step: "init", user: "alice@example.com" })
````
Expand Down Expand Up @@ -297,10 +298,10 @@ function main(workbook: ExcelScript.Workbook) {
Logger.addAppender(ExcelAppender.getInstance(logCell))

// Logging (with short layout, output shown as comments):
Logger.info("Script started.") // [INFO] Script started.
Logger.info("Script started.") // [INFO] Script started.
Logger.trace("This is a trace message.") // [TRACE] This is a trace message.
Logger.warn("This is a warning.") // [WARN] This is a warning.
Logger.error("This is an error!") // [ERROR] This is an error! (if ACTION.EXIT, aborts script)
Logger.warn("This is a warning.") // [WARN] This is a warning.
Logger.error("This is an error!") // [ERROR] This is an error! (if ACTION.EXIT, aborts script)

// ExcelAppender outputs in cell C2:
// [INFO] Script started. (green text)
Expand All @@ -323,6 +324,28 @@ This framework is designed so that the log message layout and log event factory
- Passing these configurations via `getInstance` would require adding extra rarely-used parameters to already overloaded constructors, making the API harder for most users.
- If your scenario truly requires dynamic, runtime reconfiguration, you can fork the codebase or adapt it for your specific needs, but for most Office Scripts, stability is preferred.

## Cross-Platform Compatibility

This framework is designed to work seamlessly in both Node.js/TypeScript environments (such as VSCode) and directly within Office Scripts.

- **Tested Environments:**
- Node.js/TypeScript (VSCode)
- Office Scripts (Excel on the web)

- **Usage in Office Scripts:**
To use the framework in Office Scripts, paste the source files into your script in the following order:
1. `test/unit-test-framework.ts`
2. `src/logger.ts`
3. `test/main.ts`
The order matters because Office Scripts requires that all objects and functions are declared before they are used.

- **Office Scripts Compatibility Adjustments:**
- The code avoids unsupported keywords such as `any`, `export`, and `import`.
- Office Scripts does not allow calling `ExcelScript` API methods on Office objects inside class constructors; the code is structured to comply with this limitation.
- Additional nuances and workarounds are documented in the source code comments.

This ensures the logging framework is robust and reliable across both development and production Office Scripts scenarios.

---

## Troubleshooting & FAQ
Expand All @@ -348,6 +371,26 @@ This framework is designed so that the log message layout and log event factory
- **Why can't I send a different message to different appenders?**
By design, all channels (appenders) receive the same log event message for consistency.

- **Why am I getting unexpected results when running some tests in Office Scripts compared to Node.js/TypeScript?**
This can happen because Office Scripts executes code asynchronously, which means some operations (like logging or cell updates) may not complete in strict sequence. As a result, test outcomes may differ from those in Node.js/TypeScript, which runs synchronously and flushes operations immediately.

**Workaround:**
To ensure reliable test results in Office Scripts, introduce a delay or use asynchronous test helpers to wait for operations to complete before making assertions. In `test/main.ts`, the `TestCase.runTestAsync` method is used for this purpose. For example:

```typescript
let actualEvent = appender.getLastLogEvent()
TestCase.runTestAsync(() => {
Assert.isNotNull(actualEvent, "ExcelAppender(getLastLogEvent) not null")
Assert.equals(actualEvent!.type, expectedType, "ExcelAppender(getLastLogEvent).type")
Assert.equals(actualEvent!.message, expectedMsg, "ExcelAppender(getLastLogEvent).message")
// Now checking the Excel cell value (formatted via layout)
let expectedStr = AbstractAppender.getLayout().format(actualEvent as LogEvent)
Assert.equals(actualStr, expectedStr, "ExcelAppender(cell value via log(string,LOG_EVENT))")
})
```

By wrapping assertions in `runTestAsync`, you allow asynchronous operations to finish, making your tests more reliable across both environments.

---

## Additional Information
Expand Down
94 changes: 94 additions & 0 deletions docs/git-basics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Git Basic Operations Reference

## 1. Setup

```bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
```

## 2. Creating a Repository

```bash
git init # Initialize new repo in current directory
git clone <url> # Clone an existing repository
```

## 3. Checking Status

```bash
git status # Show status of changes
```

## 4. Staging and Committing
- **Stagging**: Moves changes from your working directory to the staging area, preparing them for the next commit
- **Committing**: Captures a snapshot of the currently staged changes and records them in the local repository
```bash
git add <file> # Stage a specific file
git add . # Stage all files
git commit -m "Message" # Commit staged changes
git commit --allow-empty -m "Message" # A commit with no changes
```

## 5. Viewing History

```bash
git log # View commit history
git log --oneline # Condensed log
```

## 6. Working with Branches

```bash
git branch # List branches
git branch <name> # Create new branch
git checkout <name> # Switch to branch
git checkout -b <name> # Create and switch to branch
git merge <name> # Merge branch into current
git branch -d <name> # Delete a branch
```

## 7. Pulling and Pushing
- **Pulling**: Fetches changes from a remote repository and integrates them into your local branch
- **Pushing**: Upload local repository content to a remote repository
```bash
git pull # Fetch and merge from remote
git push # Push changes to remote
git push -u origin <branch> # Push new branch and track
```

## 8. Undoing Changes

```bash
git checkout -- <file> # Discard changes in working directory
git reset HEAD <file> # Unstage a file
git revert <commit> # Create a new commit to undo changes
git reset --hard <commit> # Reset history and working directory (danger!)
```

## 9. Tags

```bash
git tag # List tags
git tag <name> # Create tag
git push origin <tag> # Push tag to remote
```

## 10. Rebasing (Advanced)
Modify the commit history of a branch by moving or combining a sequence of commits to a new base commit
```bash
git rebase <base-branch> # Rebase current branch onto base
git rebase -i <commit-hash> # Interactive rebase for editing history
```

## 11. Stashing
Allows temporarily save uncommitted changes
```bash
git stash # Stash unsaved changes
git stash pop # Apply stashed changes
```

---

**Tip:**
Use `git help <command>` for detailed info about any command!
2 changes: 1 addition & 1 deletion docs/typedoc/assets/hierarchy.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading