Skip to content

Commit

Permalink
Formula helpers and named expressions (part 2) (#192)
Browse files Browse the repository at this point in the history
* Add test for 255-long named expression

* Add more validations for named expressions

* Export ExportedCellChange object instead of class

Because in a moment I will introduce second class, representing
changed named expression.

* It no longer exports only values

* Don't leak internal detail of workbook named expressions, -1 sheet

* Add tests for named expression changes

* Added test for matrix formula without braces

* Add tests for errors in named expressions with something other than formula

* lint-fix

* Add ability to calculate fire-and-forget formulas

* Refactor common part

* lint-fix

* Add documentation

* Fix tests

* Make it more clear what is the reason we initialize -1 sheet

* Add possibility to calculateFormula in context of some sheet

* Rename spec

* Change the test other way around

* Support any raw cell content as an expression

* Refactoring: Rename NamedExpressions#storeFormulaInCell -> #storeExpressionInCell

* Refactoring: Rename #changeNamedExpressionFormula -> #changeNamedExpressionExpression

* Support other types of input when changing named expressions

* Refactoring: change naming external formula to temporary formula

Since formula is not stored, temporary sounds better

* Refactoring: Make HyperFormula know less

not directly know that named expression is stored in some specific cell.

* lint-fix
  • Loading branch information
swistak35 committed Feb 26, 2020
1 parent 2b6b8bd commit e1d91aa
Show file tree
Hide file tree
Showing 22 changed files with 504 additions and 215 deletions.
57 changes: 54 additions & 3 deletions src/CellValue.ts
@@ -1,8 +1,44 @@
import {CellError, ErrorType, InternalCellValue, NoErrorCellValue} from './Cell'
import {CellError, ErrorType, InternalCellValue, NoErrorCellValue, simpleCellAddress, SimpleCellAddress} from './Cell'
import {CellValueChange} from './ContentChanges'
import {Config} from './Config'
import {NamedExpressions} from './NamedExpressions'

export type CellValue = NoErrorCellValue | DetailedCellError

export type ExportedChange = ExportedCellChange | ExportedNamedExpressionChange

export class ExportedCellChange {
constructor(
public readonly address: SimpleCellAddress,
public readonly newValue: CellValue,
) {
}

public get col() {
return this.address.col
}

public get row() {
return this.address.row
}

public get sheet() {
return this.address.sheet
}

public get value() {
return this.newValue
}
}

export class ExportedNamedExpressionChange {
constructor(
public readonly name: string,
public readonly newValue: CellValue,
) {
}
}

export class DetailedCellError {
constructor(
public readonly error: CellError,
Expand All @@ -19,13 +55,28 @@ export class DetailedCellError {
}
}

export class CellValueExporter {
export class Exporter {
constructor(
private readonly config: Config,
private readonly namedExpressions: NamedExpressions,
) {
}

public export(value: InternalCellValue): CellValue {
public exportChange(change: CellValueChange): ExportedChange {
if (change.sheet === NamedExpressions.SHEET_FOR_WORKBOOK_EXPRESSIONS) {
return new ExportedNamedExpressionChange(
this.namedExpressions.fetchNameForNamedExpressionRow(change.row),
this.exportValue(change.value),
)
} else {
return new ExportedCellChange(
simpleCellAddress(change.sheet, change.col, change.row),
this.exportValue(change.value),
)
}
}

public exportValue(value: InternalCellValue): CellValue {
if (this.config.smartRounding && typeof value == 'number' && !Number.isInteger(value)) {
return this.cellValueRounding(value)
} else if (value instanceof CellError) {
Expand Down
15 changes: 6 additions & 9 deletions src/ContentChanges.ts
@@ -1,5 +1,4 @@
import {InternalCellValue, SimpleCellAddress} from './Cell'
import {CellValueExporter} from './CellValue'
import {Matrix} from './Matrix'

export interface CellValueChange {
Expand All @@ -9,6 +8,9 @@ export interface CellValueChange {
value: InternalCellValue,
}

export interface IChangeExporter<T> {
exportChange: (arg: CellValueChange) => T,
}
export type ChangeList = CellValueChange[]

export class ContentChanges {
Expand Down Expand Up @@ -38,15 +40,10 @@ export class ContentChanges {
this.changes.push(...change)
}

public exportChanges(exporter: CellValueExporter): ChangeList {
const ret: ChangeList = []
public exportChanges<T>(exporter: IChangeExporter<T>): T[] {
const ret: T[] = []
this.changes.forEach((e, i) => {
ret[i] = {
sheet: this.changes[i].sheet,
col: this.changes[i].col,
row: this.changes[i].row,
value: exporter.export(this.changes[i].value),
}
ret[i] = exporter.exportChange(this.changes[i])
})
return ret
}
Expand Down
3 changes: 3 additions & 0 deletions src/Evaluator.ts
@@ -1,8 +1,11 @@
import {ContentChanges} from './ContentChanges'
import {InternalCellValue, SimpleCellAddress} from './Cell'
import {Ast} from './parser'
import {Vertex} from './DependencyGraph'

export interface Evaluator {
run(): void,
partialRun(vertices: Vertex[]): ContentChanges,
runAndForget(ast: Ast, address: SimpleCellAddress): InternalCellValue,
destroy(): void,
}

0 comments on commit e1d91aa

Please sign in to comment.