chore: fix unit test

This commit is contained in:
appflowy 2022-05-14 10:50:11 +08:00
parent c6edd1a6da
commit afc563d781
8 changed files with 97 additions and 68 deletions

View File

@ -2,7 +2,7 @@ part of 'cell_service.dart';
typedef GridCellContext = _GridCellContext<Cell, String>;
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCellPersistenceData>;
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCalData>;
class GridCellContextBuilder {
final GridCellCache _cellCache;

View File

@ -31,23 +31,26 @@ class CellDataPersistence implements _GridCellDataPersistence<String> {
}
@freezed
class DateCellPersistenceData with _$DateCellPersistenceData {
const factory DateCellPersistenceData({required DateTime date, String? time}) = _DateCellPersistenceData;
class DateCalData with _$DateCalData {
const factory DateCalData({required DateTime date, String? time}) = _DateCellPersistenceData;
}
class DateCellDataPersistence implements _GridCellDataPersistence<DateCellPersistenceData> {
class DateCellDataPersistence implements _GridCellDataPersistence<DateCalData> {
final GridCell gridCell;
DateCellDataPersistence({
required this.gridCell,
});
@override
Future<Option<FlowyError>> save(DateCellPersistenceData data) {
Future<Option<FlowyError>> save(DateCalData data) {
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
payload.date = date;
payload.time = data.time ?? "";
if (data.time != null) {
payload.time = data.time!;
}
return GridEventUpdateDateCell(payload).send().then((result) {
return result.fold(

View File

@ -9,7 +9,7 @@ import 'dart:async';
import 'cell_service/cell_service.dart';
import 'package:dartz/dartz.dart';
import 'package:protobuf/protobuf.dart';
// import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:fixnum/fixnum.dart' as $fixnum;
part 'date_cal_bloc.freezed.dart';
class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
@ -34,7 +34,11 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
setFocusedDay: (focusedDay) {
emit(state.copyWith(focusedDay: focusedDay));
},
didReceiveCellUpdate: (value) {},
didReceiveCellUpdate: (DateCellData cellData) {
final dateData = dateDataFromCellData(cellData);
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
emit(state.copyWith(dateData: dateData, time: time));
},
setIncludeTime: (includeTime) async {
await _updateTypeOption(emit, includeTime: includeTime);
},
@ -53,11 +57,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
}
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
final DateCellPersistenceData newDateData = state.dateData.fold(
() {
var newDateData = DateCellPersistenceData(date: date ?? DateTime.now());
return newDateData.copyWith(time: time);
},
final DateCalData newDateData = state.dateData.fold(
() => DateCalData(date: date ?? DateTime.now(), time: time),
(dateData) {
var newDateData = dateData;
if (date != null && !isSameDay(newDateData.date, date)) {
@ -74,7 +75,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
return _saveDateData(emit, newDateData);
}
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCellPersistenceData newDateData) async {
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCalData newDateData) async {
if (state.dateData == Some(newDateData)) {
return;
}
@ -173,31 +174,48 @@ class DateCalState with _$DateCalState {
required DateTypeOption dateTypeOption,
required CalendarFormat format,
required DateTime focusedDay,
required String time,
required Option<String> timeFormatError,
required Option<DateCellPersistenceData> dateData,
required Option<DateCalData> dateData,
required String? time,
}) = _DateCalState;
factory DateCalState.initial(
DateTypeOption dateTypeOption,
DateCellData? cellData,
) {
Option<DateCellPersistenceData> dateData = none();
final time = cellData?.time ?? "";
if (cellData != null) {
// final timestamp = $fixnum.Int64.parseInt(cellData.timestamp).toInt();
final timestamp = cellData.timestamp * 1000;
final selectedDay = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
dateData = Some(DateCellPersistenceData(date: selectedDay, time: time));
}
Option<DateCalData> dateData = dateDataFromCellData(cellData);
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
return DateCalState(
dateTypeOption: dateTypeOption,
format: CalendarFormat.month,
focusedDay: DateTime.now(),
dateData: dateData,
time: time,
dateData: dateData,
timeFormatError: none(),
);
}
}
Option<DateCalData> dateDataFromCellData(DateCellData? cellData) {
String? time = timeFromCellData(cellData);
Option<DateCalData> dateData = none();
if (cellData != null) {
final timestamp = cellData.timestamp * 1000;
final date = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
dateData = Some(DateCalData(date: date, time: time));
}
return dateData;
}
$fixnum.Int64 timestampFromDateTime(DateTime dateTime) {
final timestamp = (dateTime.millisecondsSinceEpoch ~/ 1000);
return $fixnum.Int64(timestamp);
}
String? timeFromCellData(DateCellData? cellData) {
String? time;
if (cellData?.hasTime() ?? false) {
time = cellData?.time;
}
return time;
}

View File

@ -254,7 +254,11 @@ class _TimeTextFieldState extends State<_TimeTextField> {
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return BlocBuilder<DateCalBloc, DateCalState>(
return BlocConsumer<DateCalBloc, DateCalState>(
listener: (context, state) {
_controller.text = state.time ?? "";
},
listenWhen: (p, c) => p.time != c.time,
builder: (context, state) {
if (state.dateTypeOption.includeTime) {
return Padding(

View File

@ -289,7 +289,7 @@ pub(crate) async fn get_date_cell_data_handler(
Some(field_meta) => {
let cell_meta = editor.get_cell_meta(&params.row_id, &params.field_id).await?;
let type_option = DateTypeOption::from(&field_meta);
let date_cell_data = type_option.date_cell_data(&cell_meta)?;
let date_cell_data = type_option.make_date_cell_data(&cell_meta)?;
data_result(date_cell_data)
}
}

View File

@ -5,14 +5,12 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
use bytes::Bytes;
use chrono::format::strftime::StrftimeItems;
use chrono::NaiveDateTime;
use diesel::types::Time;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
use flowy_grid_data_model::entities::{
CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
};
use serde::{Deserialize, Serialize};
use std::ops::Add;
use std::str::FromStr;
use strum_macros::EnumIter;
@ -79,7 +77,7 @@ impl DateTypeOption {
}
}
pub fn date_cell_data(&self, cell_meta: &Option<CellMeta>) -> FlowyResult<DateCellData> {
pub fn make_date_cell_data(&self, cell_meta: &Option<CellMeta>) -> FlowyResult<DateCellData> {
if cell_meta.is_none() {
return Ok(DateCellData::default());
}
@ -112,27 +110,28 @@ impl DateTypeOption {
utc: &chrono::DateTime<chrono::Utc>,
time: &Option<String>,
) -> FlowyResult<i64> {
let mut date_str = format!(
"{}",
utc.format_with_items(StrftimeItems::new(self.date_format.format_str()))
);
if let Some(time_str) = time.as_ref() {
if !time_str.is_empty() {
date_str = date_str.add(&time_str);
}
}
let fmt = self.date_fmt(time);
match NaiveDateTime::parse_from_str(&date_str, &fmt) {
Ok(native) => {
let utc = self.utc_date_time_from_native(native);
Ok(utc.timestamp())
}
Err(_e) => {
let msg = format!("Parse {} with format: {} failed", date_str, fmt);
Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg))
let date_str = format!(
"{}{}",
utc.format_with_items(StrftimeItems::new(self.date_format.format_str())),
&time_str
);
return match NaiveDateTime::parse_from_str(&date_str, &self.date_fmt(time)) {
Ok(native) => {
let utc = self.utc_date_time_from_native(native);
Ok(utc.timestamp())
}
Err(_e) => {
let msg = format!("Parse {} failed", date_str);
Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg))
}
};
}
}
return Ok(utc.timestamp());
}
}
@ -170,7 +169,7 @@ impl CellDataOperation for DateTypeOption {
let timestamp = self.timestamp_from_utc_with_time(&utc, &time)?;
DateCellDataSerde::new(timestamp, time, &self.time_format)
}
_ => DateCellDataSerde::from_timestamp(date_timestamp, &self.time_format),
_ => DateCellDataSerde::from_timestamp(date_timestamp, Some(default_time_str(&self.time_format))),
},
};
@ -312,11 +311,8 @@ impl DateCellDataSerde {
}
}
fn from_timestamp(timestamp: i64, time_format: &TimeFormat) -> Self {
Self {
timestamp,
time: Some(default_time_str(time_format)),
}
pub(crate) fn from_timestamp(timestamp: i64, time: Option<String>) -> Self {
Self { timestamp, time }
}
fn to_string(self) -> String {
@ -614,11 +610,7 @@ mod tests {
}
fn data(s: i64) -> String {
let json = serde_json::to_string(&DateCellDataSerde {
timestamp: s,
time: None,
})
.unwrap();
let json = serde_json::to_string(&DateCellDataSerde::from_timestamp(s, None)).unwrap();
TypeOptionCellData::new(&json, FieldType::DateTime).json()
}
}

View File

@ -78,7 +78,8 @@ mod tests {
// date
let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json();
let json = serde_json::to_string(&DateCellDataSerde::from_timestamp(1647251762, None)).unwrap();
let data = TypeOptionCellData::new(&json, FieldType::DateTime).json();
assert_eq!(
type_option.decode_cell_data(data, &date_time_field_meta).content,
"Mar 14,2022".to_owned()

View File

@ -2,8 +2,8 @@ use crate::grid::script::EditorScript::*;
use crate::grid::script::*;
use chrono::NaiveDateTime;
use flowy_grid::services::field::{
MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset, SingleSelectTypeOption,
SELECTION_IDS_SEPARATOR,
DateCellContentChangeset, MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset,
SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
};
use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder};
use flowy_grid_data_model::entities::{
@ -240,7 +240,9 @@ async fn grid_row_add_cells_test() {
builder.add_cell(&field.id, "18,443".to_owned()).unwrap();
}
FieldType::DateTime => {
builder.add_cell(&field.id, "1647251762".to_owned()).unwrap();
builder
.add_cell(&field.id, make_date_cell_string("1647251762"))
.unwrap();
}
FieldType::SingleSelect => {
let type_option = SingleSelectTypeOption::from(field);
@ -278,10 +280,11 @@ async fn grid_row_add_date_cell_test() {
date_field = Some(field.clone());
NaiveDateTime::from_timestamp(123, 0);
// The data should not be empty
assert!(builder.add_cell(&field.id, "".to_owned()).is_err());
assert!(builder.add_cell(&field.id, "123".to_owned()).is_ok());
assert!(builder.add_cell(&field.id, format!("{}", timestamp)).is_ok());
assert!(builder.add_cell(&field.id, "".to_string()).is_err());
assert!(builder.add_cell(&field.id, make_date_cell_string("123")).is_ok());
assert!(builder
.add_cell(&field.id, make_date_cell_string(&timestamp.to_string()))
.is_ok());
}
}
let context = builder.build();
@ -315,7 +318,7 @@ async fn grid_cell_update() {
let data = match field_meta.field_type {
FieldType::RichText => "".to_string(),
FieldType::Number => "123".to_string(),
FieldType::DateTime => "123".to_string(),
FieldType::DateTime => make_date_cell_string("123"),
FieldType::SingleSelect => {
let type_option = SingleSelectTypeOption::from(field_meta);
SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
@ -363,3 +366,11 @@ async fn grid_cell_update() {
test.run_scripts(scripts).await;
}
fn make_date_cell_string(s: &str) -> String {
serde_json::to_string(&DateCellContentChangeset {
date: Some(s.to_string()),
time: None,
})
.unwrap()
}