UPDATE: Adds bindings to update timezone and locale
UPDATE: Update "generate locale" utility FIX: Minor fixes to UI and proper support for locales/timezones UPDATE: Adds "display language" setting to core
This commit is contained in:
@@ -36,21 +36,27 @@ pub struct Model {
|
||||
#[napi]
|
||||
impl Model {
|
||||
#[napi(constructor)]
|
||||
pub fn new(name: String, locale: String, timezone: String) -> Result<Self> {
|
||||
let model = BaseModel::new_empty(&name, &locale, &timezone).map_err(to_js_error)?;
|
||||
pub fn new(name: String, locale: String, timezone: String, language_id: String) -> Result<Self> {
|
||||
let model =
|
||||
BaseModel::new_empty(&name, &locale, &timezone, &language_id).map_err(to_js_error)?;
|
||||
Ok(Self { model })
|
||||
}
|
||||
|
||||
#[napi(factory)]
|
||||
pub fn from_xlsx(file_path: String, locale: String, tz: String) -> Result<Model> {
|
||||
let model = load_from_xlsx(&file_path, &locale, &tz)
|
||||
pub fn from_xlsx(
|
||||
file_path: String,
|
||||
locale: String,
|
||||
tz: String,
|
||||
language_id: String,
|
||||
) -> Result<Model> {
|
||||
let model = load_from_xlsx(&file_path, &locale, &tz, &language_id)
|
||||
.map_err(|error| Error::new(Status::Unknown, error.to_string()))?;
|
||||
Ok(Self { model })
|
||||
}
|
||||
|
||||
#[napi(factory)]
|
||||
pub fn from_icalc(file_name: String) -> Result<Model> {
|
||||
let model = load_from_icalc(&file_name)
|
||||
pub fn from_icalc(file_name: String, language_id: String) -> Result<Model> {
|
||||
let model = load_from_icalc(&file_name, &language_id)
|
||||
.map_err(|error| Error::new(Status::Unknown, error.to_string()))?;
|
||||
Ok(Self { model })
|
||||
}
|
||||
@@ -90,7 +96,7 @@ impl Model {
|
||||
pub fn get_cell_content(&self, sheet: u32, row: i32, column: i32) -> Result<String> {
|
||||
self
|
||||
.model
|
||||
.get_cell_content(sheet, row, column)
|
||||
.get_localized_cell_content(sheet, row, column)
|
||||
.map_err(to_js_error)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,15 @@ pub struct UserModel {
|
||||
#[napi]
|
||||
impl UserModel {
|
||||
#[napi(constructor)]
|
||||
pub fn new(name: String, locale: String, timezone: String) -> Result<Self> {
|
||||
let model = BaseModel::new_empty(&name, &locale, &timezone).map_err(to_js_error)?;
|
||||
pub fn new(name: String, locale: String, timezone: String, language_id: String) -> Result<Self> {
|
||||
let model =
|
||||
BaseModel::new_empty(&name, &locale, &timezone, &language_id).map_err(to_js_error)?;
|
||||
Ok(Self { model })
|
||||
}
|
||||
|
||||
#[napi(factory)]
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<UserModel> {
|
||||
let model = BaseModel::from_bytes(bytes).map_err(to_js_error)?;
|
||||
pub fn from_bytes(bytes: &[u8], language_id: String) -> Result<UserModel> {
|
||||
let model = BaseModel::from_bytes(bytes, &language_id).map_err(to_js_error)?;
|
||||
Ok(UserModel { model })
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import ironcalc as ic
|
||||
|
||||
model = ic.create("model", "en", "UTC")
|
||||
model = ic.create("model", "en", "UTC", "en")
|
||||
|
||||
model.set_user_input(0, 1, 1, "=21*2")
|
||||
model.evaluate()
|
||||
|
||||
@@ -9,7 +9,7 @@ Creating an Empty Model
|
||||
|
||||
import ironcalc as ic
|
||||
|
||||
model = ic.create("My Workbook", "en", "UTC")
|
||||
model = ic.create("My Workbook", "en", "UTC", "en")
|
||||
|
||||
Loading from XLSX
|
||||
^^^^^^^^^^^^^^^^^
|
||||
@@ -18,14 +18,14 @@ Loading from XLSX
|
||||
|
||||
import ironcalc as ic
|
||||
|
||||
model = ic.load_from_xlsx("example.xlsx", "en", "UTC")
|
||||
model = ic.load_from_xlsx("example.xlsx", "en", "UTC", "en")
|
||||
|
||||
Modifying and Saving
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
model = ic.create("model", "en", "UTC")
|
||||
model = ic.create("model", "en", "UTC", "en")
|
||||
model.set_user_input(0, 1, 1, "123")
|
||||
model.set_user_input(0, 1, 2, "=A1*2")
|
||||
model.evaluate()
|
||||
|
||||
@@ -139,7 +139,7 @@ impl PyModel {
|
||||
/// Get raw value
|
||||
pub fn get_cell_content(&self, sheet: u32, row: i32, column: i32) -> PyResult<String> {
|
||||
self.model
|
||||
.get_cell_content(sheet, row, column)
|
||||
.get_localized_cell_content(sheet, row, column)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))
|
||||
}
|
||||
|
||||
@@ -329,17 +329,22 @@ impl PyModel {
|
||||
|
||||
/// Loads a function from an xlsx file
|
||||
#[pyfunction]
|
||||
pub fn load_from_xlsx(file_path: &str, locale: &str, tz: &str) -> PyResult<PyModel> {
|
||||
let model = import::load_from_xlsx(file_path, locale, tz)
|
||||
pub fn load_from_xlsx(
|
||||
file_path: &str,
|
||||
locale: &str,
|
||||
tz: &str,
|
||||
language_id: &str,
|
||||
) -> PyResult<PyModel> {
|
||||
let model = import::load_from_xlsx(file_path, locale, tz, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
Ok(PyModel { model })
|
||||
}
|
||||
|
||||
/// Loads a function from icalc binary representation
|
||||
#[pyfunction]
|
||||
pub fn load_from_icalc(file_name: &str) -> PyResult<PyModel> {
|
||||
let model =
|
||||
import::load_from_icalc(file_name).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
pub fn load_from_icalc(file_name: &str, language_id: &str) -> PyResult<PyModel> {
|
||||
let model = import::load_from_icalc(file_name, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
Ok(PyModel { model })
|
||||
}
|
||||
|
||||
@@ -347,26 +352,31 @@ pub fn load_from_icalc(file_name: &str) -> PyResult<PyModel> {
|
||||
/// This function expects the bytes to be in the internal binary ic format
|
||||
/// which is the same format used by the `save_to_icalc` function.
|
||||
#[pyfunction]
|
||||
pub fn load_from_bytes(bytes: &[u8]) -> PyResult<PyModel> {
|
||||
pub fn load_from_bytes(bytes: &[u8], language_id: &str) -> PyResult<PyModel> {
|
||||
let workbook: Workbook =
|
||||
bitcode::decode(bytes).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model =
|
||||
Model::from_workbook(workbook).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model = Model::from_workbook(workbook, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
Ok(PyModel { model })
|
||||
}
|
||||
|
||||
/// Creates an empty model in the raw API
|
||||
#[pyfunction]
|
||||
pub fn create(name: &str, locale: &str, tz: &str) -> PyResult<PyModel> {
|
||||
let model =
|
||||
Model::new_empty(name, locale, tz).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
pub fn create(name: &str, locale: &str, tz: &str, language_id: &str) -> PyResult<PyModel> {
|
||||
let model = Model::new_empty(name, locale, tz, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
Ok(PyModel { model })
|
||||
}
|
||||
|
||||
/// Creates a model with the user model API
|
||||
#[pyfunction]
|
||||
pub fn create_user_model(name: &str, locale: &str, tz: &str) -> PyResult<PyUserModel> {
|
||||
let model = UserModel::new_empty(name, locale, tz)
|
||||
pub fn create_user_model(
|
||||
name: &str,
|
||||
locale: &str,
|
||||
tz: &str,
|
||||
language_id: &str,
|
||||
) -> PyResult<PyUserModel> {
|
||||
let model = UserModel::new_empty(name, locale, tz, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
Ok(PyUserModel { model })
|
||||
}
|
||||
@@ -377,8 +387,9 @@ pub fn create_user_model_from_xlsx(
|
||||
file_path: &str,
|
||||
locale: &str,
|
||||
tz: &str,
|
||||
language_id: &str,
|
||||
) -> PyResult<PyUserModel> {
|
||||
let model = import::load_from_xlsx(file_path, locale, tz)
|
||||
let model = import::load_from_xlsx(file_path, locale, tz, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model = UserModel::from_model(model);
|
||||
Ok(PyUserModel { model })
|
||||
@@ -386,9 +397,9 @@ pub fn create_user_model_from_xlsx(
|
||||
|
||||
/// Creates a user model from an icalc file
|
||||
#[pyfunction]
|
||||
pub fn create_user_model_from_icalc(file_name: &str) -> PyResult<PyUserModel> {
|
||||
let model =
|
||||
import::load_from_icalc(file_name).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
pub fn create_user_model_from_icalc(file_name: &str, language_id: &str) -> PyResult<PyUserModel> {
|
||||
let model = import::load_from_icalc(file_name, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model = UserModel::from_model(model);
|
||||
Ok(PyUserModel { model })
|
||||
}
|
||||
@@ -397,11 +408,11 @@ pub fn create_user_model_from_icalc(file_name: &str) -> PyResult<PyUserModel> {
|
||||
/// This function expects the bytes to be in the internal binary ic format
|
||||
/// which is the same format used by the `save_to_icalc` function.
|
||||
#[pyfunction]
|
||||
pub fn create_user_model_from_bytes(bytes: &[u8]) -> PyResult<PyUserModel> {
|
||||
pub fn create_user_model_from_bytes(bytes: &[u8], language_id: &str) -> PyResult<PyUserModel> {
|
||||
let workbook: Workbook =
|
||||
bitcode::decode(bytes).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model =
|
||||
Model::from_workbook(workbook).map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let model = Model::from_workbook(workbook, language_id)
|
||||
.map_err(|e| WorkbookError::new_err(e.to_string()))?;
|
||||
let user_model = UserModel::from_model(model);
|
||||
Ok(PyUserModel { model: user_model })
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ironcalc as ic
|
||||
|
||||
def test_simple():
|
||||
model = ic.create("model", "en", "UTC")
|
||||
model = ic.create("model", "en", "UTC", "en")
|
||||
model.set_user_input(0, 1, 1, "=1+2")
|
||||
model.evaluate()
|
||||
|
||||
@@ -9,12 +9,12 @@ def test_simple():
|
||||
|
||||
bytes = model.to_bytes()
|
||||
|
||||
model2 = ic.load_from_bytes(bytes)
|
||||
model2 = ic.load_from_bytes(bytes, "en")
|
||||
assert model2.get_formatted_cell_value(0, 1, 1) == "3"
|
||||
|
||||
|
||||
def test_simple_user():
|
||||
model = ic.create_user_model("model", "en", "UTC")
|
||||
model = ic.create_user_model("model", "en", "UTC", "en")
|
||||
model.set_user_input(0, 1, 1, "=1+2")
|
||||
model.set_user_input(0, 1, 2, "=A1+3")
|
||||
|
||||
@@ -23,7 +23,7 @@ def test_simple_user():
|
||||
|
||||
diffs = model.flush_send_queue()
|
||||
|
||||
model2 = ic.create_user_model("model", "en", "UTC")
|
||||
model2 = ic.create_user_model("model", "en", "UTC", "en")
|
||||
model2.apply_external_diffs(diffs)
|
||||
assert model2.get_formatted_cell_value(0, 1, 1) == "3"
|
||||
assert model2.get_formatted_cell_value(0, 1, 2) == "6"
|
||||
@@ -31,7 +31,7 @@ def test_simple_user():
|
||||
|
||||
def test_sheet_dimensions():
|
||||
# Test with empty sheet
|
||||
model = ic.create("model", "en", "UTC")
|
||||
model = ic.create("model", "en", "UTC", "en")
|
||||
min_row, max_row, min_col, max_col = model.get_sheet_dimensions(0)
|
||||
assert (min_row, max_row, min_col, max_col) == (1, 1, 1, 1)
|
||||
|
||||
@@ -47,7 +47,7 @@ def test_sheet_dimensions():
|
||||
|
||||
def test_sheet_dimensions_user_model():
|
||||
# Test with user model API as well
|
||||
model = ic.create_user_model("model", "en", "UTC")
|
||||
model = ic.create_user_model("model", "en", "UTC", "en")
|
||||
|
||||
# Add a single cell
|
||||
model.set_user_input(0, 2, 3, "Test")
|
||||
|
||||
@@ -40,6 +40,18 @@ pub fn quote_name(name: &str) -> String {
|
||||
quote_name_ic(name)
|
||||
}
|
||||
|
||||
/// Gets all timezones
|
||||
#[wasm_bindgen(js_name = "getAllTimezones")]
|
||||
pub fn get_all_timezones() -> Vec<String> {
|
||||
ironcalc_base::get_all_timezones()
|
||||
}
|
||||
|
||||
/// Gets all supported locales
|
||||
#[wasm_bindgen(js_name = "getSupportedLocales")]
|
||||
pub fn get_supported_locales() -> Vec<String> {
|
||||
ironcalc_base::get_supported_locales()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DefinedName {
|
||||
name: String,
|
||||
@@ -55,13 +67,19 @@ pub struct Model {
|
||||
#[wasm_bindgen]
|
||||
impl Model {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(name: &str, locale: &str, timezone: &str) -> Result<Model, JsError> {
|
||||
let model = BaseModel::new_empty(name, locale, timezone).map_err(to_js_error)?;
|
||||
pub fn new(
|
||||
name: &str,
|
||||
locale: &str,
|
||||
timezone: &str,
|
||||
language_id: &str,
|
||||
) -> Result<Model, JsError> {
|
||||
let model =
|
||||
BaseModel::new_empty(name, locale, timezone, language_id).map_err(to_js_error)?;
|
||||
Ok(Model { model })
|
||||
}
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Model, JsError> {
|
||||
let model = BaseModel::from_bytes(bytes).map_err(to_js_error)?;
|
||||
pub fn from_bytes(bytes: &[u8], language_id: &str) -> Result<Model, JsError> {
|
||||
let model = BaseModel::from_bytes(bytes, language_id).map_err(to_js_error)?;
|
||||
Ok(Model { model })
|
||||
}
|
||||
|
||||
@@ -788,4 +806,44 @@ impl Model {
|
||||
Err(e) => Err(to_js_error(e.to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "setTimezone")]
|
||||
pub fn set_timezone(&mut self, timezone: &str) -> Result<(), JsError> {
|
||||
self.model
|
||||
.set_timezone(timezone)
|
||||
.map_err(|e| to_js_error(e.to_string()))
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = "setLocale")]
|
||||
pub fn set_locale(&mut self, locale: &str) -> Result<(), JsError> {
|
||||
self.model
|
||||
.set_locale(locale)
|
||||
.map_err(|e| to_js_error(e.to_string()))
|
||||
}
|
||||
|
||||
/// Gets the timezone of the model
|
||||
#[wasm_bindgen(js_name = "getTimezone")]
|
||||
pub fn get_timezone(&self) -> String {
|
||||
self.model.get_timezone()
|
||||
}
|
||||
|
||||
/// Gets the locale of the model
|
||||
#[wasm_bindgen(js_name = "getLocale")]
|
||||
pub fn get_locale(&self) -> String {
|
||||
self.model.get_locale()
|
||||
}
|
||||
|
||||
/// Gets the language of the model
|
||||
#[wasm_bindgen(js_name = "getLanguage")]
|
||||
pub fn get_language(&self) -> String {
|
||||
self.model.get_language()
|
||||
}
|
||||
|
||||
/// Sets the language of the model
|
||||
#[wasm_bindgen(js_name = "setLanguage")]
|
||||
pub fn set_language(&mut self, language: &str) -> Result<(), JsError> {
|
||||
self.model
|
||||
.set_language(language)
|
||||
.map_err(|e| to_js_error(e.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Model } from "../pkg/wasm.js";
|
||||
const DEFAULT_ROW_HEIGHT = 28;
|
||||
|
||||
test('Frozen rows and columns', () => {
|
||||
let model = new Model('Workbook1', 'en', 'UTC');
|
||||
let model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
assert.strictEqual(model.getFrozenRowsCount(0), 0);
|
||||
assert.strictEqual(model.getFrozenColumnsCount(0), 0);
|
||||
|
||||
@@ -17,7 +17,7 @@ test('Frozen rows and columns', () => {
|
||||
});
|
||||
|
||||
test('Row height', () => {
|
||||
let model = new Model('Workbook1', 'en', 'UTC');
|
||||
let model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
assert.strictEqual(model.getRowHeight(0, 3), DEFAULT_ROW_HEIGHT);
|
||||
|
||||
model.setRowsHeight(0, 3, 3, 32);
|
||||
@@ -34,7 +34,7 @@ test('Row height', () => {
|
||||
});
|
||||
|
||||
test('Evaluates correctly', (t) => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, "23");
|
||||
model.setUserInput(0, 1, 2, "=A1*3+1");
|
||||
|
||||
@@ -43,7 +43,7 @@ test('Evaluates correctly', (t) => {
|
||||
});
|
||||
|
||||
test('Styles work', () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
let style = model.getCellStyle(0, 1, 1);
|
||||
assert.deepEqual(style, {
|
||||
num_fmt: 'general',
|
||||
@@ -76,7 +76,7 @@ test('Styles work', () => {
|
||||
});
|
||||
|
||||
test("Add sheets", (t) => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.newSheet();
|
||||
model.renameSheet(1, "NewName");
|
||||
let props = model.getWorksheetsProperties();
|
||||
@@ -94,7 +94,7 @@ test("Add sheets", (t) => {
|
||||
});
|
||||
|
||||
test("invalid sheet index throws an exception", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
assert.throws(() => {
|
||||
model.setRowsHeight(1, 1, 1, 100);
|
||||
}, {
|
||||
@@ -104,7 +104,7 @@ test("invalid sheet index throws an exception", () => {
|
||||
});
|
||||
|
||||
test("invalid column throws an exception", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
assert.throws(() => {
|
||||
model.setRowsHeight(0, -1, 0, 100);
|
||||
}, {
|
||||
@@ -114,7 +114,7 @@ test("invalid column throws an exception", () => {
|
||||
});
|
||||
|
||||
test("floating column numbers get truncated", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setRowsHeight(0.8, 5.2, 5.5, 100.5);
|
||||
|
||||
assert.strictEqual(model.getRowHeight(0.11, 5.99), 100.5);
|
||||
@@ -122,7 +122,7 @@ test("floating column numbers get truncated", () => {
|
||||
});
|
||||
|
||||
test("autofill", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, "23");
|
||||
model.autoFillRows({sheet: 0, row: 1, column: 1, width: 1, height: 1}, 2);
|
||||
|
||||
@@ -131,7 +131,7 @@ test("autofill", () => {
|
||||
});
|
||||
|
||||
test('insertRows shifts cells', () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, '42');
|
||||
model.insertRows(0, 1, 1);
|
||||
|
||||
@@ -140,7 +140,7 @@ test('insertRows shifts cells', () => {
|
||||
});
|
||||
|
||||
test('insertColumns shifts cells', () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, 'A');
|
||||
model.setUserInput(0, 1, 2, 'B');
|
||||
|
||||
@@ -151,7 +151,7 @@ test('insertColumns shifts cells', () => {
|
||||
});
|
||||
|
||||
test('deleteRows removes cells', () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, '1');
|
||||
model.setUserInput(0, 2, 1, '2');
|
||||
|
||||
@@ -162,7 +162,7 @@ test('deleteRows removes cells', () => {
|
||||
});
|
||||
|
||||
test('deleteColumns removes cells', () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 1, 1, 'A');
|
||||
model.setUserInput(0, 1, 2, 'B');
|
||||
|
||||
@@ -173,7 +173,7 @@ test('deleteColumns removes cells', () => {
|
||||
});
|
||||
|
||||
test("move row", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 3, 5, "=G3");
|
||||
model.setUserInput(0, 4, 5, "=G4");
|
||||
model.setUserInput(0, 5, 5, "=SUM(G3:J3)");
|
||||
@@ -192,7 +192,7 @@ test("move row", () => {
|
||||
});
|
||||
|
||||
test("move column", () => {
|
||||
const model = new Model('Workbook1', 'en', 'UTC');
|
||||
const model = new Model('Workbook1', 'en', 'UTC', 'en');
|
||||
model.setUserInput(0, 3, 5, "=G3");
|
||||
model.setUserInput(0, 4, 5, "=H3");
|
||||
model.setUserInput(0, 5, 5, "=SUM(G3:J7)");
|
||||
|
||||
Reference in New Issue
Block a user