mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 07:12:20 +03:00
Small changes from Book Club issues (#6533)
- Add dropdown to tokenize and split `column`. - Remove the custom `Join_Kind` dropdown. - Adjust split and tokenize names to start numbering from 1, not 0. - Add JS_Object serialization for Period. - Add `days_until` and `until` to `Date`. - Add `Date_Period.Day` and create `next` and `previous` on `Date`. - Use simple names with `File_Format` dropdown. - Avoid using `Main.enso` based imports in `Standard.Base.Data.Map` and `Standard.Base.Data.Text.Helpers`. - Remove an incorrect import from `Standard.Database.Data.Table`. From #6587: A few small changes, lots of lines because this affected lots of tests: - `Table.join` now defaults to `Join_Kind.Left_Outer`, to avoid losing rows in the left table unexpectedly. If the user really wants to have an Inner join, they can switch to it. - `Table.join` now defaults to joining columns by name not by index - it looks in the right table for a column with the same name as the first column in left table. - Missing Input Column errors now specify which table they refer to in the join. - The unique name suffix in column renaming / default column names when loading from file is now a space instead of underscore.
This commit is contained in:
parent
f7282b7cff
commit
bc0db18a6e
@ -1,13 +1,16 @@
|
|||||||
|
import project.Any.Any
|
||||||
import project.Data.Numbers.Integer
|
import project.Data.Numbers.Integer
|
||||||
import project.Data.Vector.Vector
|
import project.Data.Vector.Vector
|
||||||
import project.Data.Pair.Pair
|
import project.Data.Pair.Pair
|
||||||
import project.Data.Text.Extensions
|
import project.Data.Text.Extensions
|
||||||
import project.Data.Text.Text
|
import project.Data.Text.Text
|
||||||
|
import project.Error.Error
|
||||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||||
import project.Errors.No_Such_Key.No_Such_Key
|
import project.Errors.No_Such_Key.No_Such_Key
|
||||||
|
import project.Nothing.Nothing
|
||||||
|
import project.Panic.Panic
|
||||||
|
|
||||||
from project.Data.Boolean import Boolean, True, False
|
from project.Data.Boolean import Boolean, True, False
|
||||||
from project import Error, Nothing, Any, Panic
|
|
||||||
|
|
||||||
## A key-value store. It is possible to use any type as keys and values and mix them in
|
## A key-value store. It is possible to use any type as keys and values and mix them in
|
||||||
one Map. Keys are checked for equality based on their hash code and `==` operator, which
|
one Map. Keys are checked for equality based on their hash code and `==` operator, which
|
||||||
|
@ -900,7 +900,7 @@ Text.repeat : Integer -> Text
|
|||||||
Text.repeat self count=1 =
|
Text.repeat self count=1 =
|
||||||
0.up_to count . fold "" acc-> _-> acc + self
|
0.up_to count . fold "" acc-> _-> acc + self
|
||||||
|
|
||||||
## ALIAS first, last, left, right, mid, substring
|
## ALIAS first, last, left, right, mid, substring, slice
|
||||||
Creates a new Text by selecting the specified range of the input.
|
Creates a new Text by selecting the specified range of the input.
|
||||||
|
|
||||||
This can select a section of text from the beginning, end, or middle of the
|
This can select a section of text from the beginning, end, or middle of the
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
from Standard.Base import all
|
|
||||||
|
|
||||||
import project.Any.Any
|
import project.Any.Any
|
||||||
import project.Data.Locale.Locale
|
import project.Data.Text.Text
|
||||||
import project.Data.Text.Case_Sensitivity.Case_Sensitivity
|
import project.Error.Error
|
||||||
import project.Errors.Common.Type_Error
|
import project.Errors.Common.Type_Error
|
||||||
import project.Meta
|
import project.Meta
|
||||||
|
|
||||||
|
@ -314,6 +314,54 @@ type Date
|
|||||||
end_of : Date_Period -> Date
|
end_of : Date_Period -> Date
|
||||||
end_of self period=Date_Period.Month = period.adjust_end self
|
end_of self period=Date_Period.Month = period.adjust_end self
|
||||||
|
|
||||||
|
## Returns the next date adding the `Date_Period` to self.
|
||||||
|
|
||||||
|
Produces a warning for a Date that is before epoch start.
|
||||||
|
See `Date_Time.enso_epoch_start`.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- period: the period to add to self.
|
||||||
|
next : Date_Period -> Date
|
||||||
|
next self period=Date_Period.Day = self + period.to_period
|
||||||
|
|
||||||
|
## Returns the previous date subtracting the `Date_Period` from self.
|
||||||
|
|
||||||
|
Produces a warning for a Date that is before epoch start.
|
||||||
|
See `Date_Time.enso_epoch_start`.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- period: the period to add to self.
|
||||||
|
previous : Date_Period -> Date
|
||||||
|
previous self period=Date_Period.Day = self - period.to_period
|
||||||
|
|
||||||
|
## Creates a `Period` between self and the provided end date.
|
||||||
|
|
||||||
|
Produces a warning for a Date that is before epoch start.
|
||||||
|
See `Date_Time.enso_epoch_start`.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- end: the end date of the interval to count workdays in.
|
||||||
|
until : Date -> Period
|
||||||
|
until self end =
|
||||||
|
ensure_in_epoch self <| ensure_in_epoch end <|
|
||||||
|
Period.between self end
|
||||||
|
|
||||||
|
## Counts the days between self (inclusive) and the provided end date
|
||||||
|
(exclusive).
|
||||||
|
|
||||||
|
Produces a warning for a Date that is before epoch start.
|
||||||
|
See `Date_Time.enso_epoch_start`.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- end: the end date of the interval to count workdays in.
|
||||||
|
- include_end_date: whether to include the end date in the count.
|
||||||
|
By default the end date is not included in the interval.
|
||||||
|
days_until : Date -> Boolean -> Integer
|
||||||
|
days_until self end include_end_date=False =
|
||||||
|
if end < self then -(end.days_until self include_end_date) else
|
||||||
|
ensure_in_epoch self <| ensure_in_epoch end <|
|
||||||
|
(Time_Utils.days_between self end) + if include_end_date then 1 else 0
|
||||||
|
|
||||||
## Counts workdays between self (inclusive) and the provided end date
|
## Counts workdays between self (inclusive) and the provided end date
|
||||||
(exclusive).
|
(exclusive).
|
||||||
|
|
||||||
@ -331,7 +379,7 @@ type Date
|
|||||||
end-exclusive manner), by default the end date is not included in the
|
end-exclusive manner), by default the end date is not included in the
|
||||||
count. This has the nice property that for example to count the work
|
count. This has the nice property that for example to count the work
|
||||||
days within the next week you can do
|
days within the next week you can do
|
||||||
`date.work_days_until (date + (Period.new days=7)` and it will look at
|
`date.work_days_until (date + (Period.new days=7))` and it will look at
|
||||||
the 7 days starting from the current `date` and not 8 days. This also
|
the 7 days starting from the current `date` and not 8 days. This also
|
||||||
gives us a property that
|
gives us a property that
|
||||||
`date.work_days_until (date.add_work_days N) == N` for any non-negative
|
`date.work_days_until (date.add_work_days N) == N` for any non-negative
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import project.Data.Time.Date.Date
|
import project.Data.Time.Date.Date
|
||||||
|
import project.Data.Time.Period.Period
|
||||||
import project.Data.Time.Date_Time.Date_Time
|
import project.Data.Time.Date_Time.Date_Time
|
||||||
import project.Data.Time.Day_Of_Week.Day_Of_Week
|
import project.Data.Time.Day_Of_Week.Day_Of_Week
|
||||||
from project.Data.Boolean import Boolean, True, False
|
from project.Data.Boolean import Boolean, True, False
|
||||||
@ -22,6 +23,8 @@ type Date_Period
|
|||||||
to any other day.
|
to any other day.
|
||||||
Week (first_day:Day_Of_Week = Day_Of_Week.Monday)
|
Week (first_day:Day_Of_Week = Day_Of_Week.Monday)
|
||||||
|
|
||||||
|
Day
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
This method could be replaced with matching on `Date_Period` supertype
|
This method could be replaced with matching on `Date_Period` supertype
|
||||||
if/when that is supported.
|
if/when that is supported.
|
||||||
@ -36,14 +39,25 @@ type Date_Period
|
|||||||
Date_Period.Quarter -> Date_Period_Utils.quarter_start
|
Date_Period.Quarter -> Date_Period_Utils.quarter_start
|
||||||
Date_Period.Month -> TemporalAdjusters.firstDayOfMonth
|
Date_Period.Month -> TemporalAdjusters.firstDayOfMonth
|
||||||
Date_Period.Week first_day -> TemporalAdjusters.previousOrSame first_day.to_java
|
Date_Period.Week first_day -> TemporalAdjusters.previousOrSame first_day.to_java
|
||||||
|
Date_Period.Day -> Date_Period_Utils.day_start
|
||||||
(Time_Utils.utils_for date).apply_adjuster date adjuster
|
(Time_Utils.utils_for date).apply_adjuster date adjuster
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
adjust_end : (Date | Date_Time) -> (Date | Date_Time)
|
adjust_end : (Date | Date_Time) -> (Date | Date_Time)
|
||||||
adjust_end self date =
|
adjust_end self date = if self == Date_Period.Day then date else
|
||||||
adjuster = case self of
|
adjuster = case self of
|
||||||
Date_Period.Year -> TemporalAdjusters.lastDayOfYear
|
Date_Period.Year -> TemporalAdjusters.lastDayOfYear
|
||||||
Date_Period.Quarter -> Date_Period_Utils.quarter_end
|
Date_Period.Quarter -> Date_Period_Utils.quarter_end
|
||||||
Date_Period.Month -> TemporalAdjusters.lastDayOfMonth
|
Date_Period.Month -> TemporalAdjusters.lastDayOfMonth
|
||||||
Date_Period.Week first_day -> Date_Period_Utils.end_of_week first_day.to_java
|
Date_Period.Week first_day -> Date_Period_Utils.end_of_week first_day.to_java
|
||||||
|
Date_Period.Day -> Date_Period_Utils.day_end
|
||||||
(Time_Utils.utils_for date).apply_adjuster date adjuster
|
(Time_Utils.utils_for date).apply_adjuster date adjuster
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
to_period : Period
|
||||||
|
to_period self = case self of
|
||||||
|
Date_Period.Year -> Period.new years=1
|
||||||
|
Date_Period.Quarter -> Period.new months=3
|
||||||
|
Date_Period.Month -> Period.new months=1
|
||||||
|
Date_Period.Week _ -> Period.new days=7
|
||||||
|
Date_Period.Day -> Period.new days=1
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import project.Any.Any
|
import project.Any.Any
|
||||||
|
import project.Data.Json.JS_Object
|
||||||
import project.Data.Numbers.Integer
|
import project.Data.Numbers.Integer
|
||||||
import project.Data.Ordering.Comparable
|
import project.Data.Ordering.Comparable
|
||||||
import project.Data.Text.Extensions
|
import project.Data.Text.Extensions
|
||||||
import project.Data.Text.Text
|
import project.Data.Text.Text
|
||||||
import project.Data.Time.Date.Date
|
import project.Data.Time.Date.Date
|
||||||
import project.Data.Time.Duration.Duration
|
import project.Data.Time.Duration.Duration
|
||||||
|
import project.Data.Vector.Vector
|
||||||
import project.Error.Error
|
import project.Error.Error
|
||||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||||
import project.Errors.Time_Error.Time_Error
|
import project.Errors.Time_Error.Time_Error
|
||||||
@ -144,3 +146,20 @@ type Period
|
|||||||
m = if months == 0 && (y=="" || d=="") then "" else months.to_text + "M "
|
m = if months == 0 && (y=="" || d=="") then "" else months.to_text + "M "
|
||||||
|
|
||||||
(y + m + d) . trim
|
(y + m + d) . trim
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Convert to a JavaScript Object representing a Period.
|
||||||
|
|
||||||
|
> Example
|
||||||
|
Convert a period of 10 months to a JS_Object.
|
||||||
|
|
||||||
|
example_to_json = (Period.new months=10).to_js_object
|
||||||
|
to_js_object : JS_Object
|
||||||
|
to_js_object self =
|
||||||
|
b = Vector.new_builder 7
|
||||||
|
b.append ["type", "Period"]
|
||||||
|
b.append ["constructor", "new"]
|
||||||
|
if self.years==0 . not then b.append ["years", self.years]
|
||||||
|
if self.months==0 . not then b.append ["months", self.months]
|
||||||
|
if self.days==0 . not then b.append ["days", self.days]
|
||||||
|
JS_Object.from_pairs b.to_vector
|
||||||
|
@ -45,7 +45,7 @@ format_widget : Single_Choice
|
|||||||
format_widget =
|
format_widget =
|
||||||
all_types = [Auto_Detect] + format_types
|
all_types = [Auto_Detect] + format_types
|
||||||
make_ctor type_obj =
|
make_ctor type_obj =
|
||||||
type_name = Meta.get_qualified_type_name type_obj
|
type_name = Meta.get_simple_type_name type_obj
|
||||||
ctors = Meta.meta type_obj . constructors
|
ctors = Meta.meta type_obj . constructors
|
||||||
is_singleton_type = ctors.length == 0
|
is_singleton_type = ctors.length == 0
|
||||||
if is_singleton_type then type_name else
|
if is_singleton_type then type_name else
|
||||||
|
@ -8,7 +8,7 @@ import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
|||||||
import Standard.Base.Errors.Illegal_State.Illegal_State
|
import Standard.Base.Errors.Illegal_State.Illegal_State
|
||||||
import Standard.Base.Errors.Unimplemented.Unimplemented
|
import Standard.Base.Errors.Unimplemented.Unimplemented
|
||||||
|
|
||||||
from Standard.Table import Auto_Detect, Aggregate_Column, Data_Formatter, Column_Selector, Sort_Column, Match_Columns, Position, Set_Mode, Auto, Value_Type
|
from Standard.Table import Aggregate_Column, Data_Formatter, Column_Selector, Sort_Column, Match_Columns, Position, Set_Mode, Auto, Value_Type
|
||||||
import Standard.Table.Data.Expression.Expression
|
import Standard.Table.Data.Expression.Expression
|
||||||
import Standard.Table.Data.Expression.Expression_Error
|
import Standard.Table.Data.Expression.Expression_Error
|
||||||
import Standard.Table.Data.Join_Condition.Join_Condition
|
import Standard.Table.Data.Join_Condition.Join_Condition
|
||||||
@ -23,6 +23,7 @@ import Standard.Table.Internal.Java_Exports
|
|||||||
import Standard.Table.Internal.Table_Helpers
|
import Standard.Table.Internal.Table_Helpers
|
||||||
import Standard.Table.Internal.Table_Helpers.Table_Column_Helper
|
import Standard.Table.Internal.Table_Helpers.Table_Column_Helper
|
||||||
import Standard.Table.Internal.Problem_Builder.Problem_Builder
|
import Standard.Table.Internal.Problem_Builder.Problem_Builder
|
||||||
|
import Standard.Table.Internal.Unique_Name_Strategy.Unique_Name_Strategy
|
||||||
import Standard.Table.Internal.Widget_Helpers
|
import Standard.Table.Internal.Widget_Helpers
|
||||||
from Standard.Table.Data.Column import get_item_string, normalize_string_for_display
|
from Standard.Table.Data.Column import get_item_string, normalize_string_for_display
|
||||||
from Standard.Table.Data.Table import print_table
|
from Standard.Table.Data.Table import print_table
|
||||||
@ -187,6 +188,7 @@ type Table
|
|||||||
table.select_columns [-1, 0, 1] reorder=True
|
table.select_columns [-1, 0, 1] reorder=True
|
||||||
|
|
||||||
Icon: select_column
|
Icon: select_column
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
select_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
select_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
select_columns self (columns = [0]) (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) =
|
select_columns self (columns = [0]) (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
||||||
@ -239,6 +241,7 @@ type Table
|
|||||||
Remove the first two columns and the last column.
|
Remove the first two columns and the last column.
|
||||||
|
|
||||||
table.remove_columns [-1, 0, 1]
|
table.remove_columns [-1, 0, 1]
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
remove_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
remove_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
remove_columns self (columns = [0]) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
remove_columns self (columns = [0]) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
||||||
@ -294,6 +297,7 @@ type Table
|
|||||||
Move the first column to back.
|
Move the first column to back.
|
||||||
|
|
||||||
table.reorder_columns [0] position=Position.After_Other_Columns
|
table.reorder_columns [0] position=Position.After_Other_Columns
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
reorder_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
reorder_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
reorder_columns self (columns = [0]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
reorder_columns self (columns = [0]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns on_problems=on_problems
|
||||||
@ -617,6 +621,7 @@ type Table
|
|||||||
double_inventory = table.at "total_stock" * 2
|
double_inventory = table.at "total_stock" * 2
|
||||||
table.set double_inventory new_name="total_stock"
|
table.set double_inventory new_name="total_stock"
|
||||||
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
||||||
|
@new_name Widget_Helpers.make_column_name_selector
|
||||||
set : Column | Text -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Unsupported_Name | Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
set : Column | Text -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Unsupported_Name | Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||||
set self column new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
set self column new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||||
resolved = case column of
|
resolved = case column of
|
||||||
@ -794,6 +799,7 @@ type Table
|
|||||||
Sort the table by columns whose names start with letter `a`.
|
Sort the table by columns whose names start with letter `a`.
|
||||||
|
|
||||||
table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)]
|
table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)]
|
||||||
|
@columns Widget_Helpers.make_order_by_selector
|
||||||
order_by : Text | Sort_Column | Vector (Text | Sort_Column) -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
order_by : Text | Sort_Column | Vector (Text | Sort_Column) -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning = Panic.handle_wrapped_dataflow_error <|
|
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning = Panic.handle_wrapped_dataflow_error <|
|
||||||
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
|
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
|
||||||
@ -843,6 +849,7 @@ type Table
|
|||||||
- If floating points values are present in the distinct columns, a
|
- If floating points values are present in the distinct columns, a
|
||||||
`Floating_Point_Equality` is reported according to the `on_problems`
|
`Floating_Point_Equality` is reported according to the `on_problems`
|
||||||
setting.
|
setting.
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
distinct : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
|
distinct : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
|
||||||
distinct self columns=self.column_names case_sensitivity=Case_Sensitivity.Default error_on_missing_columns=True on_problems=Report_Warning =
|
distinct self columns=self.column_names case_sensitivity=Case_Sensitivity.Default error_on_missing_columns=True on_problems=Report_Warning =
|
||||||
key_columns = self.columns_helper.select_columns selectors=columns reorder=True error_on_missing_columns=error_on_missing_columns on_problems=on_problems . catch No_Output_Columns _->
|
key_columns = self.columns_helper.select_columns selectors=columns reorder=True error_on_missing_columns=error_on_missing_columns on_problems=on_problems . catch No_Output_Columns _->
|
||||||
@ -855,12 +862,15 @@ type Table
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- right: The table to join with.
|
- right: The table to join with.
|
||||||
- join_kind: The `Join_Kind` for the joining the two tables.
|
- join_kind: The `Join_Kind` for the joining the two tables. It defaults
|
||||||
|
to `Left_Outer`.
|
||||||
- on: A single condition or a common column name, or a list thereof, on
|
- on: A single condition or a common column name, or a list thereof, on
|
||||||
which to correlate rows from the two tables. If multiple conditions
|
which to correlate rows from the two tables. If multiple conditions
|
||||||
are supplied, rows are correlated only if all are true.
|
are supplied, rows are correlated only if all are true.
|
||||||
If common column names are provided, these columns should be present
|
If common column names are provided, these columns should be present
|
||||||
in both tables and an equality condition is added for each of them.
|
in both tables and an equality condition is added for each of them.
|
||||||
|
By default, the join is performed on the first column of the left table
|
||||||
|
correlated with a column in the right table with the same name.
|
||||||
- right_prefix: The prefix added to right table column names in case of
|
- right_prefix: The prefix added to right table column names in case of
|
||||||
name conflict.
|
name conflict.
|
||||||
- on_problems: Specifies how to handle problems if they occur, reporting
|
- on_problems: Specifies how to handle problems if they occur, reporting
|
||||||
@ -908,10 +918,9 @@ type Table
|
|||||||
allows to join the two tables on equality of corresponding columns with
|
allows to join the two tables on equality of corresponding columns with
|
||||||
the same name. So `table.join other on=["A", "B"]` is a shorthand for:
|
the same name. So `table.join other on=["A", "B"]` is a shorthand for:
|
||||||
table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"]
|
table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"]
|
||||||
@join_kind Widget_Helpers.join_kind_selector
|
|
||||||
@on Widget_Helpers.make_column_name_selector
|
@on Widget_Helpers.make_column_name_selector
|
||||||
join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table
|
join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table
|
||||||
join self right join_kind=Join_Kind.Inner on=[Join_Condition.Equals 0 0] right_prefix="Right_" on_problems=Report_Warning =
|
join self right join_kind=Join_Kind.Left_Outer on=[Join_Condition.Equals self.column_names.first] right_prefix="Right " on_problems=Report_Warning =
|
||||||
can_proceed = if Table_Helpers.is_table right . not then Error.throw (Type_Error.Error Table right "right") else
|
can_proceed = if Table_Helpers.is_table right . not then Error.throw (Type_Error.Error Table right "right") else
|
||||||
same_backend = case right of
|
same_backend = case right of
|
||||||
_ : Table -> True
|
_ : Table -> True
|
||||||
@ -996,7 +1005,7 @@ type Table
|
|||||||
example, by sorting the table; in-memory tables will keep the memory
|
example, by sorting the table; in-memory tables will keep the memory
|
||||||
layout order while for database tables the order may be unspecified).
|
layout order while for database tables the order may be unspecified).
|
||||||
cross_join : Table -> Integer | Nothing -> Text -> Problem_Behavior -> Table
|
cross_join : Table -> Integer | Nothing -> Text -> Problem_Behavior -> Table
|
||||||
cross_join self right right_row_limit=100 right_prefix="Right_" on_problems=Report_Warning =
|
cross_join self right right_row_limit=100 right_prefix="Right " on_problems=Report_Warning =
|
||||||
_ = [right, right_row_limit, right_prefix, on_problems]
|
_ = [right, right_row_limit, right_prefix, on_problems]
|
||||||
Error.throw (Unsupported_Database_Operation.Error "Table.cross_join is not implemented yet for the Database backends.")
|
Error.throw (Unsupported_Database_Operation.Error "Table.cross_join is not implemented yet for the Database backends.")
|
||||||
|
|
||||||
@ -1045,7 +1054,7 @@ type Table
|
|||||||
order of columns is undefined and the operation will fail, reporting a
|
order of columns is undefined and the operation will fail, reporting a
|
||||||
`Undefined_Column_Order` problem and returning an empty table.
|
`Undefined_Column_Order` problem and returning an empty table.
|
||||||
zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table
|
zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table
|
||||||
zip self right keep_unmatched=Report_Unmatched right_prefix="Right_" on_problems=Report_Warning =
|
zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning =
|
||||||
_ = [right, keep_unmatched, right_prefix, on_problems]
|
_ = [right, keep_unmatched, right_prefix, on_problems]
|
||||||
Error.throw (Unsupported_Database_Operation.Error "Table.zip is not implemented yet for the Database backends.")
|
Error.throw (Unsupported_Database_Operation.Error "Table.zip is not implemented yet for the Database backends.")
|
||||||
|
|
||||||
@ -1340,6 +1349,7 @@ type Table
|
|||||||
- If any column names in the new table are clashing, a
|
- If any column names in the new table are clashing, a
|
||||||
`Duplicate_Output_Column_Names` is reported according to the
|
`Duplicate_Output_Column_Names` is reported according to the
|
||||||
`on_problems` setting.
|
`on_problems` setting.
|
||||||
|
@id_fields Widget_Helpers.make_column_name_vector_selector
|
||||||
transpose : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Text -> Text -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range | Duplicate_Output_Column_Names
|
transpose : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Text -> Text -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range | Duplicate_Output_Column_Names
|
||||||
transpose self id_fields=[] (name_field="Name") (value_field="Value") (error_on_missing_columns=True) (on_problems = Report_Warning) =
|
transpose self id_fields=[] (name_field="Name") (value_field="Value") (error_on_missing_columns=True) (on_problems = Report_Warning) =
|
||||||
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
||||||
@ -1382,6 +1392,9 @@ type Table
|
|||||||
an `Unquoted_Delimiter`
|
an `Unquoted_Delimiter`
|
||||||
- If there are more than 10 issues with a single column,
|
- If there are more than 10 issues with a single column,
|
||||||
an `Additional_Warnings`.
|
an `Additional_Warnings`.
|
||||||
|
@group_by Widget_Helpers.make_column_name_vector_selector
|
||||||
|
@name_column Widget_Helpers.make_column_name_selector
|
||||||
|
@values (Widget_Helpers.make_aggregate_column_selector include_group_by=False)
|
||||||
cross_tab : Aggregate_Column | Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector | Aggregate_Column) -> (Text | Integer | Column) -> Vector Aggregate_Column -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range | Invalid_Aggregate_Column | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings
|
cross_tab : Aggregate_Column | Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector | Aggregate_Column) -> (Text | Integer | Column) -> Vector Aggregate_Column -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range | Invalid_Aggregate_Column | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings
|
||||||
cross_tab self group_by=[] name_column=self.column_names.first values=Aggregate_Column.Count (on_problems=Report_Warning) =
|
cross_tab self group_by=[] name_column=self.column_names.first values=Aggregate_Column.Count (on_problems=Report_Warning) =
|
||||||
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
||||||
@ -1392,6 +1405,8 @@ type Table
|
|||||||
|
|
||||||
## Parsing values is not supported in database tables, the table has to be
|
## Parsing values is not supported in database tables, the table has to be
|
||||||
loaded into memory first with `read`.
|
loaded into memory first with `read`.
|
||||||
|
@type Widget_Helpers.parse_type_selector
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
parse : Text | Integer | Column_Selector | Vector (Text | Integer | Column_Selector) -> Value_Type | Auto -> Text | Data_Formatter -> Boolean -> Problem_Behavior -> Table
|
parse : Text | Integer | Column_Selector | Vector (Text | Integer | Column_Selector) -> Value_Type | Auto -> Text | Data_Formatter -> Boolean -> Problem_Behavior -> Table
|
||||||
parse columns=(self.columns . filter (c-> c.value_type.is_text) . map .name) type=Auto format=Data_Formatter.Value error_on_missing_columns=True on_problems=Report_Warning =
|
parse columns=(self.columns . filter (c-> c.value_type.is_text) . map .name) type=Auto format=Data_Formatter.Value error_on_missing_columns=True on_problems=Report_Warning =
|
||||||
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
## Avoid unused arguments warning. We cannot rename arguments to `_`,
|
||||||
@ -1415,6 +1430,7 @@ type Table
|
|||||||
! Error Conditions
|
! Error Conditions
|
||||||
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
||||||
be reported according to the `on_problems` behavior.
|
be reported according to the `on_problems` behavior.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
split_to_columns : Text | Integer -> Text -> Integer | Nothing -> Problem_Behavior -> Table
|
split_to_columns : Text | Integer -> Text -> Integer | Nothing -> Problem_Behavior -> Table
|
||||||
split_to_columns self column delimiter="," column_count=Nothing on_problems=Report_Error =
|
split_to_columns self column delimiter="," column_count=Nothing on_problems=Report_Error =
|
||||||
_ = [column delimiter column_count on_problems]
|
_ = [column delimiter column_count on_problems]
|
||||||
@ -1426,6 +1442,7 @@ type Table
|
|||||||
Arguments:
|
Arguments:
|
||||||
- column: The name or index of the column to split the text of.
|
- column: The name or index of the column to split the text of.
|
||||||
- delimiter: The term or terms used to split the text.
|
- delimiter: The term or terms used to split the text.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
split_to_rows : Text | Integer -> Text -> Table
|
split_to_rows : Text | Integer -> Text -> Table
|
||||||
split_to_rows self column delimiter="," =
|
split_to_rows self column delimiter="," =
|
||||||
_ = [column delimiter]
|
_ = [column delimiter]
|
||||||
@ -1451,6 +1468,7 @@ type Table
|
|||||||
! Error Conditions
|
! Error Conditions
|
||||||
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
||||||
be reported according to the `on_problems` behavior.
|
be reported according to the `on_problems` behavior.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
tokenize_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Integer | Nothing -> Problem_Behavior -> Table
|
tokenize_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Integer | Nothing -> Problem_Behavior -> Table
|
||||||
tokenize_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive column_count=Nothing on_problems=Report_Error =
|
tokenize_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive column_count=Nothing on_problems=Report_Error =
|
||||||
_ = [column pattern case_sensitivity column_count on_problems]
|
_ = [column pattern case_sensitivity column_count on_problems]
|
||||||
@ -1470,6 +1488,7 @@ type Table
|
|||||||
- at_least_one_row: If True, a tokenization that returns no values will still
|
- at_least_one_row: If True, a tokenization that returns no values will still
|
||||||
produce at least one row, with `Nothing` for the output column values.
|
produce at least one row, with `Nothing` for the output column values.
|
||||||
Equivalent to converting a tokenization output of [] to [Nothing].
|
Equivalent to converting a tokenization output of [] to [Nothing].
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
tokenize_to_rows : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Table
|
tokenize_to_rows : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Table
|
||||||
tokenize_to_rows self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive at_least_one_row=False =
|
tokenize_to_rows self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive at_least_one_row=False =
|
||||||
_ = [column, pattern, case_sensitivity, at_least_one_row]
|
_ = [column, pattern, case_sensitivity, at_least_one_row]
|
||||||
@ -1499,6 +1518,7 @@ type Table
|
|||||||
will be named `<Input Column> <N>` where `N` is the number of the marked group.
|
will be named `<Input Column> <N>` where `N` is the number of the marked group.
|
||||||
If the new name is already in use it will be renamed following the normal
|
If the new name is already in use it will be renamed following the normal
|
||||||
suffixing strategy.
|
suffixing strategy.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
parse_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table
|
parse_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table
|
||||||
parse_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive parse_values=True on_problems=Report_Error =
|
parse_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive parse_values=True on_problems=Report_Error =
|
||||||
_ = [column, pattern, case_sensitivity, parse_values, on_problems]
|
_ = [column, pattern, case_sensitivity, parse_values, on_problems]
|
||||||
@ -1554,6 +1574,7 @@ type Table
|
|||||||
If the backend does not support the requested target type, the closest
|
If the backend does not support the requested target type, the closest
|
||||||
supported type is chosen and a `Inexact_Type_Coercion` problem is
|
supported type is chosen and a `Inexact_Type_Coercion` problem is
|
||||||
reported.
|
reported.
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
cast : (Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector)) -> Value_Type -> Problem_Behavior -> Table ! Illegal_Argument | Inexact_Type_Coercion | Lossy_Conversion
|
cast : (Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector)) -> Value_Type -> Problem_Behavior -> Table ! Illegal_Argument | Inexact_Type_Coercion | Lossy_Conversion
|
||||||
cast self columns=[0] value_type=Value_Type.Char on_problems=Problem_Behavior.Report_Warning =
|
cast self columns=[0] value_type=Value_Type.Char on_problems=Problem_Behavior.Report_Warning =
|
||||||
selected = self.select_columns columns
|
selected = self.select_columns columns
|
||||||
@ -1593,9 +1614,7 @@ type Table
|
|||||||
table = self.connection.read_statement sql
|
table = self.connection.read_statement sql
|
||||||
table.at column_name . at 0
|
table.at column_name . at 0
|
||||||
|
|
||||||
## UNSTABLE
|
## Returns a materialized dataframe containing rows of this table.
|
||||||
|
|
||||||
Returns a materialized dataframe containing rows of this table.
|
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- max_rows: specifies a maximum amount of rows to fetch; if not set, all
|
- max_rows: specifies a maximum amount of rows to fetch; if not set, all
|
||||||
@ -1859,16 +1878,9 @@ display_dataframe df indices_count all_rows_count format_terminal =
|
|||||||
is, otherwise numerical suffixes are added.
|
is, otherwise numerical suffixes are added.
|
||||||
fresh_names : Vector Text -> Vector Text -> Vector Text
|
fresh_names : Vector Text -> Vector Text -> Vector Text
|
||||||
fresh_names used_names preferred_names =
|
fresh_names used_names preferred_names =
|
||||||
freshen currently_used name ix =
|
unique = Unique_Name_Strategy.new
|
||||||
new_name = if ix == 0 then name else name+"_"+ix.to_text
|
unique.mark_used used_names
|
||||||
case currently_used.contains new_name of
|
unique.make_all_unique preferred_names
|
||||||
False -> new_name
|
|
||||||
True -> freshen currently_used name ix+1
|
|
||||||
res = preferred_names . fold [used_names, []] acc-> name->
|
|
||||||
used = acc.first
|
|
||||||
new_name = freshen used name 0
|
|
||||||
[used_names + [new_name], acc.second + [new_name]]
|
|
||||||
res.second
|
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import project.Connection.Database
|
|||||||
import project.Connection.Postgres_Details.Postgres_Details
|
import project.Connection.Postgres_Details.Postgres_Details
|
||||||
import project.Connection.SQLite_Details.SQLite_Details
|
import project.Connection.SQLite_Details.SQLite_Details
|
||||||
import project.Connection.SQLite_Details.In_Memory
|
import project.Connection.SQLite_Details.In_Memory
|
||||||
|
import project.Connection.SQLite_Format.SQLite_Format
|
||||||
import project.Connection.SSL_Mode.SSL_Mode
|
import project.Connection.SSL_Mode.SSL_Mode
|
||||||
import project.Data.SQL_Query.SQL_Query
|
import project.Data.SQL_Query.SQL_Query
|
||||||
import project.Extensions.Upload_Table
|
import project.Extensions.Upload_Table
|
||||||
@ -21,6 +22,7 @@ export project.Connection.Database
|
|||||||
export project.Connection.Postgres_Details.Postgres_Details
|
export project.Connection.Postgres_Details.Postgres_Details
|
||||||
export project.Connection.SQLite_Details.SQLite_Details
|
export project.Connection.SQLite_Details.SQLite_Details
|
||||||
export project.Connection.SQLite_Details.In_Memory
|
export project.Connection.SQLite_Details.In_Memory
|
||||||
|
export project.Connection.SQLite_Format.SQLite_Format
|
||||||
export project.Connection.SSL_Mode.SSL_Mode
|
export project.Connection.SSL_Mode.SSL_Mode
|
||||||
export project.Data.SQL_Query.SQL_Query
|
export project.Data.SQL_Query.SQL_Query
|
||||||
export project.Extensions.Upload_Table
|
export project.Extensions.Upload_Table
|
||||||
|
@ -311,6 +311,7 @@ type Table
|
|||||||
table.select_columns [-1, 0, 1] reorder=True
|
table.select_columns [-1, 0, 1] reorder=True
|
||||||
|
|
||||||
Icon: select_column
|
Icon: select_column
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
select_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
select_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
select_columns self columns=[0] (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) =
|
select_columns self columns=[0] (reorder = False) (error_on_missing_columns = True) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.select_columns selectors=columns reorder=reorder error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
||||||
@ -363,7 +364,7 @@ type Table
|
|||||||
Remove the first two columns and the last column.
|
Remove the first two columns and the last column.
|
||||||
|
|
||||||
table.remove_columns [-1, 0, 1]
|
table.remove_columns [-1, 0, 1]
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
remove_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
remove_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
remove_columns self (columns=[0]) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
remove_columns self (columns=[0]) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.remove_columns selectors=columns error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
||||||
@ -419,7 +420,7 @@ type Table
|
|||||||
Move the first column to back.
|
Move the first column to back.
|
||||||
|
|
||||||
table.reorder_columns [0] position=Position.After_Other_Columns
|
table.reorder_columns [0] position=Position.After_Other_Columns
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
reorder_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
reorder_columns : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Position -> Boolean -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
reorder_columns self (columns = [0]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
reorder_columns self (columns = [0]) (position = Position.Before_Other_Columns) (error_on_missing_columns = False) (on_problems = Report_Warning) =
|
||||||
new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
new_columns = self.columns_helper.reorder_columns selectors=columns position=position error_on_missing_columns=error_on_missing_columns on_problems=on_problems
|
||||||
@ -681,6 +682,7 @@ type Table
|
|||||||
Sort the table by columns whose names start with letter `a`.
|
Sort the table by columns whose names start with letter `a`.
|
||||||
|
|
||||||
table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)]
|
table.order_by [(Sort_Column.Select_By_Name "a.*" use_regex=True case_sensitivity=Case_Sensitivity.Insensitive)]
|
||||||
|
@columns Widget_Helpers.make_order_by_selector
|
||||||
order_by : Text | Sort_Column | Vector (Text | Sort_Column) -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
order_by : Text | Sort_Column | Vector (Text | Sort_Column) -> Text_Ordering -> Boolean -> Problem_Behavior -> Table ! Incomparable_Values | No_Input_Columns_Selected | Missing_Input_Columns | Column_Indexes_Out_Of_Range
|
||||||
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning =
|
order_by self (columns = ([(Sort_Column.Name (self.columns.at 0 . name))])) text_ordering=Text_Ordering.Default error_on_missing_columns=True on_problems=Problem_Behavior.Report_Warning =
|
||||||
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
|
problem_builder = Problem_Builder.new error_on_missing_columns=error_on_missing_columns types_to_always_throw=[No_Input_Columns_Selected]
|
||||||
@ -739,6 +741,7 @@ type Table
|
|||||||
- If floating points values are present in the distinct columns, a
|
- If floating points values are present in the distinct columns, a
|
||||||
`Floating_Point_Equality` is reported according to the `on_problems`
|
`Floating_Point_Equality` is reported according to the `on_problems`
|
||||||
setting.
|
setting.
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
distinct : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
|
distinct : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | No_Input_Columns_Selected | Floating_Point_Equality
|
||||||
distinct self (columns = self.column_names) case_sensitivity=Case_Sensitivity.Default error_on_missing_columns=True on_problems=Report_Warning =
|
distinct self (columns = self.column_names) case_sensitivity=Case_Sensitivity.Default error_on_missing_columns=True on_problems=Report_Warning =
|
||||||
key_columns = self.columns_helper.select_columns selectors=columns reorder=True error_on_missing_columns=error_on_missing_columns on_problems=on_problems . catch No_Output_Columns _->
|
key_columns = self.columns_helper.select_columns selectors=columns reorder=True error_on_missing_columns=error_on_missing_columns on_problems=on_problems . catch No_Output_Columns _->
|
||||||
@ -833,6 +836,8 @@ type Table
|
|||||||
Parse all columns inferring their types, using `,` as the decimal point for numbers.
|
Parse all columns inferring their types, using `,` as the decimal point for numbers.
|
||||||
|
|
||||||
table.parse format=(Data_Formatter.Value.with_number_formatting decimal_point=',')
|
table.parse format=(Data_Formatter.Value.with_number_formatting decimal_point=',')
|
||||||
|
@type Widget_Helpers.parse_type_selector
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
parse : Text | Integer | Column_Selector | Vector (Text | Integer | Column_Selector) -> Value_Type | Auto -> Text | Data_Formatter -> Boolean -> Problem_Behavior -> Table
|
parse : Text | Integer | Column_Selector | Vector (Text | Integer | Column_Selector) -> Value_Type | Auto -> Text | Data_Formatter -> Boolean -> Problem_Behavior -> Table
|
||||||
parse self columns=(self.columns . filter (c-> c.value_type.is_text) . map .name) type=Auto format=Data_Formatter.Value error_on_missing_columns=True on_problems=Report_Warning =
|
parse self columns=(self.columns . filter (c-> c.value_type.is_text) . map .name) type=Auto format=Data_Formatter.Value error_on_missing_columns=True on_problems=Report_Warning =
|
||||||
formatter = case format of
|
formatter = case format of
|
||||||
@ -918,6 +923,7 @@ type Table
|
|||||||
If the backend does not support the requested target type, the closest
|
If the backend does not support the requested target type, the closest
|
||||||
supported type is chosen and a `Inexact_Type_Coercion` problem is
|
supported type is chosen and a `Inexact_Type_Coercion` problem is
|
||||||
reported.
|
reported.
|
||||||
|
@columns Widget_Helpers.make_column_name_vector_selector
|
||||||
cast : (Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector)) -> Value_Type -> Problem_Behavior -> Table ! Illegal_Argument | Inexact_Type_Coercion | Lossy_Conversion
|
cast : (Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector)) -> Value_Type -> Problem_Behavior -> Table ! Illegal_Argument | Inexact_Type_Coercion | Lossy_Conversion
|
||||||
cast self columns=[0] value_type=Value_Type.Char on_problems=Problem_Behavior.Report_Warning =
|
cast self columns=[0] value_type=Value_Type.Char on_problems=Problem_Behavior.Report_Warning =
|
||||||
_ = [columns, value_type, on_problems]
|
_ = [columns, value_type, on_problems]
|
||||||
@ -939,6 +945,7 @@ type Table
|
|||||||
! Error Conditions
|
! Error Conditions
|
||||||
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
||||||
be reported according to the `on_problems` behavior.
|
be reported according to the `on_problems` behavior.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
split_to_columns : Text | Integer -> Text -> Integer | Nothing -> Problem_Behavior -> Table
|
split_to_columns : Text | Integer -> Text -> Integer | Nothing -> Problem_Behavior -> Table
|
||||||
split_to_columns self column delimiter="," column_count=Nothing on_problems=Report_Error =
|
split_to_columns self column delimiter="," column_count=Nothing on_problems=Report_Error =
|
||||||
Split_Tokenize.split_to_columns self column delimiter column_count on_problems
|
Split_Tokenize.split_to_columns self column delimiter column_count on_problems
|
||||||
@ -949,6 +956,7 @@ type Table
|
|||||||
Arguments:
|
Arguments:
|
||||||
- column: The name or index of the column to split the text of.
|
- column: The name or index of the column to split the text of.
|
||||||
- delimiter: The term or terms used to split the text.
|
- delimiter: The term or terms used to split the text.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
split_to_rows : Text | Integer -> Text -> Table
|
split_to_rows : Text | Integer -> Text -> Table
|
||||||
split_to_rows self column delimiter="," =
|
split_to_rows self column delimiter="," =
|
||||||
Split_Tokenize.split_to_rows self column delimiter
|
Split_Tokenize.split_to_rows self column delimiter
|
||||||
@ -973,6 +981,7 @@ type Table
|
|||||||
! Error Conditions
|
! Error Conditions
|
||||||
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
If the data exceeds the `column_count`, a `Column_Count_Exceeded` will
|
||||||
be reported according to the `on_problems` behavior.
|
be reported according to the `on_problems` behavior.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
tokenize_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Integer | Nothing -> Problem_Behavior -> Table
|
tokenize_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Integer | Nothing -> Problem_Behavior -> Table
|
||||||
tokenize_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive column_count=Nothing on_problems=Report_Error =
|
tokenize_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive column_count=Nothing on_problems=Report_Error =
|
||||||
Split_Tokenize.tokenize_to_columns self column pattern case_sensitivity column_count on_problems
|
Split_Tokenize.tokenize_to_columns self column pattern case_sensitivity column_count on_problems
|
||||||
@ -991,6 +1000,7 @@ type Table
|
|||||||
- at_least_one_row: If True, a tokenization that returns no values will still
|
- at_least_one_row: If True, a tokenization that returns no values will still
|
||||||
produce at least one row, with `Nothing` for the output column values.
|
produce at least one row, with `Nothing` for the output column values.
|
||||||
Equivalent to converting a tokenization output of [] to [Nothing].
|
Equivalent to converting a tokenization output of [] to [Nothing].
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
tokenize_to_rows : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Table
|
tokenize_to_rows : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Table
|
||||||
tokenize_to_rows self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive at_least_one_row=False =
|
tokenize_to_rows self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive at_least_one_row=False =
|
||||||
Split_Tokenize.tokenize_to_rows self column pattern case_sensitivity at_least_one_row
|
Split_Tokenize.tokenize_to_rows self column pattern case_sensitivity at_least_one_row
|
||||||
@ -1019,6 +1029,7 @@ type Table
|
|||||||
will be named `<Input Column> <N>` where `N` is the number of the marked group.
|
will be named `<Input Column> <N>` where `N` is the number of the marked group.
|
||||||
If the new name is already in use it will be renamed following the normal
|
If the new name is already in use it will be renamed following the normal
|
||||||
suffixing strategy.
|
suffixing strategy.
|
||||||
|
@column Widget_Helpers.make_column_name_selector
|
||||||
parse_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table
|
parse_to_columns : Text | Integer -> Text -> Case_Sensitivity -> Boolean -> Problem_Behavior -> Table
|
||||||
parse_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive parse_values=True on_problems=Report_Error =
|
parse_to_columns self column pattern="." case_sensitivity=Case_Sensitivity.Sensitive parse_values=True on_problems=Report_Error =
|
||||||
Split_Tokenize.parse_to_columns self column pattern case_sensitivity parse_values on_problems
|
Split_Tokenize.parse_to_columns self column pattern case_sensitivity parse_values on_problems
|
||||||
@ -1208,6 +1219,7 @@ type Table
|
|||||||
double_inventory = table.at "total_stock" * 2
|
double_inventory = table.at "total_stock" * 2
|
||||||
table.set double_inventory new_name="total_stock"
|
table.set double_inventory new_name="total_stock"
|
||||||
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
table.set "2 * [total_stock]" new_name="total_stock_expr"
|
||||||
|
@new_name Widget_Helpers.make_column_name_selector
|
||||||
set : Column | Text -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
set : Column | Text -> Text | Nothing -> Set_Mode -> Problem_Behavior -> Table ! Existing_Column | Missing_Column | No_Such_Column | Expression_Error
|
||||||
set self column new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
set self column new_name=Nothing set_mode=Set_Mode.Add_Or_Update on_problems=Report_Warning =
|
||||||
resolved = case column of
|
resolved = case column of
|
||||||
@ -1322,12 +1334,15 @@ type Table
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
- right: The table to join with.
|
- right: The table to join with.
|
||||||
- join_kind: The `Join_Kind` for the joining the two tables.
|
- join_kind: The `Join_Kind` for the joining the two tables. It defaults
|
||||||
|
to `Left_Outer`.
|
||||||
- on: A single condition or a common column name, or a list thereof, on
|
- on: A single condition or a common column name, or a list thereof, on
|
||||||
which to correlate rows from the two tables. If multiple conditions
|
which to correlate rows from the two tables. If multiple conditions
|
||||||
are supplied, rows are correlated only if all are true.
|
are supplied, rows are correlated only if all are true.
|
||||||
If common column names are provided, these columns should be present
|
If common column names are provided, these columns should be present
|
||||||
in both tables and an equality condition is added for each of them.
|
in both tables and an equality condition is added for each of them.
|
||||||
|
By default, the join is performed on the first column of the left table
|
||||||
|
correlated with a column in the right table with the same name.
|
||||||
- right_prefix: The prefix added to right table column names in case of
|
- right_prefix: The prefix added to right table column names in case of
|
||||||
name conflict.
|
name conflict.
|
||||||
- on_problems: Specifies how to handle problems if they occur, reporting
|
- on_problems: Specifies how to handle problems if they occur, reporting
|
||||||
@ -1375,10 +1390,9 @@ type Table
|
|||||||
allows to join the two tables on equality of corresponding columns with
|
allows to join the two tables on equality of corresponding columns with
|
||||||
the same name. So `table.join other on=["A", "B"]` is a shorthand for:
|
the same name. So `table.join other on=["A", "B"]` is a shorthand for:
|
||||||
table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"]
|
table.join other on=[Join_Condition.Equals "A" "A", Join_Condition.Equals "B" "B"]
|
||||||
@join_kind Widget_Helpers.join_kind_selector
|
|
||||||
@on Widget_Helpers.make_column_name_selector
|
@on Widget_Helpers.make_column_name_selector
|
||||||
join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table
|
join : Table -> Join_Kind -> Join_Condition | Text | Vector (Join_Condition | Text) -> Text -> Problem_Behavior -> Table
|
||||||
join self right join_kind=Join_Kind.Inner on=[Join_Condition.Equals 0 0] right_prefix="Right_" on_problems=Report_Warning =
|
join self right join_kind=Join_Kind.Left_Outer on=[Join_Condition.Equals self.column_names.first] right_prefix="Right " on_problems=Report_Warning =
|
||||||
if check_table "right" right then
|
if check_table "right" right then
|
||||||
# [left_unmatched, matched, right_unmatched]
|
# [left_unmatched, matched, right_unmatched]
|
||||||
rows_to_keep = case join_kind of
|
rows_to_keep = case join_kind of
|
||||||
@ -1439,7 +1453,7 @@ type Table
|
|||||||
example, by sorting the table; in-memory tables will keep the memory
|
example, by sorting the table; in-memory tables will keep the memory
|
||||||
layout order while for database tables the order may be unspecified).
|
layout order while for database tables the order may be unspecified).
|
||||||
cross_join : Table -> Integer | Nothing -> Text -> Problem_Behavior -> Table
|
cross_join : Table -> Integer | Nothing -> Text -> Problem_Behavior -> Table
|
||||||
cross_join self right right_row_limit=100 right_prefix="Right_" on_problems=Report_Warning =
|
cross_join self right right_row_limit=100 right_prefix="Right " on_problems=Report_Warning =
|
||||||
if check_table "right" right then
|
if check_table "right" right then
|
||||||
limit_problems = case right_row_limit.is_nothing.not && (right.row_count > right_row_limit) of
|
limit_problems = case right_row_limit.is_nothing.not && (right.row_count > right_row_limit) of
|
||||||
True ->
|
True ->
|
||||||
@ -1495,7 +1509,7 @@ type Table
|
|||||||
order of columns is undefined and the operation will fail, reporting a
|
order of columns is undefined and the operation will fail, reporting a
|
||||||
`Undefined_Column_Order` problem and returning an empty table.
|
`Undefined_Column_Order` problem and returning an empty table.
|
||||||
zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table
|
zip : Table -> Boolean | Report_Unmatched -> Text -> Problem_Behavior -> Table
|
||||||
zip self right keep_unmatched=Report_Unmatched right_prefix="Right_" on_problems=Report_Warning =
|
zip self right keep_unmatched=Report_Unmatched right_prefix="Right " on_problems=Report_Warning =
|
||||||
if check_table "right" right then
|
if check_table "right" right then
|
||||||
keep_unmatched_bool = case keep_unmatched of
|
keep_unmatched_bool = case keep_unmatched of
|
||||||
Report_Unmatched -> True
|
Report_Unmatched -> True
|
||||||
@ -1694,6 +1708,7 @@ type Table
|
|||||||
- If any column names in the new table are clashing, a
|
- If any column names in the new table are clashing, a
|
||||||
`Duplicate_Output_Column_Names` is reported according to the
|
`Duplicate_Output_Column_Names` is reported according to the
|
||||||
`on_problems` setting.
|
`on_problems` setting.
|
||||||
|
@id_fields Widget_Helpers.make_column_name_vector_selector
|
||||||
transpose : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Text -> Text -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range | Duplicate_Output_Column_Names
|
transpose : Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector) -> Text -> Text -> Boolean -> Problem_Behavior -> Table ! No_Output_Columns | Missing_Input_Columns | Column_Indexes_Out_Of_Range | Duplicate_Output_Column_Names
|
||||||
transpose self (id_fields = []) (name_field="Name") (value_field="Value") (error_on_missing_columns=True) (on_problems = Report_Warning) =
|
transpose self (id_fields = []) (name_field="Name") (value_field="Value") (error_on_missing_columns=True) (on_problems = Report_Warning) =
|
||||||
columns_helper = self.columns_helper
|
columns_helper = self.columns_helper
|
||||||
@ -1749,7 +1764,10 @@ type Table
|
|||||||
an `Unquoted_Delimiter`
|
an `Unquoted_Delimiter`
|
||||||
- If there are more than 10 issues with a single column,
|
- If there are more than 10 issues with a single column,
|
||||||
an `Additional_Warnings`.
|
an `Additional_Warnings`.
|
||||||
cross_tab : Aggregate_Column | Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector | Aggregate_Column) -> (Text | Integer) -> Vector Aggregate_Column -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range | Invalid_Aggregate_Column | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings
|
@group_by Widget_Helpers.make_column_name_vector_selector
|
||||||
|
@name_column Widget_Helpers.make_column_name_selector
|
||||||
|
@values (Widget_Helpers.make_aggregate_column_selector include_group_by=False)
|
||||||
|
cross_tab : Aggregate_Column | Text | Integer | Column_Selector | Vector (Integer | Text | Column_Selector | Aggregate_Column) -> (Text | Integer) -> Aggregate_Column | Vector Aggregate_Column -> Problem_Behavior -> Table ! Missing_Input_Columns | Column_Indexes_Out_Of_Range | Invalid_Aggregate_Column | Floating_Point_Equality | Invalid_Aggregation | Unquoted_Delimiter | Additional_Warnings
|
||||||
cross_tab self group_by=[] name_column=self.column_names.first values=Aggregate_Column.Count (on_problems=Report_Warning) =
|
cross_tab self group_by=[] name_column=self.column_names.first values=Aggregate_Column.Count (on_problems=Report_Warning) =
|
||||||
columns_helper = self.columns_helper
|
columns_helper = self.columns_helper
|
||||||
problem_builder = Problem_Builder.new error_on_missing_columns=True
|
problem_builder = Problem_Builder.new error_on_missing_columns=True
|
||||||
|
@ -49,7 +49,7 @@ type Delimited_Format
|
|||||||
character if it anywhere else than at the beginning of the line. This
|
character if it anywhere else than at the beginning of the line. This
|
||||||
option is only applicable for read mode and does not affect writing. It
|
option is only applicable for read mode and does not affect writing. It
|
||||||
defaults to `Nothing` which means that comments are disabled.
|
defaults to `Nothing` which means that comments are disabled.
|
||||||
Delimited (delimiter:Text) (encoding:Encoding=Encoding.utf_8) (skip_rows:Integer=0) (row_limit:Integer|Nothing=Nothing) (quote_style:Quote_Style=Quote_Style.With_Quotes) (headers:Boolean|Infer=Infer) (value_formatter:Data_Formatter|Nothing=Data_Formatter.Value) (keep_invalid_rows:Boolean=True) (line_endings:Line_Ending_Style=Infer) (comment_character:Text|Nothing=Nothing)
|
Delimited (delimiter:Text=',') (encoding:Encoding=Encoding.utf_8) (skip_rows:Integer=0) (row_limit:Integer|Nothing=Nothing) (quote_style:Quote_Style=Quote_Style.With_Quotes) (headers:Boolean|Infer=Infer) (value_formatter:Data_Formatter|Nothing=Data_Formatter.Value) (keep_invalid_rows:Boolean=True) (line_endings:Line_Ending_Style=Infer) (comment_character:Text|Nothing=Nothing)
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
ADVANCED
|
ADVANCED
|
||||||
|
@ -12,14 +12,17 @@ polyglot java import org.enso.table.error.EmptySheetException
|
|||||||
type Missing_Input_Columns
|
type Missing_Input_Columns
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
One or more columns not found in the input table.
|
One or more columns not found in the input table.
|
||||||
Error (criteria : [Text])
|
Error (criteria : [Text]) (where:Text|Nothing = Nothing)
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
|
||||||
Convert a missing input error to a human-readable form.
|
Convert a missing input error to a human-readable form.
|
||||||
to_display_text : Text
|
to_display_text : Text
|
||||||
to_display_text self =
|
to_display_text self =
|
||||||
"The criteria "+self.criteria.to_text+" did not match any columns."
|
where = case self.where of
|
||||||
|
Nothing -> "."
|
||||||
|
location : Text -> " in "+location+"."
|
||||||
|
"The criteria "+self.criteria.to_text+" did not match any columns"+where
|
||||||
|
|
||||||
type Column_Indexes_Out_Of_Range
|
type Column_Indexes_Out_Of_Range
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
|
@ -23,9 +23,10 @@ type Join_Condition_Resolver
|
|||||||
resolve : Join_Condition | Text | Vector (Join_Condition | Text) -> Problem_Behavior -> Join_Condition_Resolution
|
resolve : Join_Condition | Text | Vector (Join_Condition | Text) -> Problem_Behavior -> Join_Condition_Resolution
|
||||||
resolve self conditions on_problems =
|
resolve self conditions on_problems =
|
||||||
redundant_names = Vector.new_builder
|
redundant_names = Vector.new_builder
|
||||||
problem_builder = Problem_Builder.new types_to_always_throw=[Missing_Input_Columns, Column_Indexes_Out_Of_Range]
|
left_problem_builder = Problem_Builder.new missing_input_columns_location="the left table" types_to_always_throw=[Missing_Input_Columns, Column_Indexes_Out_Of_Range]
|
||||||
|
right_problem_builder = Problem_Builder.new missing_input_columns_location="the right table" types_to_always_throw=[Missing_Input_Columns, Column_Indexes_Out_Of_Range]
|
||||||
|
|
||||||
resolve_selector resolver selector =
|
resolve_selector problem_builder resolver selector =
|
||||||
r_1 = resolver selector
|
r_1 = resolver selector
|
||||||
r_2 = r_1.catch No_Such_Column _->
|
r_2 = r_1.catch No_Such_Column _->
|
||||||
problem_builder.report_missing_input_columns [selector]
|
problem_builder.report_missing_input_columns [selector]
|
||||||
@ -33,9 +34,10 @@ type Join_Condition_Resolver
|
|||||||
r_2.catch Index_Out_Of_Bounds _->
|
r_2.catch Index_Out_Of_Bounds _->
|
||||||
problem_builder.report_oob_indices [selector]
|
problem_builder.report_oob_indices [selector]
|
||||||
Nothing
|
Nothing
|
||||||
resolve_left = resolve_selector self.left_at
|
resolve_left = resolve_selector left_problem_builder self.left_at
|
||||||
resolve_right = resolve_selector self.right_at
|
resolve_right = resolve_selector right_problem_builder self.right_at
|
||||||
|
|
||||||
|
problem_builder = Problem_Builder.new
|
||||||
is_nothing column = case column of
|
is_nothing column = case column of
|
||||||
Nothing -> True
|
Nothing -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
@ -70,7 +72,12 @@ type Join_Condition_Resolver
|
|||||||
Value_Type.expect_comparable left right_lower <|
|
Value_Type.expect_comparable left right_lower <|
|
||||||
Value_Type.expect_comparable left right_upper <|
|
Value_Type.expect_comparable left right_upper <|
|
||||||
self.make_between problem_builder left right_lower right_upper
|
self.make_between problem_builder left right_lower right_upper
|
||||||
problem_builder.attach_problems_before on_problems <|
|
attach_problems ~result =
|
||||||
|
left_problem_builder.attach_problems_before on_problems <|
|
||||||
|
right_problem_builder.attach_problems_before on_problems <|
|
||||||
|
problem_builder.attach_problems_before on_problems <|
|
||||||
|
result
|
||||||
|
attach_problems <|
|
||||||
if converted.contains Nothing then Panic.throw (Illegal_State.Error "Impossible: unresolved columns remaining in the join resolution. This should have raised a dataflow error. This is a bug in the Table library.") else
|
if converted.contains Nothing then Panic.throw (Illegal_State.Error "Impossible: unresolved columns remaining in the join resolution. This should have raised a dataflow error. This is a bug in the Table library.") else
|
||||||
Join_Condition_Resolution.Result converted redundant_names.to_vector
|
Join_Condition_Resolution.Result converted redundant_names.to_vector
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from project.Errors import Missing_Input_Columns, Column_Indexes_Out_Of_Range, D
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
type Problem_Builder
|
type Problem_Builder
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Value types_to_always_throw oob_indices missing_input_columns other
|
Value types_to_always_throw oob_indices missing_input_columns missing_input_columns_location other
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
report_oob_indices self indices =
|
report_oob_indices self indices =
|
||||||
@ -39,7 +39,7 @@ type Problem_Builder
|
|||||||
if vec.not_empty then
|
if vec.not_empty then
|
||||||
problems.append (problem_creator vec)
|
problems.append (problem_creator vec)
|
||||||
|
|
||||||
build_vector_and_append self.missing_input_columns Missing_Input_Columns.Error
|
build_vector_and_append self.missing_input_columns (Missing_Input_Columns.Error _ where=self.missing_input_columns_location)
|
||||||
build_vector_and_append self.oob_indices Column_Indexes_Out_Of_Range.Error
|
build_vector_and_append self.oob_indices Column_Indexes_Out_Of_Range.Error
|
||||||
self.other.to_vector.each problems.append
|
self.other.to_vector.each problems.append
|
||||||
|
|
||||||
@ -91,10 +91,12 @@ type Problem_Builder
|
|||||||
methods regardless of the `Problem_Behavior` used. Defaults to `False`.
|
methods regardless of the `Problem_Behavior` used. Defaults to `False`.
|
||||||
Setting this to `True` is essentially a shorthand for adding these two
|
Setting this to `True` is essentially a shorthand for adding these two
|
||||||
problem types to `types_to_always_throw`.
|
problem types to `types_to_always_throw`.
|
||||||
|
- missing_input_columns_location: The location to add to the missing
|
||||||
|
input column error to make it more informative. Defaults to `Nothing`.
|
||||||
new : Vector -> Boolean -> Problem_Builder
|
new : Vector -> Boolean -> Problem_Builder
|
||||||
new types_to_always_throw=[] error_on_missing_columns=False =
|
new types_to_always_throw=[] error_on_missing_columns=False missing_input_columns_location=Nothing =
|
||||||
additional_types_to_throw = if error_on_missing_columns then [Missing_Input_Columns, Column_Indexes_Out_Of_Range, Invalid_Aggregate_Column] else []
|
additional_types_to_throw = if error_on_missing_columns then [Missing_Input_Columns, Column_Indexes_Out_Of_Range, Invalid_Aggregate_Column] else []
|
||||||
Problem_Builder.Value types_to_always_throw+additional_types_to_throw (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) other=Vector.new_builder
|
Problem_Builder.Value types_to_always_throw+additional_types_to_throw (Ref.new Vector_Builder.empty) (Ref.new Vector_Builder.empty) missing_input_columns_location other=Vector.new_builder
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Appends a `Vector` to a `Vector_Builder` stored in a `Ref`.
|
Appends a `Vector` to a `Vector_Builder` stored in a `Ref`.
|
||||||
|
@ -173,7 +173,7 @@ fan_out_to_rows table input_column_id function at_least_one_row=False on_problem
|
|||||||
x | 12 34 56 | y ===>
|
x | 12 34 56 | y ===>
|
||||||
... | ... | ...
|
... | ... | ...
|
||||||
|
|
||||||
foo | bar 0 | bar 1 | baz
|
foo | bar 1 | bar 2 | baz
|
||||||
----+-------+-------+----
|
----+-------+-------+----
|
||||||
x | 1 | 2 | y
|
x | 1 | 2 | y
|
||||||
x | 3 | 4 | y
|
x | 3 | 4 | y
|
||||||
@ -367,7 +367,7 @@ repeat_each n ~action = 0.up_to n . each _-> action
|
|||||||
## PRIVATE
|
## PRIVATE
|
||||||
Name a column by appending an integer to a base column name.
|
Name a column by appending an integer to a base column name.
|
||||||
default_column_namer : Text -> Integer -> Text
|
default_column_namer : Text -> Integer -> Text
|
||||||
default_column_namer base_name i = base_name + " " + i.to_text
|
default_column_namer base_name i = base_name + " " + (i+1).to_text
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Pad or truncate a vector to be a specified length; if altered, report
|
Pad or truncate a vector to be a specified length; if altered, report
|
||||||
|
@ -56,10 +56,10 @@ type Unique_Name_Strategy
|
|||||||
> Example
|
> Example
|
||||||
Rename names from a second list to avoid clashing with the first one.
|
Rename names from a second list to avoid clashing with the first one.
|
||||||
|
|
||||||
first = ["A", "B", "second_A"]
|
first = ["A", "B", "second A"]
|
||||||
second = ["A", "B", "second_A_1", "C"]
|
second = ["A", "B", "second A 1", "C"]
|
||||||
unique_second = Unique_Name_Strategy.combine_with_prefix first second "second_"
|
unique_second = Unique_Name_Strategy.combine_with_prefix first second "second_"
|
||||||
unique_second == ["second_A_2", "second_B", "second_A_1", "C"]
|
unique_second == ["second A 2", "second_B", "second A 1", "C"]
|
||||||
combine_with_prefix : Vector Text -> Vector Text -> Text -> Unique_Name_Strategy
|
combine_with_prefix : Vector Text -> Vector Text -> Text -> Unique_Name_Strategy
|
||||||
combine_with_prefix self first second second_prefix =
|
combine_with_prefix self first second second_prefix =
|
||||||
Vector.from_polyglot_array <|
|
Vector.from_polyglot_array <|
|
||||||
@ -110,7 +110,7 @@ type Unique_Name_Strategy
|
|||||||
> Example
|
> Example
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
strategy.make_unique "A" # returns "A"
|
strategy.make_unique "A" # returns "A"
|
||||||
strategy.make_unique "A" # returns "A_1"
|
strategy.make_unique "A" # returns "A 1"
|
||||||
make_unique : Text -> Text
|
make_unique : Text -> Text
|
||||||
make_unique self name = self.deduplicator.makeUnique name
|
make_unique self name = self.deduplicator.makeUnique name
|
||||||
|
|
||||||
|
@ -1,16 +1,72 @@
|
|||||||
from Standard.Base import all
|
from Standard.Base import all
|
||||||
|
from Standard.Base.Metadata.Widget import Single_Choice, Vector_Editor
|
||||||
from Standard.Base.Metadata.Widget import Single_Choice
|
|
||||||
from Standard.Base.Metadata.Choice import Option
|
from Standard.Base.Metadata.Choice import Option
|
||||||
import Standard.Base.Metadata.Display
|
import Standard.Base.Metadata.Display
|
||||||
|
|
||||||
from project.Data.Table import Table
|
import project.Data.Table.Table
|
||||||
|
import project.Data.Aggregate_Column.Aggregate_Column
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Make an aggregate column selector.
|
||||||
|
make_aggregate_column_selector : Table -> Display -> Boolean -> Single_Choice
|
||||||
|
make_aggregate_column_selector table display=Display.Always include_group_by=True =
|
||||||
|
col_names_selector = make_column_name_selector table display=Display.Always
|
||||||
|
column_widget = Pair.new "column" col_names_selector
|
||||||
|
|
||||||
|
col_list_selector = make_column_name_vector_selector table display=Display.Always
|
||||||
|
|
||||||
|
group_by = if include_group_by then [Option "Group By" "(Aggregate_Column.Group_By)" [column_widget]] else []
|
||||||
|
count = Option "Count" "Aggregate_Column.Count"
|
||||||
|
count_distinct = Option "Count Distinct" "(Aggregate_Column.Count_Distinct)" [Pair.new "columns" (col_list_selector)]
|
||||||
|
first = Option "First" "(Aggregate_Column.First)" [column_widget, Pair.new "order_by" (col_list_selector)]
|
||||||
|
last = Option "Last" "(Aggregate_Column.Last)" [column_widget, Pair.new "order_by" (col_list_selector)]
|
||||||
|
|
||||||
|
count_not_nothing = Option "Count Not Nothing" "(Aggregate_Column.Count_Not_Nothing)" [column_widget]
|
||||||
|
count_nothing = Option "Count Nothing" "(Aggregate_Column.Count_Nothing)" [column_widget]
|
||||||
|
|
||||||
|
## Should be a list of Text columns only
|
||||||
|
count_not_empty = Option "Count Not Empty" "(Aggregate_Column.Count_Not_Empty)" [column_widget]
|
||||||
|
count_empty = Option "Count Empty" "(Aggregate_Column.Count_Empty)" [column_widget]
|
||||||
|
concatenate = Option "Concatenate" "(Aggregate_Column.Concatenate)" [column_widget]
|
||||||
|
shortest = Option "Shortest" "(Aggregate_Column.Shortest)" [column_widget]
|
||||||
|
longest = Option "Longest" "(Aggregate_Column.Longest)" [column_widget]
|
||||||
|
|
||||||
|
## Should be a list of Numeric columns only
|
||||||
|
sum = Option "Sum" "(Aggregate_Column.Sum)" [column_widget]
|
||||||
|
average = Option "Average" "(Aggregate_Column.Average)" [column_widget]
|
||||||
|
median = Option "Median" "(Aggregate_Column.Median)" [column_widget]
|
||||||
|
percentile = Option "Percentile" "(Aggregate_Column.Percentile)" [column_widget]
|
||||||
|
mode = Option "Mode" "(Aggregate_Column.Mode)" [column_widget]
|
||||||
|
standard_deviation = Option "Standard Deviation" "(Aggregate_Column.Standard_Deviation)" [column_widget]
|
||||||
|
|
||||||
|
# Should be a list of comparable columns only
|
||||||
|
maximum = Option "Maximum" "(Aggregate_Column.Maximum)" [column_widget]
|
||||||
|
minimum = Option "Minimum" "(Aggregate_Column.Minimum)" [column_widget]
|
||||||
|
|
||||||
|
Single_Choice display=display values=(group_by+[count, count_distinct, first, last, count_not_nothing, count_nothing, count_not_empty, count_empty, concatenate, shortest, longest, sum, average, median, percentile, mode, standard_deviation, maximum, minimum])
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Make a column name selector.
|
Make a column name selector.
|
||||||
make_column_name_selector : Table -> Display -> Single_Choice
|
make_column_name_selector : Table -> Display -> Single_Choice
|
||||||
make_column_name_selector table display=Display.Always =
|
make_column_name_selector table display=Display.Always =
|
||||||
Single_Choice display=display values=(table.column_names.map n->(Option n n.pretty))
|
col_names = table.column_names
|
||||||
|
names = col_names.map n-> Option n n.pretty
|
||||||
|
Single_Choice display=display values=names
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Make a multiple column name selector.
|
||||||
|
make_column_name_vector_selector : Table -> Display -> Vector_Editor
|
||||||
|
make_column_name_vector_selector table display=Display.Always =
|
||||||
|
item_editor = make_column_name_selector table display=Display.Always
|
||||||
|
Vector_Editor item_editor=item_editor item_default=table.column_names.first.pretty display=display
|
||||||
|
|
||||||
|
## PRIVATE
|
||||||
|
Make a column name selector.
|
||||||
|
make_order_by_selector : Table -> Display -> Single_Choice
|
||||||
|
make_order_by_selector table display=Display.Always =
|
||||||
|
col_names = table.column_names
|
||||||
|
names = col_names.fold [] c-> n-> c + [Option n+" (Asc)" n.pretty, Option n+" (Desc)" "(Sort_Column.Name "+n.pretty+" Sort_Direction.Descending)"]
|
||||||
|
Single_Choice display=display values=names
|
||||||
|
|
||||||
## PRIVATE
|
## PRIVATE
|
||||||
Selector for type argument on `Column.parse`.
|
Selector for type argument on `Column.parse`.
|
||||||
@ -21,11 +77,3 @@ parse_type_selector =
|
|||||||
options = names.zip choice . map pair-> Option pair.first pair.second
|
options = names.zip choice . map pair-> Option pair.first pair.second
|
||||||
Single_Choice display=Display.Always values=options
|
Single_Choice display=Display.Always values=options
|
||||||
|
|
||||||
## PRIVATE
|
|
||||||
Selector for type argument on `Column.parse`.
|
|
||||||
join_kind_selector : Single_Choice
|
|
||||||
join_kind_selector =
|
|
||||||
choice = ['Join_Kind.Inner','Join_Kind.Left_Outer','Join_Kind.Right_Outer','Join_Kind.Full','Join_Kind.Left_Exclusive','Join_Kind.Right_Exclusive']
|
|
||||||
names = ['Inner', 'Left Outer', 'Right Outer', 'Full', 'Left Exclusive', 'Right Exclusive']
|
|
||||||
options = names.zip choice . map pair-> Option pair.first pair.second
|
|
||||||
Single_Choice display=Display.Always values=options
|
|
||||||
|
@ -5,6 +5,20 @@ import java.time.YearMonth;
|
|||||||
import java.time.temporal.*;
|
import java.time.temporal.*;
|
||||||
|
|
||||||
public class Date_Period_Utils implements TimeUtilsBase {
|
public class Date_Period_Utils implements TimeUtilsBase {
|
||||||
|
private static final long NANOSECONDS_IN_DAY = 86_400_000_000_000L;
|
||||||
|
public static TemporalAdjuster day_start =
|
||||||
|
(Temporal temporal) -> {
|
||||||
|
return temporal.isSupported(ChronoField.NANO_OF_DAY)
|
||||||
|
? temporal.with(ChronoField.NANO_OF_DAY, 0)
|
||||||
|
: temporal;
|
||||||
|
};
|
||||||
|
|
||||||
|
public static TemporalAdjuster day_end =
|
||||||
|
(Temporal temporal) -> {
|
||||||
|
return temporal.isSupported(ChronoField.NANO_OF_DAY)
|
||||||
|
? temporal.with(ChronoField.NANO_OF_DAY, NANOSECONDS_IN_DAY - 1)
|
||||||
|
: temporal;
|
||||||
|
};
|
||||||
|
|
||||||
public static TemporalAdjuster quarter_start =
|
public static TemporalAdjuster quarter_start =
|
||||||
(Temporal temporal) -> {
|
(Temporal temporal) -> {
|
||||||
|
@ -334,7 +334,7 @@ public class DelimitedReader {
|
|||||||
private WithProblems<List<String>> generateDefaultHeaders(int columnCount) {
|
private WithProblems<List<String>> generateDefaultHeaders(int columnCount) {
|
||||||
List<String> headerNames = new ArrayList<>(columnCount);
|
List<String> headerNames = new ArrayList<>(columnCount);
|
||||||
for (int i = 0; i < columnCount; ++i) {
|
for (int i = 0; i < columnCount; ++i) {
|
||||||
headerNames.add(COLUMN_NAME + "_" + (i + 1));
|
headerNames.add(COLUMN_NAME + " " + (i + 1));
|
||||||
}
|
}
|
||||||
return new WithProblems<>(headerNames, Collections.emptyList());
|
return new WithProblems<>(headerNames, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public class NameDeduplicator {
|
|||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
return name + "_" + index;
|
return name + " " + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getInvalidNames() {
|
public String[] getInvalidNames() {
|
||||||
@ -134,7 +134,7 @@ public class NameDeduplicator {
|
|||||||
String name = second.get(i);
|
String name = second.get(i);
|
||||||
if (output.get(i) == null) {
|
if (output.get(i) == null) {
|
||||||
var prefixed = secondPrefix + name;
|
var prefixed = secondPrefix + name;
|
||||||
output.set(i, makeUnique(secondPrefix + name));
|
output.set(i, makeUnique(prefixed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
@ -111,9 +111,9 @@ spec setup =
|
|||||||
materialized.columns.at 0 . at 0 . should_equal 56.708660 epsilon=0.000001
|
materialized.columns.at 0 . at 0 . should_equal 56.708660 epsilon=0.000001
|
||||||
materialized.columns.at 1 . name . should_equal "Standard Deviation ValueWithNothing"
|
materialized.columns.at 1 . name . should_equal "Standard Deviation ValueWithNothing"
|
||||||
materialized.columns.at 1 . at 0 . should_equal 58.588610 epsilon=0.000001
|
materialized.columns.at 1 . at 0 . should_equal 58.588610 epsilon=0.000001
|
||||||
materialized.columns.at 2 . name . should_equal "Standard Deviation Value_1"
|
materialized.columns.at 2 . name . should_equal "Standard Deviation Value 1"
|
||||||
materialized.columns.at 2 . at 0 . should_equal 56.697317 epsilon=0.000001
|
materialized.columns.at 2 . at 0 . should_equal 56.697317 epsilon=0.000001
|
||||||
materialized.columns.at 3 . name . should_equal "Standard Deviation ValueWithNothing_1"
|
materialized.columns.at 3 . name . should_equal "Standard Deviation ValueWithNothing 1"
|
||||||
materialized.columns.at 3 . at 0 . should_equal 58.575554 epsilon=0.000001
|
materialized.columns.at 3 . at 0 . should_equal 58.575554 epsilon=0.000001
|
||||||
|
|
||||||
Test.specify "should be able to create median, mode and percentile values" (pending = resolve_pending test_selection.advanced_stats) <|
|
Test.specify "should be able to create median, mode and percentile values" (pending = resolve_pending test_selection.advanced_stats) <|
|
||||||
@ -153,7 +153,7 @@ spec setup =
|
|||||||
materialized.column_count . should_equal 3
|
materialized.column_count . should_equal 3
|
||||||
materialized.columns.at 0 . name . should_equal "First TextWithNothing"
|
materialized.columns.at 0 . name . should_equal "First TextWithNothing"
|
||||||
materialized.columns.at 0 . at 0 . should_equal "riwaiqq1io"
|
materialized.columns.at 0 . at 0 . should_equal "riwaiqq1io"
|
||||||
materialized.columns.at 1 . name . should_equal "First TextWithNothing_1"
|
materialized.columns.at 1 . name . should_equal "First TextWithNothing 1"
|
||||||
materialized.columns.at 1 . at 0 . should_equal "j4i2ua7uft"
|
materialized.columns.at 1 . at 0 . should_equal "j4i2ua7uft"
|
||||||
materialized.columns.at 2 . name . should_equal "Last ValueWithNothing"
|
materialized.columns.at 2 . name . should_equal "Last ValueWithNothing"
|
||||||
materialized.columns.at 2 . at 0 . should_equal -38.56 epsilon=0.000001
|
materialized.columns.at 2 . at 0 . should_equal -38.56 epsilon=0.000001
|
||||||
@ -236,7 +236,7 @@ spec setup =
|
|||||||
materialized.column_count . should_equal 2
|
materialized.column_count . should_equal 2
|
||||||
materialized.columns.at 0 . name . should_equal "Count Distinct Code"
|
materialized.columns.at 0 . name . should_equal "Count Distinct Code"
|
||||||
materialized.columns.at 0 . at 0 . should_equal 0
|
materialized.columns.at 0 . at 0 . should_equal 0
|
||||||
materialized.columns.at 1 . name . should_equal "Count Distinct Code_1"
|
materialized.columns.at 1 . name . should_equal "Count Distinct Code 1"
|
||||||
materialized.columns.at 1 . at 0 . should_equal 0
|
materialized.columns.at 1 . at 0 . should_equal 0
|
||||||
|
|
||||||
Test.specify "should be able to compute sum and average of values" <|
|
Test.specify "should be able to compute sum and average of values" <|
|
||||||
@ -527,9 +527,9 @@ spec setup =
|
|||||||
materialized.columns.at 1 . at idx . should_equal 60.272158 epsilon=0.000001
|
materialized.columns.at 1 . at idx . should_equal 60.272158 epsilon=0.000001
|
||||||
materialized.columns.at 2 . name . should_equal "Standard Deviation ValueWithNothing"
|
materialized.columns.at 2 . name . should_equal "Standard Deviation ValueWithNothing"
|
||||||
materialized.columns.at 2 . at idx . should_equal 56.798691 epsilon=0.000001
|
materialized.columns.at 2 . at idx . should_equal 56.798691 epsilon=0.000001
|
||||||
materialized.columns.at 3 . name . should_equal "Standard Deviation Value_1"
|
materialized.columns.at 3 . name . should_equal "Standard Deviation Value 1"
|
||||||
materialized.columns.at 3 . at idx . should_equal 60.156583 epsilon=0.000001
|
materialized.columns.at 3 . at idx . should_equal 60.156583 epsilon=0.000001
|
||||||
materialized.columns.at 4 . name . should_equal "Standard Deviation ValueWithNothing_1"
|
materialized.columns.at 4 . name . should_equal "Standard Deviation ValueWithNothing 1"
|
||||||
materialized.columns.at 4 . at idx . should_equal 56.677714 epsilon=0.000001
|
materialized.columns.at 4 . at idx . should_equal 56.677714 epsilon=0.000001
|
||||||
|
|
||||||
Test.specify "should be able to create median values" (pending = resolve_pending test_selection.advanced_stats) <|
|
Test.specify "should be able to create median values" (pending = resolve_pending test_selection.advanced_stats) <|
|
||||||
@ -735,9 +735,9 @@ spec setup =
|
|||||||
materialized.columns.at 2 . at idx . should_equal 58.979275 epsilon=0.000001
|
materialized.columns.at 2 . at idx . should_equal 58.979275 epsilon=0.000001
|
||||||
materialized.columns.at 3 . name . should_equal "Standard Deviation ValueWithNothing"
|
materialized.columns.at 3 . name . should_equal "Standard Deviation ValueWithNothing"
|
||||||
materialized.columns.at 3 . at idx . should_equal 57.561756 epsilon=0.000001
|
materialized.columns.at 3 . at idx . should_equal 57.561756 epsilon=0.000001
|
||||||
materialized.columns.at 4 . name . should_equal "Standard Deviation Value_1"
|
materialized.columns.at 4 . name . should_equal "Standard Deviation Value 1"
|
||||||
materialized.columns.at 4 . at idx . should_equal 58.746614 epsilon=0.000001
|
materialized.columns.at 4 . at idx . should_equal 58.746614 epsilon=0.000001
|
||||||
materialized.columns.at 5 . name . should_equal "Standard Deviation ValueWithNothing_1"
|
materialized.columns.at 5 . name . should_equal "Standard Deviation ValueWithNothing 1"
|
||||||
materialized.columns.at 5 . at idx . should_equal 57.306492 epsilon=0.000001
|
materialized.columns.at 5 . at idx . should_equal 57.306492 epsilon=0.000001
|
||||||
|
|
||||||
Test.specify "should be able to create median values" (pending = resolve_pending test_selection.advanced_stats) <|
|
Test.specify "should be able to create median values" (pending = resolve_pending test_selection.advanced_stats) <|
|
||||||
@ -1366,25 +1366,25 @@ spec setup =
|
|||||||
Test.specify "should raise a warning when an invalid output name" <|
|
Test.specify "should raise a warning when an invalid output name" <|
|
||||||
action = table.aggregate [Group_By "Index" ""] on_problems=_
|
action = table.aggregate [Group_By "Index" ""] on_problems=_
|
||||||
problems = [Invalid_Output_Column_Names.Error [""]]
|
problems = [Invalid_Output_Column_Names.Error [""]]
|
||||||
tester = expect_column_names ["Column_1"]
|
tester = expect_column_names ["Column 1"]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should raise a warning when a duplicate column name" <|
|
Test.specify "should raise a warning when a duplicate column name" <|
|
||||||
action = table.aggregate [Group_By "Index", Group_By 0] on_problems=_
|
action = table.aggregate [Group_By "Index", Group_By 0] on_problems=_
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["Index"]]
|
problems = [Duplicate_Output_Column_Names.Error ["Index"]]
|
||||||
tester = expect_column_names ["Index", "Index_1"]
|
tester = expect_column_names ["Index", "Index 1"]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should raise a warning when a duplicate column name and rename default names first" <|
|
Test.specify "should raise a warning when a duplicate column name and rename default names first" <|
|
||||||
action = table.aggregate [Group_By "Value", Group_By "Index" "Value"] on_problems=_
|
action = table.aggregate [Group_By "Value", Group_By "Index" "Value"] on_problems=_
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["Value"]]
|
problems = [Duplicate_Output_Column_Names.Error ["Value"]]
|
||||||
tester = expect_column_names ["Value_1", "Value"]
|
tester = expect_column_names ["Value 1", "Value"]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should raise a warning when duplicate column names" <|
|
Test.specify "should raise a warning when duplicate column names" <|
|
||||||
action = table.aggregate [Sum "Value" new_name="AGG1", Count new_name="AGG1"] on_problems=_
|
action = table.aggregate [Sum "Value" new_name="AGG1", Count new_name="AGG1"] on_problems=_
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["AGG1"]]
|
problems = [Duplicate_Output_Column_Names.Error ["AGG1"]]
|
||||||
tester = expect_column_names ["AGG1", "AGG1_1"]
|
tester = expect_column_names ["AGG1", "AGG1 1"]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should allow partial matches on Count_Distinct" <|
|
Test.specify "should allow partial matches on Count_Distinct" <|
|
||||||
|
@ -21,8 +21,8 @@ spec setup =
|
|||||||
col1 = ["foo", [1,2,3]]
|
col1 = ["foo", [1,2,3]]
|
||||||
col2 = ["bar", [4,5,6]]
|
col2 = ["bar", [4,5,6]]
|
||||||
col3 = ["Baz", [7,8,9]]
|
col3 = ["Baz", [7,8,9]]
|
||||||
col4 = ["foo_1", [10,11,12]]
|
col4 = ["foo 1", [10,11,12]]
|
||||||
col5 = ["foo_2", [13,14,15]]
|
col5 = ["foo 2", [13,14,15]]
|
||||||
col6 = ["ab.+123", [16,17,18]]
|
col6 = ["ab.+123", [16,17,18]]
|
||||||
col7 = ["abcd123", [19,20,21]]
|
col7 = ["abcd123", [19,20,21]]
|
||||||
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
||||||
@ -100,11 +100,11 @@ spec setup =
|
|||||||
Test.specify "should allow adding a column" <|
|
Test.specify "should allow adding a column" <|
|
||||||
bar2 = table.get "bar" . rename "bar2"
|
bar2 = table.get "bar" . rename "bar2"
|
||||||
t2 = table.set bar2
|
t2 = table.set bar2
|
||||||
t2.column_names . should_equal ["foo", "bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "bar2"]
|
t2.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "bar2"]
|
||||||
t2.get "bar2" . to_vector . should_equal [4, 5, 6]
|
t2.get "bar2" . to_vector . should_equal [4, 5, 6]
|
||||||
|
|
||||||
t3 = t2.set bar2 "bar3"
|
t3 = t2.set bar2 "bar3"
|
||||||
t3.column_names . should_equal ["foo", "bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "bar2", "bar3"]
|
t3.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "bar2", "bar3"]
|
||||||
|
|
||||||
Test.specify "should not allow illegal column names" <|
|
Test.specify "should not allow illegal column names" <|
|
||||||
table.set (table.get "bar") new_name="" . should_fail_with Illegal_Argument
|
table.set (table.get "bar") new_name="" . should_fail_with Illegal_Argument
|
||||||
@ -113,11 +113,11 @@ spec setup =
|
|||||||
Test.specify "should allow replacing a column" <|
|
Test.specify "should allow replacing a column" <|
|
||||||
foo = table.get "bar" . rename "foo"
|
foo = table.get "bar" . rename "foo"
|
||||||
t2 = table.set foo
|
t2 = table.set foo
|
||||||
t2.column_names . should_equal ["foo", "bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"]
|
t2.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"]
|
||||||
t2.get "foo" . to_vector . should_equal [4, 5, 6]
|
t2.get "foo" . to_vector . should_equal [4, 5, 6]
|
||||||
|
|
||||||
t3 = t2.set foo "bar3"
|
t3 = t2.set foo "bar3"
|
||||||
t3.column_names . should_equal ["foo", "bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "bar3"]
|
t3.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "bar3"]
|
||||||
|
|
||||||
Test.specify "should allow adding a column" <|
|
Test.specify "should allow adding a column" <|
|
||||||
bar2 = table.get "bar" . rename "bar2"
|
bar2 = table.get "bar" . rename "bar2"
|
||||||
@ -166,7 +166,7 @@ spec setup =
|
|||||||
|
|
||||||
Test.group prefix+"Table.column_names" <|
|
Test.group prefix+"Table.column_names" <|
|
||||||
Test.specify "should return the names of all columns" <|
|
Test.specify "should return the names of all columns" <|
|
||||||
table.column_names . should_equal ["foo", "bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"]
|
table.column_names . should_equal ["foo", "bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"]
|
||||||
|
|
||||||
Test.specify "should allow weird column names in all backends" <|
|
Test.specify "should allow weird column names in all backends" <|
|
||||||
columns = weird_names.map_with_index ix-> name->
|
columns = weird_names.map_with_index ix-> name->
|
||||||
|
@ -149,14 +149,14 @@ spec setup =
|
|||||||
Test.specify "should gracefully handle duplicate aggregate names" <|
|
Test.specify "should gracefully handle duplicate aggregate names" <|
|
||||||
action = table.cross_tab [] "Key" values=[Count new_name="Agg1", Sum "Value" new_name="Agg1"] on_problems=_
|
action = table.cross_tab [] "Key" values=[Count new_name="Agg1", Sum "Value" new_name="Agg1"] on_problems=_
|
||||||
tester table =
|
tester table =
|
||||||
table.column_names . should_equal ["x Agg1", "x Agg1_1", "y Agg1", "y Agg1_1", "z Agg1", "z Agg1_1"]
|
table.column_names . should_equal ["x Agg1", "x Agg1 1", "y Agg1", "y Agg1 1", "z Agg1", "z Agg1 1"]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["x Agg1", "y Agg1", "z Agg1"]]
|
problems = [Duplicate_Output_Column_Names.Error ["x Agg1", "y Agg1", "z Agg1"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
table3 = table2.rename_columns (Map.from_vector [["Group", "x"]])
|
table3 = table2.rename_columns (Map.from_vector [["Group", "x"]])
|
||||||
action3 = table3.cross_tab ["x"] "Key" on_problems=_
|
action3 = table3.cross_tab ["x"] "Key" on_problems=_
|
||||||
tester3 table =
|
tester3 table =
|
||||||
table.column_names . should_equal ["x", "x_1", "y", "z"]
|
table.column_names . should_equal ["x", "x 1", "y", "z"]
|
||||||
problems3 = [Duplicate_Output_Column_Names.Error ["x"]]
|
problems3 = [Duplicate_Output_Column_Names.Error ["x"]]
|
||||||
Problems.test_problem_handling action3 problems3 tester3
|
Problems.test_problem_handling action3 problems3 tester3
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ spec setup =
|
|||||||
|
|
||||||
t3 = t2.aggregate [Group_By "Letter", Count]
|
t3 = t2.aggregate [Group_By "Letter", Count]
|
||||||
t4 = t3.join t1 on="Count" join_kind=Join_Kind.Left_Outer |> materialize |> _.order_by "Letter"
|
t4 = t3.join t1 on="Count" join_kind=Join_Kind.Left_Outer |> materialize |> _.order_by "Letter"
|
||||||
t4.columns.map .name . should_equal ["Letter", "Count", "Right_Count", "Class"]
|
t4.columns.map .name . should_equal ["Letter", "Count", "Right Count", "Class"]
|
||||||
rows = t4.rows . map .to_vector
|
rows = t4.rows . map .to_vector
|
||||||
rows.at 0 . should_equal ["A", 4, Nothing, Nothing]
|
rows.at 0 . should_equal ["A", 4, Nothing, Nothing]
|
||||||
rows.at 1 . should_equal ["B", 3, 3, "Z"]
|
rows.at 1 . should_equal ["B", 3, 3, "Z"]
|
||||||
|
@ -94,7 +94,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1, 2]], ["Y", [4, 5]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [4, 5]]]
|
||||||
t2 = t1.cross_join t1
|
t2 = t1.cross_join t1
|
||||||
|
|
||||||
expect_column_names ["X", "Y", "Right_X", "Right_Y"] t2
|
expect_column_names ["X", "Y", "Right X", "Right Y"] t2
|
||||||
t2.row_count . should_equal 4
|
t2.row_count . should_equal 4
|
||||||
r = materialize t2 . rows . map .to_vector
|
r = materialize t2 . rows . map .to_vector
|
||||||
r.length . should_equal 4
|
r.length . should_equal 4
|
||||||
@ -108,26 +108,26 @@ spec setup =
|
|||||||
False -> r.should_equal expected_rows
|
False -> r.should_equal expected_rows
|
||||||
|
|
||||||
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
||||||
t1 = table_builder [["X", [1]], ["Y", [5]], ["Right_Y", [10]]]
|
t1 = table_builder [["X", [1]], ["Y", [5]], ["Right Y", [10]]]
|
||||||
t2 = table_builder [["X", ['a']], ["Y", ['d']]]
|
t2 = table_builder [["X", ['a']], ["Y", ['d']]]
|
||||||
|
|
||||||
t3 = t1.cross_join t2
|
t3 = t1.cross_join t2
|
||||||
expect_column_names ["X", "Y", "Right_Y", "Right_X", "Right_Y_1"] t3
|
expect_column_names ["X", "Y", "Right Y", "Right X", "Right Y 1"] t3
|
||||||
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right_Y"]]
|
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right Y"]]
|
||||||
t3.row_count . should_equal 1
|
t3.row_count . should_equal 1
|
||||||
t3.at "X" . to_vector . should_equal [1]
|
t3.at "X" . to_vector . should_equal [1]
|
||||||
t3.at "Y" . to_vector . should_equal [5]
|
t3.at "Y" . to_vector . should_equal [5]
|
||||||
t3.at "Right_Y" . to_vector . should_equal [10]
|
t3.at "Right Y" . to_vector . should_equal [10]
|
||||||
t3.at "Right_X" . to_vector . should_equal ['a']
|
t3.at "Right X" . to_vector . should_equal ['a']
|
||||||
t3.at "Right_Y_1" . to_vector . should_equal ['d']
|
t3.at "Right Y 1" . to_vector . should_equal ['d']
|
||||||
|
|
||||||
t1.cross_join t2 on_problems=Problem_Behavior.Report_Error . should_fail_with Duplicate_Output_Column_Names
|
t1.cross_join t2 on_problems=Problem_Behavior.Report_Error . should_fail_with Duplicate_Output_Column_Names
|
||||||
|
|
||||||
expect_column_names ["X", "Y", "Right_Y", "X_1", "Y_1"] (t1.cross_join t2 right_prefix="")
|
expect_column_names ["X", "Y", "Right Y", "X 1", "Y 1"] (t1.cross_join t2 right_prefix="")
|
||||||
|
|
||||||
t4 = table_builder [["X", [1]], ["Right_X", [5]]]
|
t4 = table_builder [["X", [1]], ["Right X", [5]]]
|
||||||
expect_column_names ["X", "Y", "Right_Y", "Right_X_1", "Right_X"] (t1.cross_join t4)
|
expect_column_names ["X", "Y", "Right Y", "Right X 1", "Right X"] (t1.cross_join t4)
|
||||||
expect_column_names ["X", "Right_X", "Right_X_1", "Y", "Right_Y"] (t4.cross_join t1)
|
expect_column_names ["X", "Right X", "Right X 1", "Y", "Right Y"] (t4.cross_join t1)
|
||||||
|
|
||||||
Test.specify "should respect the column ordering" <|
|
Test.specify "should respect the column ordering" <|
|
||||||
t1 = table_builder [["X", [100, 2]], ["Y", [4, 5]]]
|
t1 = table_builder [["X", [100, 2]], ["Y", [4, 5]]]
|
||||||
|
@ -34,9 +34,18 @@ spec setup =
|
|||||||
Test.group prefix+"Table.join" <|
|
Test.group prefix+"Table.join" <|
|
||||||
t1 = table_builder [["X", [1, 2, 3]], ["Y", [4, 5, 6]]]
|
t1 = table_builder [["X", [1, 2, 3]], ["Y", [4, 5, 6]]]
|
||||||
t2 = table_builder [["Z", [2, 3, 2, 4]], ["W", [4, 5, 6, 7]]]
|
t2 = table_builder [["Z", [2, 3, 2, 4]], ["W", [4, 5, 6, 7]]]
|
||||||
Test.specify "should allow to Inner join on equality of a the first column by default" <|
|
|
||||||
|
|
||||||
t3 = t1.join t2
|
Test.specify "should by default do a Left Outer join on equality of first column in the left table, correlated with column of the same name in the right one" <|
|
||||||
|
t3 = table_builder [["Z", [4, 5, 6, 7]], ["X", [2, 3, 2, 4]]]
|
||||||
|
t4 = t1.join t3 |> materialize |> _.order_by ["X", "Z"]
|
||||||
|
expect_column_names ["X", "Y", "Z", "Right X"] t4
|
||||||
|
t4.at "X" . to_vector . should_equal [1, 2, 2, 3]
|
||||||
|
t4.at "Y" . to_vector . should_equal [4, 5, 5, 6]
|
||||||
|
t4.at "Right X" . to_vector . should_equal [Nothing, 2, 2, 3]
|
||||||
|
t4.at "Z" . to_vector . should_equal [Nothing, 4, 6, 5]
|
||||||
|
|
||||||
|
Test.specify "should allow Inner join" <|
|
||||||
|
t3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals 0 0)
|
||||||
expect_column_names ["X", "Y", "Z", "W"] t3
|
expect_column_names ["X", "Y", "Z", "W"] t3
|
||||||
t4 = t3 |> materialize |> _.order_by ["X", "W"]
|
t4 = t3 |> materialize |> _.order_by ["X", "W"]
|
||||||
t4.at "X" . to_vector . should_equal [2, 2, 3]
|
t4.at "X" . to_vector . should_equal [2, 2, 3]
|
||||||
@ -45,23 +54,15 @@ spec setup =
|
|||||||
t4.at "W" . to_vector . should_equal [4, 6, 5]
|
t4.at "W" . to_vector . should_equal [4, 6, 5]
|
||||||
|
|
||||||
Test.specify "should allow Full join" <|
|
Test.specify "should allow Full join" <|
|
||||||
t3 = t1.join t2 join_kind=Join_Kind.Full |> materialize |> _.order_by ["X", "W"]
|
t3 = t1.join t2 join_kind=Join_Kind.Full on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X", "W"]
|
||||||
expect_column_names ["X", "Y", "Z", "W"] t3
|
expect_column_names ["X", "Y", "Z", "W"] t3
|
||||||
t3.at "X" . to_vector . should_equal [Nothing, 1, 2, 2, 3]
|
t3.at "X" . to_vector . should_equal [Nothing, 1, 2, 2, 3]
|
||||||
t3.at "Y" . to_vector . should_equal [Nothing, 4, 5, 5, 6]
|
t3.at "Y" . to_vector . should_equal [Nothing, 4, 5, 5, 6]
|
||||||
t3.at "Z" . to_vector . should_equal [4, Nothing, 2, 2, 3]
|
t3.at "Z" . to_vector . should_equal [4, Nothing, 2, 2, 3]
|
||||||
t3.at "W" . to_vector . should_equal [7, Nothing, 4, 6, 5]
|
t3.at "W" . to_vector . should_equal [7, Nothing, 4, 6, 5]
|
||||||
|
|
||||||
Test.specify "should allow Left Outer join" <|
|
|
||||||
t4 = t1.join t2 join_kind=Join_Kind.Left_Outer |> materialize |> _.order_by ["X", "W"]
|
|
||||||
expect_column_names ["X", "Y", "Z", "W"] t4
|
|
||||||
t4.at "X" . to_vector . should_equal [1, 2, 2, 3]
|
|
||||||
t4.at "Y" . to_vector . should_equal [4, 5, 5, 6]
|
|
||||||
t4.at "Z" . to_vector . should_equal [Nothing, 2, 2, 3]
|
|
||||||
t4.at "W" . to_vector . should_equal [Nothing, 4, 6, 5]
|
|
||||||
|
|
||||||
Test.specify "should allow Right Outer join" <|
|
Test.specify "should allow Right Outer join" <|
|
||||||
t5 = t1.join t2 join_kind=Join_Kind.Right_Outer |> materialize |> _.order_by ["X", "W"]
|
t5 = t1.join t2 join_kind=Join_Kind.Right_Outer on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X", "W"]
|
||||||
expect_column_names ["X", "Y", "Z", "W"] t5
|
expect_column_names ["X", "Y", "Z", "W"] t5
|
||||||
t5.at "X" . to_vector . should_equal [Nothing, 2, 2, 3]
|
t5.at "X" . to_vector . should_equal [Nothing, 2, 2, 3]
|
||||||
t5.at "Y" . to_vector . should_equal [Nothing, 5, 5, 6]
|
t5.at "Y" . to_vector . should_equal [Nothing, 5, 5, 6]
|
||||||
@ -69,12 +70,12 @@ spec setup =
|
|||||||
t5.at "W" . to_vector . should_equal [7, 4, 6, 5]
|
t5.at "W" . to_vector . should_equal [7, 4, 6, 5]
|
||||||
|
|
||||||
Test.specify "should allow to perform anti-joins" <|
|
Test.specify "should allow to perform anti-joins" <|
|
||||||
t6 = t1.join t2 join_kind=Join_Kind.Left_Exclusive |> materialize |> _.order_by ["X"]
|
t6 = t1.join t2 join_kind=Join_Kind.Left_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["X"]
|
||||||
t6.columns.map .name . should_equal ["X", "Y"]
|
t6.columns.map .name . should_equal ["X", "Y"]
|
||||||
t6.at "X" . to_vector . should_equal [1]
|
t6.at "X" . to_vector . should_equal [1]
|
||||||
t6.at "Y" . to_vector . should_equal [4]
|
t6.at "Y" . to_vector . should_equal [4]
|
||||||
|
|
||||||
t7 = t1.join t2 join_kind=Join_Kind.Right_Exclusive |> materialize |> _.order_by ["Z"]
|
t7 = t1.join t2 join_kind=Join_Kind.Right_Exclusive on=(Join_Condition.Equals 0 0) |> materialize |> _.order_by ["Z"]
|
||||||
t7.columns.map .name . should_equal ["Z", "W"]
|
t7.columns.map .name . should_equal ["Z", "W"]
|
||||||
t7.at "Z" . to_vector . should_equal [4]
|
t7.at "Z" . to_vector . should_equal [4]
|
||||||
t7.at "W" . to_vector . should_equal [7]
|
t7.at "W" . to_vector . should_equal [7]
|
||||||
@ -82,39 +83,39 @@ spec setup =
|
|||||||
t3 = table_builder [["X", [1, 1, 1, 2, 2, 2]], ["Y", ["A", "B", "B", "C", "C", "A"]], ["Z", [1, 2, 3, 4, 5, 6]]]
|
t3 = table_builder [["X", [1, 1, 1, 2, 2, 2]], ["Y", ["A", "B", "B", "C", "C", "A"]], ["Z", [1, 2, 3, 4, 5, 6]]]
|
||||||
t4 = table_builder [["X", [1, 1, 3, 2, 2, 4]], ["Y", ["B", "B", "C", "C", "D", "A"]], ["Z", [1, 2, 3, 4, 5, 6]]]
|
t4 = table_builder [["X", [1, 1, 3, 2, 2, 4]], ["Y", ["B", "B", "C", "C", "D", "A"]], ["Z", [1, 2, 3, 4, 5, 6]]]
|
||||||
check_xy_joined r =
|
check_xy_joined r =
|
||||||
expect_column_names ["X", "Y", "Z", "Right_Z"] r
|
expect_column_names ["X", "Y", "Z", "Right Z"] r
|
||||||
r.at "X" . to_vector . should_equal [1, 1, 1, 1, 2, 2]
|
r.at "X" . to_vector . should_equal [1, 1, 1, 1, 2, 2]
|
||||||
r.at "Y" . to_vector . should_equal ["B", "B", "B", "B", "C", "C"]
|
r.at "Y" . to_vector . should_equal ["B", "B", "B", "B", "C", "C"]
|
||||||
r.at "Z" . to_vector . should_equal [2, 2, 3, 3, 4, 5]
|
r.at "Z" . to_vector . should_equal [2, 2, 3, 3, 4, 5]
|
||||||
r.at "Right_Z" . to_vector . should_equal [1, 2, 1, 2, 4, 4]
|
r.at "Right Z" . to_vector . should_equal [1, 2, 1, 2, 4, 4]
|
||||||
|
|
||||||
Test.specify "should allow to join on equality of multiple columns and drop redundant columns if Inner join" <|
|
Test.specify "should allow to join on equality of multiple columns and drop redundant columns if Inner join" <|
|
||||||
conditions = [Join_Condition.Equals "Y" "Y", Join_Condition.Equals "X" "X"]
|
conditions = [Join_Condition.Equals "Y" "Y", Join_Condition.Equals "X" "X"]
|
||||||
r = t3.join t4 on=conditions |> materialize |> _.order_by ["X", "Y", "Z", "Right_Z"]
|
r = t3.join t4 join_kind=Join_Kind.Inner on=conditions |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
|
||||||
check_xy_joined r
|
check_xy_joined r
|
||||||
|
|
||||||
[Join_Kind.Full, Join_Kind.Left_Outer, Join_Kind.Right_Outer].each kind->
|
[Join_Kind.Full, Join_Kind.Left_Outer, Join_Kind.Right_Outer].each kind->
|
||||||
r2 = t3.join t4 join_kind=kind on=conditions
|
r2 = t3.join t4 join_kind=kind on=conditions
|
||||||
expect_column_names ["X", "Y", "Z", "Right_X", "Right_Y", "Right_Z"] r2
|
expect_column_names ["X", "Y", "Z", "Right X", "Right Y", "Right Z"] r2
|
||||||
|
|
||||||
Test.specify "should support same-name column join shorthand" <|
|
Test.specify "should support same-name column join shorthand" <|
|
||||||
r = t3.join t4 on=["X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right_Z"]
|
r = t3.join t4 join_kind=Join_Kind.Inner on=["X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
|
||||||
check_xy_joined r
|
check_xy_joined r
|
||||||
|
|
||||||
Test.specify "should allow to join on text equality ignoring case" <|
|
Test.specify "should allow to join on text equality ignoring case" <|
|
||||||
t1 = table_builder [["X", ["a", "B"]], ["Y", [1, 2]]]
|
t1 = table_builder [["X", ["a", "B"]], ["Y", [1, 2]]]
|
||||||
t2 = table_builder [["X", ["A", "a", "b"]], ["Z", [1, 2, 3]]]
|
t2 = table_builder [["X", ["A", "a", "b"]], ["Z", [1, 2, 3]]]
|
||||||
|
|
||||||
r1 = t1.join t2
|
r1 = t1.join t2 join_kind=Join_Kind.Inner
|
||||||
expect_column_names ["X", "Y", "Z"] r1
|
expect_column_names ["X", "Y", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal ["a"]
|
r1 . at "X" . to_vector . should_equal ["a"]
|
||||||
r1 . at "Y" . to_vector . should_equal [1]
|
r1 . at "Y" . to_vector . should_equal [1]
|
||||||
r1 . at "Z" . to_vector . should_equal [2]
|
r1 . at "Z" . to_vector . should_equal [2]
|
||||||
|
|
||||||
r2 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Z"]
|
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Z"]
|
||||||
expect_column_names ["X", "Y", "Right_X", "Z"] r2
|
expect_column_names ["X", "Y", "Right X", "Z"] r2
|
||||||
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
|
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
|
||||||
r2 . at "Right_X" . to_vector . should_equal ["A", "a", "b"]
|
r2 . at "Right X" . to_vector . should_equal ["A", "a", "b"]
|
||||||
r2 . at "Y" . to_vector . should_equal [1, 1, 2]
|
r2 . at "Y" . to_vector . should_equal [1, 1, 2]
|
||||||
r2 . at "Z" . to_vector . should_equal [1, 2, 3]
|
r2 . at "Z" . to_vector . should_equal [1, 2, 3]
|
||||||
|
|
||||||
@ -123,16 +124,16 @@ spec setup =
|
|||||||
t1 = table_builder [["X", ['s\u0301', 'S\u0301']], ["Y", [1, 2]]]
|
t1 = table_builder [["X", ['s\u0301', 'S\u0301']], ["Y", [1, 2]]]
|
||||||
t2 = table_builder [["X", ['s', 'S', 'ś']], ["Z", [1, 2, 3]]]
|
t2 = table_builder [["X", ['s', 'S', 'ś']], ["Z", [1, 2, 3]]]
|
||||||
|
|
||||||
r1 = t1.join t2
|
r1 = t1.join t2 join_kind=Join_Kind.Inner
|
||||||
expect_column_names ["X", "Y", "Z"] r1
|
expect_column_names ["X", "Y", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal ['ś']
|
r1 . at "X" . to_vector . should_equal ['ś']
|
||||||
r1 . at "Y" . to_vector . should_equal [1]
|
r1 . at "Y" . to_vector . should_equal [1]
|
||||||
r1 . at "Z" . to_vector . should_equal [3]
|
r1 . at "Z" . to_vector . should_equal [3]
|
||||||
|
|
||||||
r2 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
|
r2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Right_X", "Z"] r2
|
expect_column_names ["X", "Y", "Right X", "Z"] r2
|
||||||
r2 . at "X" . to_vector . should_equal ['s\u0301', 'S\u0301']
|
r2 . at "X" . to_vector . should_equal ['s\u0301', 'S\u0301']
|
||||||
r2 . at "Right_X" . to_vector . should_equal ['ś', 'ś']
|
r2 . at "Right X" . to_vector . should_equal ['ś', 'ś']
|
||||||
r2 . at "Y" . to_vector . should_equal [1, 2]
|
r2 . at "Y" . to_vector . should_equal [1, 2]
|
||||||
r2 . at "Z" . to_vector . should_equal [3, 3]
|
r2 . at "Z" . to_vector . should_equal [3, 3]
|
||||||
|
|
||||||
@ -141,7 +142,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1, 2]], ["Y", [10, 20]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [10, 20]]]
|
||||||
t2 = table_builder [["X", [2.0, 2.1, 0.0]], ["Z", [1, 2, 3]]]
|
t2 = table_builder [["X", [2.0, 2.1, 0.0]], ["Z", [1, 2, 3]]]
|
||||||
|
|
||||||
r1 = t1.join t2
|
r1 = t1.join t2 join_kind=Join_Kind.Inner
|
||||||
expect_column_names ["X", "Y", "Z"] r1
|
expect_column_names ["X", "Y", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal [2]
|
r1 . at "X" . to_vector . should_equal [2]
|
||||||
r1 . at "Y" . to_vector . should_equal [20]
|
r1 . at "Y" . to_vector . should_equal [20]
|
||||||
@ -152,14 +153,14 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [My_Type.Value 1 2, My_Type.Value 2 3]], ["Y", [1, 2]]]
|
t1 = table_builder [["X", [My_Type.Value 1 2, My_Type.Value 2 3]], ["Y", [1, 2]]]
|
||||||
t2 = table_builder [["X", [My_Type.Value 5 0, My_Type.Value 2 1]], ["Z", [10, 20]]]
|
t2 = table_builder [["X", [My_Type.Value 5 0, My_Type.Value 2 1]], ["Z", [10, 20]]]
|
||||||
|
|
||||||
r1 = t1.join t2 |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Z"] r1
|
expect_column_names ["X", "Y", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal [My_Type.Value 1 2, My_Type.Value 2 3]
|
r1 . at "X" . to_vector . should_equal [My_Type.Value 1 2, My_Type.Value 2 3]
|
||||||
## We don't keep the other column, because the values in both
|
## We don't keep the other column, because the values in both
|
||||||
are equal. However, with custom comparators, they may not be
|
are equal. However, with custom comparators, they may not be
|
||||||
the same values, so we may consider keeping it. For not it is
|
the same values, so we may consider keeping it. For not it is
|
||||||
dropped though for consistency.
|
dropped though for consistency.
|
||||||
# r1 . at "Right_X" . to_vector . should_equal [My_Type.Value 1 2, My_Type.Value 2 3]
|
# r1 . at "Right X" . to_vector . should_equal [My_Type.Value 1 2, My_Type.Value 2 3]
|
||||||
r1 . at "Y" . to_vector . should_equal [1, 2]
|
r1 . at "Y" . to_vector . should_equal [1, 2]
|
||||||
r1 . at "Z" . to_vector . should_equal [20, 10]
|
r1 . at "Z" . to_vector . should_equal [20, 10]
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
|
t1 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
|
||||||
t2 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
|
t2 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
|
r1 = t1.join join_kind=Join_Kind.Inner t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
|
||||||
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
|
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
|
||||||
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
|
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
|
||||||
@ -179,7 +180,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", ["a", "b", "c"]], ["Y", [1, 2, 3]]]
|
t1 = table_builder [["X", ["a", "b", "c"]], ["Y", [1, 2, 3]]]
|
||||||
t2 = table_builder [["lower", ["a", "b"]], ["upper", ["a", "ccc"]], ["Z", [10, 20]]]
|
t2 = table_builder [["lower", ["a", "b"]], ["upper", ["a", "ccc"]], ["Z", [10, 20]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["X", "Z"]
|
||||||
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal ["a", "b", "c"]
|
r1 . at "X" . to_vector . should_equal ["a", "b", "c"]
|
||||||
r1 . at "Y" . to_vector . should_equal [1, 2, 3]
|
r1 . at "Y" . to_vector . should_equal [1, 2, 3]
|
||||||
@ -192,7 +193,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", ['s\u0301', 's']], ["Y", [1, 2]]]
|
t1 = table_builder [["X", ['s\u0301', 's']], ["Y", [1, 2]]]
|
||||||
t2 = table_builder [["lower", ['s', 'ś']], ["upper", ['sa', 'ś']], ["Z", [10, 20]]]
|
t2 = table_builder [["lower", ['s', 'ś']], ["upper", ['sa', 'ś']], ["Z", [10, 20]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
||||||
r1 . at "X" . to_vector . should_equal ['s\u0301', 's']
|
r1 . at "X" . to_vector . should_equal ['s\u0301', 's']
|
||||||
r1 . at "Y" . to_vector . should_equal [1, 2]
|
r1 . at "Y" . to_vector . should_equal [1, 2]
|
||||||
@ -205,7 +206,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [My_Type.Value 20 30, My_Type.Value 1 2]], ["Y", [1, 2]]]
|
t1 = table_builder [["X", [My_Type.Value 20 30, My_Type.Value 1 2]], ["Y", [1, 2]]]
|
||||||
t2 = table_builder [["lower", [My_Type.Value 3 0, My_Type.Value 10 10]], ["upper", [My_Type.Value 2 1, My_Type.Value 100 0]], ["Z", [10, 20]]]
|
t2 = table_builder [["lower", [My_Type.Value 3 0, My_Type.Value 10 10]], ["upper", [My_Type.Value 2 1, My_Type.Value 100 0]], ["Z", [10, 20]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Z"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "lower" "upper") |> materialize |> _.order_by ["Z"]
|
||||||
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
expect_column_names ["X", "Y", "lower", "upper", "Z"] r1
|
||||||
r1 . at "X" . to_vector . to_text . should_equal "[(My_Type.Value 1 2), (My_Type.Value 20 30)]"
|
r1 . at "X" . to_vector . to_text . should_equal "[(My_Type.Value 1 2), (My_Type.Value 20 30)]"
|
||||||
r1 . at "Y" . to_vector . should_equal [2, 1]
|
r1 . at "Y" . to_vector . should_equal [2, 1]
|
||||||
@ -217,25 +218,25 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1, 12, 12, 0]], ["Y", [1, 2, 3, 4]], ["Z", ["a", "A", "a", "ą"]], ["W", [1, 2, 3, 4]]]
|
t1 = table_builder [["X", [1, 12, 12, 0]], ["Y", [1, 2, 3, 4]], ["Z", ["a", "A", "a", "ą"]], ["W", [1, 2, 3, 4]]]
|
||||||
t2 = table_builder [["X", [12, 12, 1]], ["l", [0, 100, 100]], ["u", [10, 100, 100]], ["Z", ["A", "A", "A"]], ["W'", [10, 20, 30]]]
|
t2 = table_builder [["X", [12, 12, 1]], ["l", [0, 100, 100]], ["u", [10, 100, 100]], ["Z", ["A", "A", "A"]], ["W'", [10, 20, 30]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=[Join_Condition.Between "Y" "l" "u", Join_Condition.Equals_Ignore_Case "Z" "Z", Join_Condition.Equals "X" "X"] |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=[Join_Condition.Between "Y" "l" "u", Join_Condition.Equals_Ignore_Case "Z" "Z", Join_Condition.Equals "X" "X"] |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Z", "W", "l", "u", "Right_Z", "W'"] r1
|
expect_column_names ["X", "Y", "Z", "W", "l", "u", "Right Z", "W'"] r1
|
||||||
r1.at "X" . to_vector . should_equal [12, 12]
|
r1.at "X" . to_vector . should_equal [12, 12]
|
||||||
r1.at "Y" . to_vector . should_equal [2, 3]
|
r1.at "Y" . to_vector . should_equal [2, 3]
|
||||||
r1.at "Z" . to_vector . should_equal ["A", "a"]
|
r1.at "Z" . to_vector . should_equal ["A", "a"]
|
||||||
r1.at "W" . to_vector . should_equal [2, 3]
|
r1.at "W" . to_vector . should_equal [2, 3]
|
||||||
r1.at "l" . to_vector . should_equal [0, 0]
|
r1.at "l" . to_vector . should_equal [0, 0]
|
||||||
r1.at "u" . to_vector . should_equal [10, 10]
|
r1.at "u" . to_vector . should_equal [10, 10]
|
||||||
r1.at "Right_Z" . to_vector . should_equal ["A", "A"]
|
r1.at "Right Z" . to_vector . should_equal ["A", "A"]
|
||||||
r1.at "W'" . to_vector . should_equal [10, 10]
|
r1.at "W'" . to_vector . should_equal [10, 10]
|
||||||
|
|
||||||
Test.specify "should work fine if the same condition is specified multiple times" <|
|
Test.specify "should work fine if the same condition is specified multiple times" <|
|
||||||
r = t3.join t4 on=["X", "X", "Y", "X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right_Z"]
|
r = t3.join t4 join_kind=Join_Kind.Inner on=["X", "X", "Y", "X", "Y"] |> materialize |> _.order_by ["X", "Y", "Z", "Right Z"]
|
||||||
check_xy_joined r
|
check_xy_joined r
|
||||||
|
|
||||||
t5 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
|
t5 = table_builder [["X", [1, 10, 12]], ["Y", [1, 2, 3]]]
|
||||||
t6 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
|
t6 = table_builder [["lower", [1, 10, 8, 12]], ["upper", [1, 12, 30, 0]], ["Z", [1, 2, 3, 4]]]
|
||||||
|
|
||||||
r1 = t5.join t6 on=[Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper"] |> materialize |> _.order_by ["X", "Z"]
|
r1 = t5.join t6 join_kind=Join_Kind.Inner on=[Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper", Join_Condition.Between "X" "lower" "upper"] |> materialize |> _.order_by ["X", "Z"]
|
||||||
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
|
r1 . at "X" . to_vector . should_equal [1, 10, 10, 12, 12]
|
||||||
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
|
r1 . at "Y" . to_vector . should_equal [1, 2, 2, 3, 3]
|
||||||
r1 . at "Z" . to_vector . should_equal [1, 2, 3, 2, 3]
|
r1 . at "Z" . to_vector . should_equal [1, 2, 3, 2, 3]
|
||||||
@ -243,64 +244,71 @@ spec setup =
|
|||||||
t7 = table_builder [["X", ["a", "B"]], ["Y", [1, 2]]]
|
t7 = table_builder [["X", ["a", "B"]], ["Y", [1, 2]]]
|
||||||
t8 = table_builder [["X", ["A", "a", "b"]], ["Z", [1, 2, 3]]]
|
t8 = table_builder [["X", ["A", "a", "b"]], ["Z", [1, 2, 3]]]
|
||||||
|
|
||||||
r2 = t7.join t8 on=[Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X" "X"] |> materialize |> _.order_by ["Z"]
|
r2 = t7.join t8 join_kind=Join_Kind.Inner on=[Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X", Join_Condition.Equals_Ignore_Case "X" "X"] |> materialize |> _.order_by ["Z"]
|
||||||
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
|
r2 . at "X" . to_vector . should_equal ["a", "a", "B"]
|
||||||
r2 . at "Right_X" . to_vector . should_equal ["A", "a", "b"]
|
r2 . at "Right X" . to_vector . should_equal ["A", "a", "b"]
|
||||||
r2 . at "Z" . to_vector . should_equal [1, 2, 3]
|
r2 . at "Z" . to_vector . should_equal [1, 2, 3]
|
||||||
|
|
||||||
Test.specify "should correctly handle joining a table with itself" <|
|
Test.specify "should correctly handle joining a table with itself" <|
|
||||||
t1 = table_builder [["X", [0, 1, 2, 3, 2]], ["Y", [1, 2, 3, 4, 100]], ["A", ["B", "C", "D", "E", "X"]]]
|
t1 = table_builder [["X", [0, 1, 2, 3, 2]], ["Y", [1, 2, 3, 4, 100]], ["A", ["B", "C", "D", "E", "X"]]]
|
||||||
t2 = t1.join t1 on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y"]
|
t2 = t1.join t1 join_kind=Join_Kind.Inner on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y"]
|
||||||
|
|
||||||
expect_column_names ["X", "Y", "A", "Right_X", "Right_Y", "Right_A"] t2
|
expect_column_names ["X", "Y", "A", "Right X", "Right Y", "Right A"] t2
|
||||||
t2.at "X" . to_vector . should_equal [1, 2, 2, 3]
|
t2.at "X" . to_vector . should_equal [1, 2, 2, 3]
|
||||||
t2.at "Right_Y" . to_vector . should_equal [1, 2, 2, 3]
|
t2.at "Right Y" . to_vector . should_equal [1, 2, 2, 3]
|
||||||
|
|
||||||
t2.at "Y" . to_vector . should_equal [2, 3, 100, 4]
|
t2.at "Y" . to_vector . should_equal [2, 3, 100, 4]
|
||||||
t2.at "A" . to_vector . should_equal ["C", "D", "X", "E"]
|
t2.at "A" . to_vector . should_equal ["C", "D", "X", "E"]
|
||||||
t2.at "Right_X" . to_vector . should_equal [0, 1, 1, 2]
|
t2.at "Right X" . to_vector . should_equal [0, 1, 1, 2]
|
||||||
t2.at "Right_A" . to_vector . should_equal ["B", "C", "C", "D"]
|
t2.at "Right A" . to_vector . should_equal ["B", "C", "C", "D"]
|
||||||
|
|
||||||
t3 = t1.join t1 join_kind=Join_Kind.Full on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y", "Right_X"]
|
t3 = t1.join t1 join_kind=Join_Kind.Full on=(Join_Condition.Equals left="X" right="Y") |> materialize |> _.order_by ["X", "Y", "Right X"]
|
||||||
expect_column_names ["X", "Y", "A", "Right_X", "Right_Y", "Right_A"] t3
|
expect_column_names ["X", "Y", "A", "Right X", "Right Y", "Right A"] t3
|
||||||
t3.at "X" . to_vector . should_equal [Nothing, Nothing, 0, 1, 2, 2, 3]
|
t3.at "X" . to_vector . should_equal [Nothing, Nothing, 0, 1, 2, 2, 3]
|
||||||
t3.at "Right_Y" . to_vector . should_equal [100, 4, Nothing, 1, 2, 2, 3]
|
t3.at "Right Y" . to_vector . should_equal [100, 4, Nothing, 1, 2, 2, 3]
|
||||||
|
|
||||||
t3.at "Y" . to_vector . should_equal [Nothing, Nothing, 1, 2, 3, 100, 4]
|
t3.at "Y" . to_vector . should_equal [Nothing, Nothing, 1, 2, 3, 100, 4]
|
||||||
t3.at "A" . to_vector . should_equal [Nothing, Nothing, "B", "C", "D", "X", "E"]
|
t3.at "A" . to_vector . should_equal [Nothing, Nothing, "B", "C", "D", "X", "E"]
|
||||||
t3.at "Right_X" . to_vector . should_equal [2, 3, Nothing, 0, 1, 1, 2]
|
t3.at "Right X" . to_vector . should_equal [2, 3, Nothing, 0, 1, 1, 2]
|
||||||
t3.at "Right_A" . to_vector . should_equal ["X", "E", Nothing, "B", "C", "C", "D"]
|
t3.at "Right A" . to_vector . should_equal ["X", "E", Nothing, "B", "C", "C", "D"]
|
||||||
|
|
||||||
t4 = table_builder [["X", [Nothing, "a", "B"]], ["Y", ["ą", "b", Nothing]], ["Z", [1, 2, 3]]]
|
t4 = table_builder [["X", [Nothing, "a", "B"]], ["Y", ["ą", "b", Nothing]], ["Z", [1, 2, 3]]]
|
||||||
t5 = t4.join t4 on=(Join_Condition.Equals_Ignore_Case left="Y" right="X") |> materialize |> _.order_by ["Y"]
|
t5 = t4.join t4 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case left="Y" right="X") |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Z", "Right_X", "Right_Y", "Right_Z"] t5
|
expect_column_names ["X", "Y", "Z", "Right X", "Right Y", "Right Z"] t5
|
||||||
# TODO enable once we handle nothing properly
|
# TODO enable once we handle nothing properly
|
||||||
# t5.at "Y" . to_vector . should_equal [Nothing, "b"]
|
# t5.at "Y" . to_vector . should_equal [Nothing, "b"]
|
||||||
# t5.at "Right_X" . to_vector . should_equal [Nothing, "B"]
|
# t5.at "Right X" . to_vector . should_equal [Nothing, "B"]
|
||||||
|
|
||||||
# t5.at "X" . to_vector . should_equal ["B", "a"]
|
# t5.at "X" . to_vector . should_equal ["B", "a"]
|
||||||
# t5.at "Z" . to_vector . should_equal [3, 2]
|
# t5.at "Z" . to_vector . should_equal [3, 2]
|
||||||
# t5.at "Right_Y" . to_vector . should_equal ["ą", Nothing]
|
# t5.at "Right Y" . to_vector . should_equal ["ą", Nothing]
|
||||||
# t5.at "Right_Z" . to_vector . should_equal [1, 3]
|
# t5.at "Right Z" . to_vector . should_equal [1, 3]
|
||||||
|
|
||||||
Test.specify "should gracefully handle unmatched columns in Join_Conditions" <|
|
Test.specify "should gracefully handle unmatched columns in Join_Conditions" <|
|
||||||
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
||||||
t2 = table_builder [["Z", [2, 1]], ["W", [5, 6]]]
|
t2 = table_builder [["Z", [2, 1]], ["W", [5, 6]]]
|
||||||
|
|
||||||
|
# Report error if the default fails - the right table does not have a column with same name as first column of left one:
|
||||||
|
r1 = t1.join t2
|
||||||
|
r1.should_fail_with Missing_Input_Columns
|
||||||
|
r1.catch.criteria.should_equal ["X"]
|
||||||
|
r1.catch.to_display_text.should_equal "The criteria [X] did not match any columns in the right table."
|
||||||
|
|
||||||
conditions = [Join_Condition.Equals "foo" 42, Join_Condition.Equals "X" -3, Join_Condition.Equals -1 "baz"]
|
conditions = [Join_Condition.Equals "foo" 42, Join_Condition.Equals "X" -3, Join_Condition.Equals -1 "baz"]
|
||||||
|
|
||||||
r1 = t1.join t2 on=conditions on_problems=Problem_Behavior.Ignore
|
r2 = t1.join t2 on=conditions on_problems=Problem_Behavior.Ignore
|
||||||
## We have both
|
## We have both
|
||||||
- Column_Indexes_Out_Of_Range.Error [42, -3]
|
- Column_Indexes_Out_Of_Range.Error [42, -3]
|
||||||
- Missing_Input_Columns.Error ["foo", "baz"]
|
- Missing_Input_Columns.Error ["foo", "baz"]
|
||||||
here, but we can throw only one error. I think column names error
|
here, but we can throw only one error. I think column names error
|
||||||
will be more useful, so I'd prioritize it.
|
will be more useful, so I'd prioritize it.
|
||||||
r1.should_fail_with Missing_Input_Columns
|
r2.should_fail_with Missing_Input_Columns
|
||||||
r1.catch.criteria.should_equal ["foo", "baz"]
|
r2.catch.criteria.should_equal ["foo"]
|
||||||
|
r2.catch.to_display_text.should_equal "The criteria [foo] did not match any columns in the left table."
|
||||||
|
|
||||||
r2 = t1.join t2 on=[Join_Condition.Equals 42 0] on_problems=Problem_Behavior.Ignore
|
r3 = t1.join t2 on=[Join_Condition.Equals 42 0] on_problems=Problem_Behavior.Ignore
|
||||||
r2.should_fail_with Column_Indexes_Out_Of_Range
|
r3.should_fail_with Column_Indexes_Out_Of_Range
|
||||||
r2.catch.indexes.should_equal [42]
|
r3.catch.indexes.should_equal [42]
|
||||||
|
|
||||||
Test.specify "should report Invalid_Value_Type if non-text columns are provided to Equals_Ignore_Case" <|
|
Test.specify "should report Invalid_Value_Type if non-text columns are provided to Equals_Ignore_Case" <|
|
||||||
t1 = table_builder [["X", ["1", "2", "c"]], ["Y", [1, 2, 3]]]
|
t1 = table_builder [["X", ["1", "2", "c"]], ["Y", [1, 2, 3]]]
|
||||||
@ -317,7 +325,7 @@ spec setup =
|
|||||||
|
|
||||||
Test.specify "should report Invalid_Value_Type if incompatible types are correlated" <|
|
Test.specify "should report Invalid_Value_Type if incompatible types are correlated" <|
|
||||||
t1 = table_builder [["X", ["1", "2", "c"]]]
|
t1 = table_builder [["X", ["1", "2", "c"]]]
|
||||||
t2 = table_builder [["Y", [1, 2, 3]]]
|
t2 = table_builder [["X", [1, 2, 3]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on_problems=Problem_Behavior.Ignore
|
r1 = t1.join t2 on_problems=Problem_Behavior.Ignore
|
||||||
r1.should_fail_with Invalid_Value_Type
|
r1.should_fail_with Invalid_Value_Type
|
||||||
@ -334,7 +342,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1.5, 2.0, 2.00000000001]], ["Y", [10, 20, 30]]]
|
t1 = table_builder [["X", [1.5, 2.0, 2.00000000001]], ["Y", [10, 20, 30]]]
|
||||||
t2 = table_builder [["Z", [2.0, 1.5, 2.0]], ["W", [1, 2, 3]]]
|
t2 = table_builder [["Z", [2.0, 1.5, 2.0]], ["W", [1, 2, 3]]]
|
||||||
|
|
||||||
action1 = t1.join t2 on=(Join_Condition.Equals "X" "Z") on_problems=_
|
action1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Z") on_problems=_
|
||||||
tester1 table =
|
tester1 table =
|
||||||
expect_column_names ["X", "Y", "Z", "W"] table
|
expect_column_names ["X", "Y", "Z", "W"] table
|
||||||
t1 = table.order_by ["Y", "W"]
|
t1 = table.order_by ["Y", "W"]
|
||||||
@ -345,7 +353,7 @@ spec setup =
|
|||||||
problems1 = [Floating_Point_Equality.Error "X", Floating_Point_Equality.Error "Z"]
|
problems1 = [Floating_Point_Equality.Error "X", Floating_Point_Equality.Error "Z"]
|
||||||
Problems.test_problem_handling action1 problems1 tester1
|
Problems.test_problem_handling action1 problems1 tester1
|
||||||
|
|
||||||
action2 = t1.join t2 on=(Join_Condition.Equals "X" "W") on_problems=_
|
action2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "W") on_problems=_
|
||||||
tester2 table =
|
tester2 table =
|
||||||
expect_column_names ["X", "Y", "Z", "W"] table
|
expect_column_names ["X", "Y", "Z", "W"] table
|
||||||
t1 = table.order_by ["Y", "W"]
|
t1 = table.order_by ["Y", "W"]
|
||||||
@ -363,7 +371,7 @@ spec setup =
|
|||||||
if setup.supports_custom_objects then
|
if setup.supports_custom_objects then
|
||||||
t1 = table_builder [["X", [My_Type.Value 1 2, 2.0, 2]], ["Y", [10, 20, 30]]]
|
t1 = table_builder [["X", [My_Type.Value 1 2, 2.0, 2]], ["Y", [10, 20, 30]]]
|
||||||
t2 = table_builder [["Z", [2.0, 1.5, 2.0]], ["W", [1, 2, 3]]]
|
t2 = table_builder [["Z", [2.0, 1.5, 2.0]], ["W", [1, 2, 3]]]
|
||||||
action3 = t1.join t2 on=(Join_Condition.Equals "X" "Z") on_problems=_
|
action3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Z") on_problems=_
|
||||||
tester3 table =
|
tester3 table =
|
||||||
expect_column_names ["X", "Y", "Z", "W"] table
|
expect_column_names ["X", "Y", "Z", "W"] table
|
||||||
t1 = table.order_by ["Y", "W"]
|
t1 = table.order_by ["Y", "W"]
|
||||||
@ -378,7 +386,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą"]], ["Y", [0, 1, 2, 3, 4]]]
|
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą"]], ["Y", [0, 1, 2, 3, 4]]]
|
||||||
t2 = table_builder [["X", ["a", Nothing, Nothing]], ["Z", [10, 20, 30]]]
|
t2 = table_builder [["X", ["a", Nothing, Nothing]], ["Z", [10, 20, 30]]]
|
||||||
|
|
||||||
r1 = t1.join t2 |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Z"] r1
|
expect_column_names ["X", "Y", "Z"] r1
|
||||||
r1.at "X" . to_vector . should_equal [Nothing, Nothing, "a", Nothing, Nothing]
|
r1.at "X" . to_vector . should_equal [Nothing, Nothing, "a", Nothing, Nothing]
|
||||||
r1.at "Y" . to_vector . should_equal [1, 1, 2, 3, 3]
|
r1.at "Y" . to_vector . should_equal [1, 1, 2, 3, 3]
|
||||||
@ -388,10 +396,10 @@ spec setup =
|
|||||||
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą"]], ["Y", [0, 1, 2, 3, 4]]]
|
t1 = table_builder [["X", ["A", Nothing, "a", Nothing, "ą"]], ["Y", [0, 1, 2, 3, 4]]]
|
||||||
t2 = table_builder [["X", ["a", Nothing, Nothing]], ["Z", [10, 20, 30]]]
|
t2 = table_builder [["X", ["a", Nothing, Nothing]], ["Z", [10, 20, 30]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals_Ignore_Case "X") |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "Right_X", "Z"] r1
|
expect_column_names ["X", "Y", "Right X", "Z"] r1
|
||||||
r1.at "X" . to_vector . should_equal ["A", Nothing, Nothing, "a", Nothing, Nothing]
|
r1.at "X" . to_vector . should_equal ["A", Nothing, Nothing, "a", Nothing, Nothing]
|
||||||
r1.at "Right_X" . to_vector . should_equal ["a", Nothing, Nothing, "a", Nothing, Nothing]
|
r1.at "Right X" . to_vector . should_equal ["a", Nothing, Nothing, "a", Nothing, Nothing]
|
||||||
r1.at "Y" . to_vector . should_equal [0, 1, 1, 2, 3, 3]
|
r1.at "Y" . to_vector . should_equal [0, 1, 1, 2, 3, 3]
|
||||||
r1.at "Z" . to_vector . should_equal [10, 20, 30, 10, 20, 30]
|
r1.at "Z" . to_vector . should_equal [10, 20, 30, 10, 20, 30]
|
||||||
|
|
||||||
@ -399,7 +407,7 @@ spec setup =
|
|||||||
t1 = table_builder [["X", [1, Nothing, 2, Nothing]], ["Y", [0, 1, 2, 3]]]
|
t1 = table_builder [["X", [1, Nothing, 2, Nothing]], ["Y", [0, 1, 2, 3]]]
|
||||||
t2 = table_builder [["l", [Nothing, 0, 1]], ["u", [100, 10, Nothing]], ["Z", [10, 20, 30]]]
|
t2 = table_builder [["l", [Nothing, 0, 1]], ["u", [100, 10, Nothing]], ["Z", [10, 20, 30]]]
|
||||||
|
|
||||||
r1 = t1.join t2 on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.order_by ["Y"]
|
r1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Between "X" "l" "u") |> materialize |> _.order_by ["Y"]
|
||||||
expect_column_names ["X", "Y", "l", "u", "Z"] r1
|
expect_column_names ["X", "Y", "l", "u", "Z"] r1
|
||||||
r1.at "X" . to_vector . should_equal [1, 2]
|
r1.at "X" . to_vector . should_equal [1, 2]
|
||||||
r1.at "Y" . to_vector . should_equal [0, 2]
|
r1.at "Y" . to_vector . should_equal [0, 2]
|
||||||
@ -408,51 +416,55 @@ spec setup =
|
|||||||
r1.at "Z" . to_vector . should_equal [20, 20]
|
r1.at "Z" . to_vector . should_equal [20, 20]
|
||||||
|
|
||||||
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
||||||
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]], ["Right_Y", [5, 6]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]], ["Right Y", [5, 6]]]
|
||||||
t2 = table_builder [["X", [2, 1]], ["Y", [2, 2]]]
|
t2 = table_builder [["X", [2, 1]], ["Y", [2, 2]]]
|
||||||
|
|
||||||
t3 = t1.join t2 on=(Join_Condition.Equals "X" "Y") |> materialize |> _.order_by ["Right_X"]
|
t3 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Y") |> materialize |> _.order_by ["Right X"]
|
||||||
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right_Y"]]
|
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right Y"]]
|
||||||
expect_column_names ["X", "Y", "Right_Y", "Right_X", "Right_Y_1"] t3
|
t3.column_names.should_equal ["X", "Y", "Right Y", "Right X", "Right Y 1"]
|
||||||
t3.at "X" . to_vector . should_equal [2, 2]
|
t3.at "X" . to_vector . should_equal [2, 2]
|
||||||
t3.at "Y" . to_vector . should_equal [4, 4]
|
t3.at "Y" . to_vector . should_equal [4, 4]
|
||||||
t3.at "Right_Y" . to_vector . should_equal [6, 6]
|
t3.at "Right Y" . to_vector . should_equal [6, 6]
|
||||||
t3.at "Right_X" . to_vector . should_equal [1, 2]
|
t3.at "Right X" . to_vector . should_equal [1, 2]
|
||||||
t3.at "Right_Y_1" . to_vector . should_equal [2, 2]
|
t3.at "Right Y 1" . to_vector . should_equal [2, 2]
|
||||||
|
|
||||||
err1 = t1.join t2 on=(Join_Condition.Equals "X" "Y") on_problems=Problem_Behavior.Report_Error
|
err1 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "Y") on_problems=Problem_Behavior.Report_Error
|
||||||
err1.should_fail_with Duplicate_Output_Column_Names
|
err1.should_fail_with Duplicate_Output_Column_Names
|
||||||
err1.catch.column_names . should_equal ["Right_Y"]
|
err1.catch.column_names . should_equal ["Right Y"]
|
||||||
|
|
||||||
t4 = table_builder [["Right_X", [1, 1]], ["X", [1, 2]], ["Y", [3, 4]], ["Right_Y_2", [2, 2]]]
|
t4 = table_builder [["Right X", [1, 1]], ["X", [1, 2]], ["Y", [3, 4]], ["Right Y 2", [2, 2]]]
|
||||||
t5 = table_builder [["Right_X", [2, 1]], ["X", [2, 2]], ["Y", [2, 2]], ["Right_Y", [2, 2]], ["Right_Y_1", [2, 2]], ["Right_Y_4", [2, 2]]]
|
t5 = table_builder [["Right X", [2, 1]], ["X", [2, 2]], ["Y", [2, 2]], ["Right Y", [2, 2]], ["Right Y 1", [2, 2]], ["Right Y 4", [2, 2]]]
|
||||||
|
|
||||||
t6 = t4.join t5 on=(Join_Condition.Equals "X" "Y")
|
t6 = t4.join t5 on=(Join_Condition.Equals "X" "Y")
|
||||||
expect_column_names ["Right_X", "X", "Y", "Right_Y_2"]+["Right_Right_X", "Right_X_1", "Right_Y_3", "Right_Y", "Right_Y_1", "Right_Y_4"] t6
|
t6.column_names.should_equal ["Right X", "X", "Y", "Right Y 2"]+["Right Right X", "Right X 1", "Right Y 3", "Right Y", "Right Y 1", "Right Y 4"]
|
||||||
|
|
||||||
action = t1.join t2 right_prefix="" on_problems=_
|
action = t1.join t2 right_prefix="" on_problems=_
|
||||||
tester = expect_column_names ["X", "Y", "Right_Y", "Y_1"]
|
tester = expect_column_names ["X", "Y", "Right Y", "X 1", "Y 1"]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["Y"]]
|
problems = [Duplicate_Output_Column_Names.Error ["X", "Y"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
t8 = t1.join t2 right_prefix="P"
|
action_2 = t1.join t2 join_kind=Join_Kind.Inner right_prefix="" on_problems=_
|
||||||
expect_column_names ["X", "Y", "Right_Y", "PY"] t8
|
tester_2 = expect_column_names ["X", "Y", "Right Y", "Y 1"]
|
||||||
|
problems_2 = [Duplicate_Output_Column_Names.Error ["Y"]]
|
||||||
|
Problems.test_problem_handling action_2 problems_2 tester_2
|
||||||
|
|
||||||
|
t8 = t1.join t2 join_kind=Join_Kind.Inner right_prefix="P"
|
||||||
|
t8.column_names.should_equal ["X", "Y", "Right Y", "PY"]
|
||||||
|
|
||||||
Test.specify "should warn about renamed columns" <|
|
Test.specify "should warn about renamed columns" <|
|
||||||
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [3, 4]]]
|
||||||
t2 = table_builder [["X", [2, 1]], ["Y", [2, 2]], ["Right_Y", [2, 44]]]
|
t2 = table_builder [["X", [2, 1]], ["Y", [2, 2]], ["Right Y", [2, 44]]]
|
||||||
|
|
||||||
action1 = t1.join t2 on=(Join_Condition.Equals "X" "Y") on_problems=_
|
action1 = t1.join t2 on=(Join_Condition.Equals "X" "Y") on_problems=_
|
||||||
tester1 table =
|
tester1 table =
|
||||||
expect_column_names ["X", "Y", "Right_X", "Right_Y_1", "Right_Y"] table
|
expect_column_names ["X", "Y", "Right X", "Right Y 1", "Right Y"] table
|
||||||
problems1 = [Duplicate_Output_Column_Names.Error ["Right_Y"]]
|
problems1 = [Duplicate_Output_Column_Names.Error ["Right Y"]]
|
||||||
Problems.test_problem_handling action1 problems1 tester1
|
Problems.test_problem_handling action1 problems1 tester1
|
||||||
|
|
||||||
|
action2 = t1.join t2 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "X" "X") on_problems=_
|
||||||
action2 = t1.join t2 on=(Join_Condition.Equals "X" "X") on_problems=_
|
|
||||||
tester2 table =
|
tester2 table =
|
||||||
expect_column_names ["X", "Y", "Right_Y_1", "Right_Y"] table
|
expect_column_names ["X", "Y", "Right Y 1", "Right Y"] table
|
||||||
problems2 = [Duplicate_Output_Column_Names.Error ["Right_Y"]]
|
problems2 = [Duplicate_Output_Column_Names.Error ["Right Y"]]
|
||||||
Problems.test_problem_handling action2 problems2 tester2
|
Problems.test_problem_handling action2 problems2 tester2
|
||||||
|
|
||||||
Test.specify "should pass dataflow errors through" <|
|
Test.specify "should pass dataflow errors through" <|
|
||||||
@ -527,13 +539,13 @@ spec setup =
|
|||||||
t7 = table_builder [["A", [Nothing, 2]], ["B", [Nothing, 3]]]
|
t7 = table_builder [["A", [Nothing, 2]], ["B", [Nothing, 3]]]
|
||||||
t8 = table_builder [["C", [2, 3]], ["D", [4, 5]]]
|
t8 = table_builder [["C", [2, 3]], ["D", [4, 5]]]
|
||||||
|
|
||||||
t9 = t7.join t8 join_kind=Join_Kind.Inner
|
t9 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Inner
|
||||||
r9 = materialize t9 . order_by ["A", "B", "D"] . rows . map .to_vector
|
r9 = materialize t9 . order_by ["A", "B", "D"] . rows . map .to_vector
|
||||||
within_table t9 <|
|
within_table t9 <|
|
||||||
r9.length . should_equal 1
|
r9.length . should_equal 1
|
||||||
r9.at 0 . should_equal [2, 3, 2, 4]
|
r9.at 0 . should_equal [2, 3, 2, 4]
|
||||||
|
|
||||||
t10 = t7.join t8 join_kind=Join_Kind.Full
|
t10 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Full
|
||||||
r10 = materialize t10 . order_by ["A", "C"] . rows . map .to_vector
|
r10 = materialize t10 . order_by ["A", "C"] . rows . map .to_vector
|
||||||
within_table t10 <|
|
within_table t10 <|
|
||||||
r10.length . should_equal 3
|
r10.length . should_equal 3
|
||||||
@ -541,27 +553,27 @@ spec setup =
|
|||||||
r10.at 1 . should_equal [Nothing, Nothing, 3, 5]
|
r10.at 1 . should_equal [Nothing, Nothing, 3, 5]
|
||||||
r10.at 2 . should_equal [2, 3, 2, 4]
|
r10.at 2 . should_equal [2, 3, 2, 4]
|
||||||
|
|
||||||
t10_2 = t7.join t8 join_kind=Join_Kind.Left_Outer
|
t10_2 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Left_Outer
|
||||||
r10_2 = materialize t10_2 . order_by ["A", "C"] . rows . map .to_vector
|
r10_2 = materialize t10_2 . order_by ["A", "C"] . rows . map .to_vector
|
||||||
within_table t10_2 <|
|
within_table t10_2 <|
|
||||||
r10_2.length . should_equal 2
|
r10_2.length . should_equal 2
|
||||||
r10_2.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
|
r10_2.at 0 . should_equal [Nothing, Nothing, Nothing, Nothing]
|
||||||
r10_2.at 1 . should_equal [2, 3, 2, 4]
|
r10_2.at 1 . should_equal [2, 3, 2, 4]
|
||||||
|
|
||||||
t10_3 = t7.join t8 join_kind=Join_Kind.Right_Outer
|
t10_3 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Right_Outer
|
||||||
r10_3 = materialize t10_3 . order_by ["A", "C"] . rows . map .to_vector
|
r10_3 = materialize t10_3 . order_by ["A", "C"] . rows . map .to_vector
|
||||||
within_table t10_3 <|
|
within_table t10_3 <|
|
||||||
r10_3.length . should_equal 2
|
r10_3.length . should_equal 2
|
||||||
r10_3.at 0 . should_equal [Nothing, Nothing, 3, 5]
|
r10_3.at 0 . should_equal [Nothing, Nothing, 3, 5]
|
||||||
r10_3.at 1 . should_equal [2, 3, 2, 4]
|
r10_3.at 1 . should_equal [2, 3, 2, 4]
|
||||||
|
|
||||||
t11 = t7.join t8 join_kind=Join_Kind.Left_Exclusive
|
t11 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Left_Exclusive
|
||||||
r11 = materialize t11 . rows . map .to_vector
|
r11 = materialize t11 . rows . map .to_vector
|
||||||
within_table t11 <|
|
within_table t11 <|
|
||||||
r11.length . should_equal 1
|
r11.length . should_equal 1
|
||||||
r11.at 0 . should_equal [Nothing, Nothing]
|
r11.at 0 . should_equal [Nothing, Nothing]
|
||||||
|
|
||||||
t12 = t7.join t8 join_kind=Join_Kind.Right_Exclusive
|
t12 = t7.join t8 on=[Join_Condition.Equals "A" "C"] join_kind=Join_Kind.Right_Exclusive
|
||||||
r12 = materialize t12 . rows . map .to_vector
|
r12 = materialize t12 . rows . map .to_vector
|
||||||
within_table t12 <|
|
within_table t12 <|
|
||||||
r12.length . should_equal 1
|
r12.length . should_equal 1
|
||||||
@ -585,18 +597,18 @@ spec setup =
|
|||||||
t1_2 = t1.set "10*[X]+1" new_name="A"
|
t1_2 = t1.set "10*[X]+1" new_name="A"
|
||||||
t1_3 = t1.set "[X]+20" new_name="B"
|
t1_3 = t1.set "[X]+20" new_name="B"
|
||||||
|
|
||||||
t2 = t1_2.join t1_3 on=(Join_Condition.Equals "A" "B")
|
t2 = t1_2.join t1_3 join_kind=Join_Kind.Inner on=(Join_Condition.Equals "A" "B")
|
||||||
t2.at "A" . to_vector . should_equal [21]
|
t2.at "A" . to_vector . should_equal [21]
|
||||||
t2.at "X" . to_vector . should_equal [2]
|
t2.at "X" . to_vector . should_equal [2]
|
||||||
t2.at "B" . to_vector . should_equal [21]
|
t2.at "B" . to_vector . should_equal [21]
|
||||||
t2.at "Right_X" . to_vector . should_equal [1]
|
t2.at "Right X" . to_vector . should_equal [1]
|
||||||
|
|
||||||
t4 = table_builder [["X", [1, 2, 3]], ["Y", [10, 20, 30]]]
|
t4 = table_builder [["X", [1, 2, 3]], ["Y", [10, 20, 30]]]
|
||||||
t5 = table_builder [["X", [5, 7, 1]], ["Z", [100, 200, 300]]]
|
t5 = table_builder [["X", [5, 7, 1]], ["Z", [100, 200, 300]]]
|
||||||
|
|
||||||
t4_2 = t4.set "2*[X]+1" new_name="C"
|
t4_2 = t4.set "2*[X]+1" new_name="C"
|
||||||
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Inner
|
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Inner
|
||||||
expect_column_names ["X", "Y", "C", "Right_X", "Z"] t6
|
expect_column_names ["X", "Y", "C", "Right X", "Z"] t6
|
||||||
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
|
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
|
||||||
r2.length . should_equal 2
|
r2.length . should_equal 2
|
||||||
r2.at 0 . should_equal [2, 20, 5, 5, 100]
|
r2.at 0 . should_equal [2, 20, 5, 5, 100]
|
||||||
@ -607,7 +619,7 @@ spec setup =
|
|||||||
t2 = table_builder [["X", ["Ć", "A", "b"]], ["Z", [100, 200, 300]]]
|
t2 = table_builder [["X", ["Ć", "A", "b"]], ["Z", [100, 200, 300]]]
|
||||||
|
|
||||||
t3 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") join_kind=Join_Kind.Full
|
t3 = t1.join t2 on=(Join_Condition.Equals_Ignore_Case "X") join_kind=Join_Kind.Full
|
||||||
expect_column_names ["X", "Y", "Right_X", "Z"] t3
|
expect_column_names ["X", "Y", "Right X", "Z"] t3
|
||||||
r = materialize t3 . order_by ["Y"] . rows . map .to_vector
|
r = materialize t3 . order_by ["Y"] . rows . map .to_vector
|
||||||
r.length . should_equal 4
|
r.length . should_equal 4
|
||||||
r.at 0 . should_equal [Nothing, Nothing, "Ć", 100]
|
r.at 0 . should_equal [Nothing, Nothing, "Ć", 100]
|
||||||
@ -620,7 +632,7 @@ spec setup =
|
|||||||
|
|
||||||
t4_2 = t4.set "2*[X]+1" new_name="C"
|
t4_2 = t4.set "2*[X]+1" new_name="C"
|
||||||
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
|
t6 = t4_2.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
|
||||||
expect_column_names ["X", "Y", "C", "Right_X", "Z"] t6
|
expect_column_names ["X", "Y", "C", "Right X", "Z"] t6
|
||||||
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
|
r2 = materialize t6 . order_by ["Y"] . rows . map .to_vector
|
||||||
r2.length . should_equal 4
|
r2.length . should_equal 4
|
||||||
r2.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
|
r2.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
|
||||||
@ -632,8 +644,8 @@ spec setup =
|
|||||||
t4_4 = t4_3.set (t4_3.at "X" . fill_nothing 7) new_name="C"
|
t4_4 = t4_3.set (t4_3.at "X" . fill_nothing 7) new_name="C"
|
||||||
t7 = t4_4.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
|
t7 = t4_4.join t5 on=(Join_Condition.Equals "C" "X") join_kind=Join_Kind.Full
|
||||||
within_table t7 <|
|
within_table t7 <|
|
||||||
expect_column_names ["X", "Y", "C", "Right_X", "Z"] t7
|
expect_column_names ["X", "Y", "C", "Right X", "Z"] t7
|
||||||
r3 = materialize t7 . order_by ["Y", "Right_X"] . rows . map .to_vector
|
r3 = materialize t7 . order_by ["Y", "Right X"] . rows . map .to_vector
|
||||||
r3.length . should_equal 5
|
r3.length . should_equal 5
|
||||||
r3.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
|
r3.at 0 . should_equal [Nothing, Nothing, Nothing, 1, 300]
|
||||||
r3.at 1 . should_equal [Nothing, Nothing, Nothing, 5, 100]
|
r3.at 1 . should_equal [Nothing, Nothing, Nothing, 5, 100]
|
||||||
|
@ -148,33 +148,33 @@ spec setup =
|
|||||||
t3.at "W" . to_vector . should_equal ['b', Nothing, Nothing]
|
t3.at "W" . to_vector . should_equal ['b', Nothing, Nothing]
|
||||||
|
|
||||||
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
Test.specify "should rename columns of the right table to avoid duplicates" <|
|
||||||
t1 = table_builder [["X", [1, 2]], ["Y", [5, 6]], ["Right_Y", [7, 8]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [5, 6]], ["Right Y", [7, 8]]]
|
||||||
t2 = table_builder [["X", ['a']], ["Y", ['d']]]
|
t2 = table_builder [["X", ['a']], ["Y", ['d']]]
|
||||||
|
|
||||||
t3 = t1.zip t2 keep_unmatched=True
|
t3 = t1.zip t2 keep_unmatched=True
|
||||||
expect_column_names ["X", "Y", "Right_Y", "Right_X", "Right_Y_1"] t3
|
expect_column_names ["X", "Y", "Right Y", "Right X", "Right Y 1"] t3
|
||||||
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right_Y"]]
|
Problems.get_attached_warnings t3 . should_equal [Duplicate_Output_Column_Names.Error ["Right Y"]]
|
||||||
t3.row_count . should_equal 2
|
t3.row_count . should_equal 2
|
||||||
t3.at "X" . to_vector . should_equal [1, 2]
|
t3.at "X" . to_vector . should_equal [1, 2]
|
||||||
t3.at "Y" . to_vector . should_equal [5, 6]
|
t3.at "Y" . to_vector . should_equal [5, 6]
|
||||||
t3.at "Right_Y" . to_vector . should_equal [7, 8]
|
t3.at "Right Y" . to_vector . should_equal [7, 8]
|
||||||
t3.at "Right_X" . to_vector . should_equal ['a', Nothing]
|
t3.at "Right X" . to_vector . should_equal ['a', Nothing]
|
||||||
t3.at "Right_Y_1" . to_vector . should_equal ['d', Nothing]
|
t3.at "Right Y 1" . to_vector . should_equal ['d', Nothing]
|
||||||
|
|
||||||
t1.zip t2 keep_unmatched=False on_problems=Problem_Behavior.Report_Error . should_fail_with Duplicate_Output_Column_Names
|
t1.zip t2 keep_unmatched=False on_problems=Problem_Behavior.Report_Error . should_fail_with Duplicate_Output_Column_Names
|
||||||
|
|
||||||
expect_column_names ["X", "Y", "Right_Y", "X_1", "Y_1"] (t1.zip t2 right_prefix="")
|
expect_column_names ["X", "Y", "Right Y", "X 1", "Y 1"] (t1.zip t2 right_prefix="")
|
||||||
|
|
||||||
t4 = table_builder [["X", [1]], ["Right_X", [5]]]
|
t4 = table_builder [["X", [1]], ["Right X", [5]]]
|
||||||
expect_column_names ["X", "Y", "Right_Y", "Right_X_1", "Right_X"] (t1.zip t4)
|
expect_column_names ["X", "Y", "Right Y", "Right X 1", "Right X"] (t1.zip t4)
|
||||||
expect_column_names ["X", "Right_X", "Right_X_1", "Y", "Right_Y"] (t4.zip t1)
|
expect_column_names ["X", "Right X", "Right X 1", "Y", "Right Y"] (t4.zip t1)
|
||||||
|
|
||||||
Test.specify "should report both row count mismatch and duplicate column warnings at the same time" <|
|
Test.specify "should report both row count mismatch and duplicate column warnings at the same time" <|
|
||||||
t1 = table_builder [["X", [1, 2]], ["Right_X", [5, 6]]]
|
t1 = table_builder [["X", [1, 2]], ["Right X", [5, 6]]]
|
||||||
t2 = table_builder [["X", ['a']], ["Z", ['d']]]
|
t2 = table_builder [["X", ['a']], ["Z", ['d']]]
|
||||||
|
|
||||||
t3 = t1.zip t2
|
t3 = t1.zip t2
|
||||||
expected_problems = [Row_Count_Mismatch.Error 2 1, Duplicate_Output_Column_Names.Error ["Right_X"]]
|
expected_problems = [Row_Count_Mismatch.Error 2 1, Duplicate_Output_Column_Names.Error ["Right X"]]
|
||||||
Problems.get_attached_warnings t3 . should_contain_the_same_elements_as expected_problems
|
Problems.get_attached_warnings t3 . should_contain_the_same_elements_as expected_problems
|
||||||
|
|
||||||
Test.specify "should allow to zip the table with itself" <|
|
Test.specify "should allow to zip the table with itself" <|
|
||||||
@ -183,12 +183,12 @@ spec setup =
|
|||||||
the Database backend.
|
the Database backend.
|
||||||
t1 = table_builder [["X", [1, 2]], ["Y", [4, 5]]]
|
t1 = table_builder [["X", [1, 2]], ["Y", [4, 5]]]
|
||||||
t2 = t1.zip t1
|
t2 = t1.zip t1
|
||||||
expect_column_names ["X", "Y", "Right_X", "Right_Y"] t2
|
expect_column_names ["X", "Y", "Right X", "Right Y"] t2
|
||||||
t2.row_count . should_equal 2
|
t2.row_count . should_equal 2
|
||||||
t2.at "X" . to_vector . should_equal [1, 2]
|
t2.at "X" . to_vector . should_equal [1, 2]
|
||||||
t2.at "Y" . to_vector . should_equal [4, 5]
|
t2.at "Y" . to_vector . should_equal [4, 5]
|
||||||
t2.at "Right_X" . to_vector . should_equal [1, 2]
|
t2.at "Right X" . to_vector . should_equal [1, 2]
|
||||||
t2.at "Right_Y" . to_vector . should_equal [4, 5]
|
t2.at "Right Y" . to_vector . should_equal [4, 5]
|
||||||
|
|
||||||
if setup.is_database.not then
|
if setup.is_database.not then
|
||||||
Test.specify "should correctly pad/truncate all kinds of column types" <|
|
Test.specify "should correctly pad/truncate all kinds of column types" <|
|
||||||
|
@ -19,8 +19,8 @@ spec setup =
|
|||||||
col1 = ["foo", [1,2,3]]
|
col1 = ["foo", [1,2,3]]
|
||||||
col2 = ["bar", [4,5,6]]
|
col2 = ["bar", [4,5,6]]
|
||||||
col3 = ["Baz", [7,8,9]]
|
col3 = ["Baz", [7,8,9]]
|
||||||
col4 = ["foo_1", [10,11,12]]
|
col4 = ["foo 1", [10,11,12]]
|
||||||
col5 = ["foo_2", [13,14,15]]
|
col5 = ["foo 2", [13,14,15]]
|
||||||
col6 = ["ab.+123", [16,17,18]]
|
col6 = ["ab.+123", [16,17,18]]
|
||||||
col7 = ["abcd123", [19,20,21]]
|
col7 = ["abcd123", [19,20,21]]
|
||||||
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
||||||
@ -28,7 +28,7 @@ spec setup =
|
|||||||
Test.group prefix+"Table.select_columns" <|
|
Test.group prefix+"Table.select_columns" <|
|
||||||
Test.specify "should work as shown in the doc examples" <|
|
Test.specify "should work as shown in the doc examples" <|
|
||||||
expect_column_names ["foo", "bar"] <| table.select_columns ["bar", "foo"]
|
expect_column_names ["foo", "bar"] <| table.select_columns ["bar", "foo"]
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2"] <| table.select_columns [By_Name "foo.+" use_regex=True, By_Name "b.*" use_regex=True]
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2"] <| table.select_columns [By_Name "foo.+" use_regex=True, By_Name "b.*" use_regex=True]
|
||||||
expect_column_names ["abcd123", "foo", "bar"] <| table.select_columns [-1, 0, 1] reorder=True
|
expect_column_names ["abcd123", "foo", "bar"] <| table.select_columns [-1, 0, 1] reorder=True
|
||||||
|
|
||||||
Test.specify "should allow to reorder columns if asked to" <|
|
Test.specify "should allow to reorder columns if asked to" <|
|
||||||
@ -45,13 +45,13 @@ spec setup =
|
|||||||
expect_column_names ["abcd123"] <| table.select_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["abcd123"] <| table.select_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
|
|
||||||
Test.specify "should allow negative indices" <|
|
Test.specify "should allow negative indices" <|
|
||||||
expect_column_names ["foo", "bar", "foo_2"] <| table.select_columns [-3, 0, 1]
|
expect_column_names ["foo", "bar", "foo 2"] <| table.select_columns [-3, 0, 1]
|
||||||
|
|
||||||
Test.specify "should allow mixed names and indexes" <|
|
Test.specify "should allow mixed names and indexes" <|
|
||||||
expect_column_names ["foo", "bar", "foo_2"] <| table.select_columns [-3, "bar", 0]
|
expect_column_names ["foo", "bar", "foo 2"] <| table.select_columns [-3, "bar", 0]
|
||||||
expect_column_names ["foo_2", "bar", "foo"] <| table.select_columns [-3, "bar", 0] reorder=True
|
expect_column_names ["foo 2", "bar", "foo"] <| table.select_columns [-3, "bar", 0] reorder=True
|
||||||
expect_column_names ["foo", "bar", "foo_1", "foo_2", "abcd123"] <| table.select_columns [-1, "bar", By_Name "foo.*" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["foo", "bar", "foo 1", "foo 2", "abcd123"] <| table.select_columns [-1, "bar", By_Name "foo.*" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names ["foo", "foo_1", "foo_2", "bar", "abcd123"] <| table.select_columns [By_Name "foo.*" Case_Sensitivity.Sensitive use_regex=True, "bar", "foo", -1] reorder=True
|
expect_column_names ["foo", "foo 1", "foo 2", "bar", "abcd123"] <| table.select_columns [By_Name "foo.*" Case_Sensitivity.Sensitive use_regex=True, "bar", "foo", -1] reorder=True
|
||||||
|
|
||||||
if test_selection.supports_case_sensitive_columns then
|
if test_selection.supports_case_sensitive_columns then
|
||||||
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
||||||
@ -63,8 +63,8 @@ spec setup =
|
|||||||
expect_column_names ["bar", "Bar"] <| table.select_columns [By_Name "bar"]
|
expect_column_names ["bar", "Bar"] <| table.select_columns [By_Name "bar"]
|
||||||
|
|
||||||
Test.specify "should correctly handle regexes matching multiple names" <|
|
Test.specify "should correctly handle regexes matching multiple names" <|
|
||||||
expect_column_names ["foo", "bar", "foo_1", "foo_2"] <| table.select_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["foo", "bar", "foo 1", "foo 2"] <| table.select_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names ["bar", "foo", "foo_1", "foo_2"] <| table.select_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True] reorder=True
|
expect_column_names ["bar", "foo", "foo 1", "foo 2"] <| table.select_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True] reorder=True
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: out of bounds indices" <|
|
Test.specify "should correctly handle problems: out of bounds indices" <|
|
||||||
selector = [1, 0, 100, -200, 300]
|
selector = [1, 0, 100, -200, 300]
|
||||||
@ -142,21 +142,21 @@ spec setup =
|
|||||||
|
|
||||||
Test.group prefix+"Table.remove_columns" <|
|
Test.group prefix+"Table.remove_columns" <|
|
||||||
Test.specify "should work as shown in the doc examples" <|
|
Test.specify "should work as shown in the doc examples" <|
|
||||||
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] <| table.remove_columns ["bar", "foo"]
|
expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] <| table.remove_columns ["bar", "foo"]
|
||||||
expect_column_names ["foo", "ab.+123", "abcd123"] <| table.remove_columns [By_Name "foo.+" Case_Sensitivity.Insensitive use_regex=True, By_Name "b.*" Case_Sensitivity.Insensitive use_regex=True]
|
expect_column_names ["foo", "ab.+123", "abcd123"] <| table.remove_columns [By_Name "foo.+" Case_Sensitivity.Insensitive use_regex=True, By_Name "b.*" Case_Sensitivity.Insensitive use_regex=True]
|
||||||
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123"] <| table.remove_columns [-1, 0, 1]
|
expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123"] <| table.remove_columns [-1, 0, 1]
|
||||||
|
|
||||||
Test.specify "should correctly handle regex matching" <|
|
Test.specify "should correctly handle regex matching" <|
|
||||||
last_ones = table.columns.drop 1 . map .name
|
last_ones = table.columns.drop 1 . map .name
|
||||||
expect_column_names last_ones <| table.remove_columns [By_Name "foo" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names last_ones <| table.remove_columns [By_Name "foo" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
first_ones = ["foo", "bar", "Baz", "foo_1", "foo_2"]
|
first_ones = ["foo", "bar", "Baz", "foo 1", "foo 2"]
|
||||||
expect_column_names first_ones <| table.remove_columns [By_Name "a.*" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names first_ones <| table.remove_columns [By_Name "a.*" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names first_ones <| table.remove_columns [By_Name "ab.+123" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names first_ones <| table.remove_columns [By_Name "ab.+123" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names first_ones+["abcd123"] <| table.remove_columns [By_Name "ab.+123"]
|
expect_column_names first_ones+["abcd123"] <| table.remove_columns [By_Name "ab.+123"]
|
||||||
expect_column_names first_ones+["ab.+123"] <| table.remove_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names first_ones+["ab.+123"] <| table.remove_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
|
|
||||||
Test.specify "should allow negative indices" <|
|
Test.specify "should allow negative indices" <|
|
||||||
expect_column_names ["Baz", "foo_1", "ab.+123"] <| table.remove_columns [-1, -3, 0, 1]
|
expect_column_names ["Baz", "foo 1", "ab.+123"] <| table.remove_columns [-1, -3, 0, 1]
|
||||||
|
|
||||||
if test_selection.supports_case_sensitive_columns then
|
if test_selection.supports_case_sensitive_columns then
|
||||||
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
||||||
@ -173,7 +173,7 @@ spec setup =
|
|||||||
Test.specify "should correctly handle problems: out of bounds indices" <|
|
Test.specify "should correctly handle problems: out of bounds indices" <|
|
||||||
selector = [1, 0, 100, -200, 300]
|
selector = [1, 0, 100, -200, 300]
|
||||||
action = table.remove_columns selector on_problems=_
|
action = table.remove_columns selector on_problems=_
|
||||||
tester = expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123"]
|
tester = expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123"]
|
||||||
problems = [Column_Indexes_Out_Of_Range.Error [100, -200, 300]]
|
problems = [Column_Indexes_Out_Of_Range.Error [100, -200, 300]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -183,28 +183,28 @@ spec setup =
|
|||||||
Test.specify "should correctly handle edge-cases: duplicate indices" <|
|
Test.specify "should correctly handle edge-cases: duplicate indices" <|
|
||||||
selector = [0, 0, 0]
|
selector = [0, 0, 0]
|
||||||
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] t
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle edge-cases: aliased indices" <|
|
Test.specify "should correctly handle edge-cases: aliased indices" <|
|
||||||
selector = [0, -7, -6, 1]
|
selector = [0, -7, -6, 1]
|
||||||
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] t
|
expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle edge-cases: duplicate names" <|
|
Test.specify "should correctly handle edge-cases: duplicate names" <|
|
||||||
selector = ["foo", "foo"]
|
selector = ["foo", "foo"]
|
||||||
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] t
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle edge-cases: duplicate matches due to case insensitivity" <|
|
Test.specify "should correctly handle edge-cases: duplicate matches due to case insensitivity" <|
|
||||||
selector = [By_Name "FOO", By_Name "foo"]
|
selector = [By_Name "FOO", By_Name "foo"]
|
||||||
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
t = table.remove_columns selector on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] t
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: unmatched names" <|
|
Test.specify "should correctly handle problems: unmatched names" <|
|
||||||
weird_name = '.*?-!@#!"'
|
weird_name = '.*?-!@#!"'
|
||||||
selector = ["foo", "hmm", weird_name]
|
selector = ["foo", "hmm", weird_name]
|
||||||
action = table.remove_columns selector on_problems=_
|
action = table.remove_columns selector on_problems=_
|
||||||
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"]
|
tester = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"]
|
||||||
problems = [Missing_Input_Columns.Error ["hmm", weird_name]]
|
problems = [Missing_Input_Columns.Error ["hmm", weird_name]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -223,22 +223,22 @@ spec setup =
|
|||||||
|
|
||||||
Test.group prefix+"Table.reorder_columns" <|
|
Test.group prefix+"Table.reorder_columns" <|
|
||||||
Test.specify "should work as shown in the doc examples" <|
|
Test.specify "should work as shown in the doc examples" <|
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns "foo" Position.After_Other_Columns
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns "foo" Position.After_Other_Columns
|
||||||
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"] <| table.reorder_columns ["foo", "bar"] Position.After_Other_Columns
|
expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo", "bar"] <| table.reorder_columns ["foo", "bar"] Position.After_Other_Columns
|
||||||
expect_column_names ["foo_1", "foo_2", "bar", "Baz", "foo", "ab.+123", "abcd123"] <| table.reorder_columns [By_Name "foo.+" Case_Sensitivity.Insensitive use_regex=True, By_Name "b.*" Case_Sensitivity.Insensitive use_regex=True]
|
expect_column_names ["foo 1", "foo 2", "bar", "Baz", "foo", "ab.+123", "abcd123"] <| table.reorder_columns [By_Name "foo.+" Case_Sensitivity.Insensitive use_regex=True, By_Name "b.*" Case_Sensitivity.Insensitive use_regex=True]
|
||||||
expect_column_names ["bar", "foo", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"] <| table.reorder_columns [1, 0] Position.Before_Other_Columns
|
expect_column_names ["bar", "foo", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] <| table.reorder_columns [1, 0] Position.Before_Other_Columns
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns [0] Position.After_Other_Columns
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns [0] Position.After_Other_Columns
|
||||||
|
|
||||||
Test.specify "should correctly handle regex matching" <|
|
Test.specify "should correctly handle regex matching" <|
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns [By_Name "foo" Case_Sensitivity.Sensitive use_regex=True] Position.After_Other_Columns
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] <| table.reorder_columns [By_Name "foo" Case_Sensitivity.Sensitive use_regex=True] Position.After_Other_Columns
|
||||||
rest = ["foo", "bar", "Baz", "foo_1", "foo_2"]
|
rest = ["foo", "bar", "Baz", "foo 1", "foo 2"]
|
||||||
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns [By_Name "a.*" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns [By_Name "a.*" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns [By_Name "ab.+123" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["ab.+123", "abcd123"]+rest <| table.reorder_columns [By_Name "ab.+123" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
expect_column_names ["ab.+123"]+rest+["abcd123"] <| table.reorder_columns ["ab.+123"]
|
expect_column_names ["ab.+123"]+rest+["abcd123"] <| table.reorder_columns ["ab.+123"]
|
||||||
expect_column_names ["abcd123"]+rest+["ab.+123"] <| table.reorder_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["abcd123"]+rest+["ab.+123"] <| table.reorder_columns [By_Name "abcd123" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
|
|
||||||
Test.specify "should allow negative indices" <|
|
Test.specify "should allow negative indices" <|
|
||||||
expect_column_names ["abcd123", "foo_2", "foo", "bar", "Baz", "foo_1", "ab.+123"] <| table.reorder_columns [-1, -3, 0, 1]
|
expect_column_names ["abcd123", "foo 2", "foo", "bar", "Baz", "foo 1", "ab.+123"] <| table.reorder_columns [-1, -3, 0, 1]
|
||||||
|
|
||||||
if test_selection.supports_case_sensitive_columns then
|
if test_selection.supports_case_sensitive_columns then
|
||||||
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
Test.specify "should correctly handle exact matches matching multiple names due to case insensitivity" <|
|
||||||
@ -250,12 +250,12 @@ spec setup =
|
|||||||
expect_column_names ["bar", "Bar", "foo"] <| table.reorder_columns [By_Name "bar"]
|
expect_column_names ["bar", "Bar", "foo"] <| table.reorder_columns [By_Name "bar"]
|
||||||
|
|
||||||
Test.specify "should correctly handle regexes matching multiple names" <|
|
Test.specify "should correctly handle regexes matching multiple names" <|
|
||||||
expect_column_names ["bar", "foo", "foo_1", "foo_2", "Baz", "ab.+123", "abcd123"] <| table.reorder_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True]
|
expect_column_names ["bar", "foo", "foo 1", "foo 2", "Baz", "ab.+123", "abcd123"] <| table.reorder_columns [By_Name "b.*" Case_Sensitivity.Sensitive use_regex=True, By_Name "f.+" Case_Sensitivity.Sensitive use_regex=True]
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: out of bounds indices" <|
|
Test.specify "should correctly handle problems: out of bounds indices" <|
|
||||||
selector = [1, 0, 100, -200, 300]
|
selector = [1, 0, 100, -200, 300]
|
||||||
action = table.reorder_columns selector on_problems=_
|
action = table.reorder_columns selector on_problems=_
|
||||||
tester = expect_column_names ["bar", "foo", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123"]
|
tester = expect_column_names ["bar", "foo", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"]
|
||||||
problems = [Column_Indexes_Out_Of_Range.Error [100, -200, 300]]
|
problems = [Column_Indexes_Out_Of_Range.Error [100, -200, 300]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -265,23 +265,23 @@ spec setup =
|
|||||||
Test.specify "should correctly handle edge-cases: duplicate indices" <|
|
Test.specify "should correctly handle edge-cases: duplicate indices" <|
|
||||||
selector = [0, 0, 0]
|
selector = [0, 0, 0]
|
||||||
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] t
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle edge-cases: aliased indices" <|
|
Test.specify "should correctly handle edge-cases: aliased indices" <|
|
||||||
selector = [0, -7, -6, 1]
|
selector = [0, -7, -6, 1]
|
||||||
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo", "bar"] t
|
expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo", "bar"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle edge-cases: duplicate names" <|
|
Test.specify "should correctly handle edge-cases: duplicate names" <|
|
||||||
selector = ["foo", "foo"]
|
selector = ["foo", "foo"]
|
||||||
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
t = table.reorder_columns selector Position.After_Other_Columns on_problems=Problem_Behavior.Report_Error
|
||||||
expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"] t
|
expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] t
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: unmatched names" <|
|
Test.specify "should correctly handle problems: unmatched names" <|
|
||||||
weird_name = '.*?-!@#!"'
|
weird_name = '.*?-!@#!"'
|
||||||
selector = ["foo", "hmm", weird_name]
|
selector = ["foo", "hmm", weird_name]
|
||||||
action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
|
action = table.reorder_columns selector Position.After_Other_Columns on_problems=_
|
||||||
tester = expect_column_names ["bar", "Baz", "foo_1", "foo_2", "ab.+123", "abcd123", "foo"]
|
tester = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"]
|
||||||
problems = [Missing_Input_Columns.Error ["hmm", weird_name]]
|
problems = [Missing_Input_Columns.Error ["hmm", weird_name]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -290,31 +290,31 @@ spec setup =
|
|||||||
|
|
||||||
Test.group prefix+"Table.sort_columns" <|
|
Test.group prefix+"Table.sort_columns" <|
|
||||||
table =
|
table =
|
||||||
col1 = ["foo_21", [1,2,3]]
|
col1 = ["foo 21", [1,2,3]]
|
||||||
col2 = ["foo_100", [4,5,6]]
|
col2 = ["foo 100", [4,5,6]]
|
||||||
col3 = ["foo_1", [7,8,9]]
|
col3 = ["foo 1", [7,8,9]]
|
||||||
col4 = ["Foo_2", [10,11,12]]
|
col4 = ["Foo 2", [10,11,12]]
|
||||||
col5 = ["foo_3", [13,14,15]]
|
col5 = ["foo 3", [13,14,15]]
|
||||||
col6 = ["foo_001", [16,17,18]]
|
col6 = ["foo 001", [16,17,18]]
|
||||||
col7 = ["bar", [19,20,21]]
|
col7 = ["bar", [19,20,21]]
|
||||||
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
table_builder [col1, col2, col3, col4, col5, col6, col7]
|
||||||
|
|
||||||
Test.specify "should work as shown in the doc examples" <|
|
Test.specify "should work as shown in the doc examples" <|
|
||||||
sorted = table.sort_columns
|
sorted = table.sort_columns
|
||||||
expect_column_names ["Foo_2", "bar", "foo_001", "foo_1", "foo_100", "foo_21", "foo_3"] sorted
|
expect_column_names ["Foo 2", "bar", "foo 001", "foo 1", "foo 100", "foo 21", "foo 3"] sorted
|
||||||
sorted.columns.first.to_vector . should_equal [10,11,12]
|
sorted.columns.first.to_vector . should_equal [10,11,12]
|
||||||
|
|
||||||
expect_column_names ["bar", "foo_001", "foo_1", "Foo_2", "foo_3", "foo_21", "foo_100"] <| table.sort_columns text_ordering=(Text_Ordering.Case_Insensitive sort_digits_as_numbers=True)
|
expect_column_names ["bar", "foo 001", "foo 1", "Foo 2", "foo 3", "foo 21", "foo 100"] <| table.sort_columns text_ordering=(Text_Ordering.Case_Insensitive sort_digits_as_numbers=True)
|
||||||
expect_column_names ["foo_3", "foo_21", "foo_100", "foo_1", "foo_001", "bar", "Foo_2"] <| table.sort_columns Sort_Direction.Descending
|
expect_column_names ["foo 3", "foo 21", "foo 100", "foo 1", "foo 001", "bar", "Foo 2"] <| table.sort_columns Sort_Direction.Descending
|
||||||
|
|
||||||
Test.specify "should correctly handle case-insensitive sorting" <|
|
Test.specify "should correctly handle case-insensitive sorting" <|
|
||||||
expect_column_names ["bar", "foo_001", "foo_1", "foo_100", "Foo_2", "foo_21", "foo_3"] <| table.sort_columns text_ordering=(Text_Ordering.Case_Insensitive)
|
expect_column_names ["bar", "foo 001", "foo 1", "foo 100", "Foo 2", "foo 21", "foo 3"] <| table.sort_columns text_ordering=(Text_Ordering.Case_Insensitive)
|
||||||
|
|
||||||
Test.specify "should correctly handle natural order sorting" <|
|
Test.specify "should correctly handle natural order sorting" <|
|
||||||
expect_column_names ["Foo_2", "bar", "foo_001", "foo_1", "foo_3", "foo_21", "foo_100"] <| table.sort_columns text_ordering=(Text_Ordering.Default sort_digits_as_numbers=True)
|
expect_column_names ["Foo 2", "bar", "foo 001", "foo 1", "foo 3", "foo 21", "foo 100"] <| table.sort_columns text_ordering=(Text_Ordering.Default sort_digits_as_numbers=True)
|
||||||
|
|
||||||
Test.specify "should correctly handle various combinations of options" <|
|
Test.specify "should correctly handle various combinations of options" <|
|
||||||
expect_column_names ["foo_100", "foo_21", "foo_3", "Foo_2", "foo_1", "foo_001", "bar"] <| table.sort_columns Sort_Direction.Descending text_ordering=(Text_Ordering.Case_Insensitive sort_digits_as_numbers=True)
|
expect_column_names ["foo 100", "foo 21", "foo 3", "Foo 2", "foo 1", "foo 001", "bar"] <| table.sort_columns Sort_Direction.Descending text_ordering=(Text_Ordering.Case_Insensitive sort_digits_as_numbers=True)
|
||||||
|
|
||||||
Test.group prefix+"Table.rename_columns" <|
|
Test.group prefix+"Table.rename_columns" <|
|
||||||
table =
|
table =
|
||||||
@ -441,41 +441,41 @@ spec setup =
|
|||||||
Test.specify "should correctly handle problems: invalid names ''" <|
|
Test.specify "should correctly handle problems: invalid names ''" <|
|
||||||
map = Map.from_vector [[1, ""]]
|
map = Map.from_vector [[1, ""]]
|
||||||
action = table.rename_columns map on_problems=_
|
action = table.rename_columns map on_problems=_
|
||||||
tester = expect_column_names ["alpha", "Column_1", "gamma", "delta"]
|
tester = expect_column_names ["alpha", "Column 1", "gamma", "delta"]
|
||||||
problems = [Invalid_Output_Column_Names.Error [""]]
|
problems = [Invalid_Output_Column_Names.Error [""]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: invalid names Nothing" <|
|
Test.specify "should correctly handle problems: invalid names Nothing" <|
|
||||||
map = ["alpha", Nothing]
|
map = ["alpha", Nothing]
|
||||||
action = table.rename_columns map on_problems=_
|
action = table.rename_columns map on_problems=_
|
||||||
tester = expect_column_names ["alpha", "Column_1", "gamma", "delta"]
|
tester = expect_column_names ["alpha", "Column 1", "gamma", "delta"]
|
||||||
problems = [Invalid_Output_Column_Names.Error [Nothing]]
|
problems = [Invalid_Output_Column_Names.Error [Nothing]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: invalid names null character" <|
|
Test.specify "should correctly handle problems: invalid names null character" <|
|
||||||
map = ["alpha", 'a\0b']
|
map = ["alpha", 'a\0b']
|
||||||
action = table.rename_columns map on_problems=_
|
action = table.rename_columns map on_problems=_
|
||||||
tester = expect_column_names ["alpha", "Column_1", "gamma", "delta"]
|
tester = expect_column_names ["alpha", "Column 1", "gamma", "delta"]
|
||||||
problems = [Invalid_Output_Column_Names.Error ['a\0b']]
|
problems = [Invalid_Output_Column_Names.Error ['a\0b']]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: duplicate names" <|
|
Test.specify "should correctly handle problems: duplicate names" <|
|
||||||
map = ["Test", "Test", "Test", "Test"]
|
map = ["Test", "Test", "Test", "Test"]
|
||||||
action = table.rename_columns map on_problems=_
|
action = table.rename_columns map on_problems=_
|
||||||
tester = expect_column_names ["Test", "Test_1", "Test_2", "Test_3"]
|
tester = expect_column_names ["Test", "Test 1", "Test 2", "Test 3"]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["Test", "Test", "Test"]]
|
problems = [Duplicate_Output_Column_Names.Error ["Test", "Test", "Test"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "should correctly handle problems: new name is clashing with existing name of existing column" <|
|
Test.specify "should correctly handle problems: new name is clashing with existing name of existing column" <|
|
||||||
map = Map.from_vector [["alpha", "beta"]]
|
map = Map.from_vector [["alpha", "beta"]]
|
||||||
action = table.rename_columns map on_problems=_
|
action = table.rename_columns map on_problems=_
|
||||||
tester = expect_column_names ["beta", "beta_1", "gamma", "delta"]
|
tester = expect_column_names ["beta", "beta 1", "gamma", "delta"]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["beta"]]
|
problems = [Duplicate_Output_Column_Names.Error ["beta"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
map2 = Map.from_vector [["beta", "alpha"]]
|
map2 = Map.from_vector [["beta", "alpha"]]
|
||||||
action2 = table.rename_columns map2 on_problems=_
|
action2 = table.rename_columns map2 on_problems=_
|
||||||
tester2 = expect_column_names ["alpha_1", "alpha", "gamma", "delta"]
|
tester2 = expect_column_names ["alpha 1", "alpha", "gamma", "delta"]
|
||||||
problems2 = [Duplicate_Output_Column_Names.Error ["alpha"]]
|
problems2 = [Duplicate_Output_Column_Names.Error ["alpha"]]
|
||||||
Problems.test_problem_handling action2 problems2 tester2
|
Problems.test_problem_handling action2 problems2 tester2
|
||||||
|
|
||||||
|
@ -73,18 +73,18 @@ spec setup =
|
|||||||
Test.specify "should handle missing columns" <|
|
Test.specify "should handle missing columns" <|
|
||||||
t1 = table_builder [["Key", ["x", "y", "z"]], ["Value", [1, 2, 3]], ["Another", [10, Nothing, 20]]]
|
t1 = table_builder [["Key", ["x", "y", "z"]], ["Value", [1, 2, 3]], ["Another", [10, Nothing, 20]]]
|
||||||
|
|
||||||
err1 = t1.transpose ["Key", "Missing", "Missing_2"]
|
err1 = t1.transpose ["Key", "Missing", "Missing 2"]
|
||||||
err1.should_fail_with Missing_Input_Columns
|
err1.should_fail_with Missing_Input_Columns
|
||||||
err1.catch.criteria . should_equal ["Missing", "Missing_2"]
|
err1.catch.criteria . should_equal ["Missing", "Missing 2"]
|
||||||
|
|
||||||
err2 = t1.transpose [0, -1, 42, -100]
|
err2 = t1.transpose [0, -1, 42, -100]
|
||||||
err2.should_fail_with Column_Indexes_Out_Of_Range
|
err2.should_fail_with Column_Indexes_Out_Of_Range
|
||||||
err2.catch.indexes . should_equal [42, -100]
|
err2.catch.indexes . should_equal [42, -100]
|
||||||
|
|
||||||
action1 = t1.transpose ["Key", "Missing", "Missing_2"] error_on_missing_columns=False on_problems=_
|
action1 = t1.transpose ["Key", "Missing", "Missing 2"] error_on_missing_columns=False on_problems=_
|
||||||
tester1 table =
|
tester1 table =
|
||||||
table.column_names . should_equal ["Key", "Name", "Value"]
|
table.column_names . should_equal ["Key", "Name", "Value"]
|
||||||
problems1 = [Missing_Input_Columns.Error ["Missing", "Missing_2"]]
|
problems1 = [Missing_Input_Columns.Error ["Missing", "Missing 2"]]
|
||||||
Problems.test_problem_handling action1 problems1 tester1
|
Problems.test_problem_handling action1 problems1 tester1
|
||||||
|
|
||||||
action2 = t1.transpose [0, -1, 42, -100] error_on_missing_columns=False on_problems=_
|
action2 = t1.transpose [0, -1, 42, -100] error_on_missing_columns=False on_problems=_
|
||||||
@ -98,13 +98,13 @@ spec setup =
|
|||||||
|
|
||||||
action1 = t1.transpose ["X", "Y", "Z"] name_field="Y" value_field="Z" on_problems=_
|
action1 = t1.transpose ["X", "Y", "Z"] name_field="Y" value_field="Z" on_problems=_
|
||||||
tester1 table =
|
tester1 table =
|
||||||
table.column_names . should_equal ["X", "Y", "Z", "Y_1", "Z_1"]
|
table.column_names . should_equal ["X", "Y", "Z", "Y 1", "Z 1"]
|
||||||
problems1 = [Duplicate_Output_Column_Names.Error ["Y", "Z"]]
|
problems1 = [Duplicate_Output_Column_Names.Error ["Y", "Z"]]
|
||||||
Problems.test_problem_handling action1 problems1 tester1
|
Problems.test_problem_handling action1 problems1 tester1
|
||||||
|
|
||||||
action2 = t1.transpose ["X"] name_field="F" value_field="F" on_problems=_
|
action2 = t1.transpose ["X"] name_field="F" value_field="F" on_problems=_
|
||||||
tester2 table =
|
tester2 table =
|
||||||
table.column_names . should_equal ["X", "F", "F_1"]
|
table.column_names . should_equal ["X", "F", "F 1"]
|
||||||
problems2 = [Duplicate_Output_Column_Names.Error ["F"]]
|
problems2 = [Duplicate_Output_Column_Names.Error ["F"]]
|
||||||
Problems.test_problem_handling action2 problems2 tester2
|
Problems.test_problem_handling action2 problems2 tester2
|
||||||
|
|
||||||
|
@ -115,9 +115,9 @@ spec =
|
|||||||
|
|
||||||
Test.group "Helpers" <|
|
Test.group "Helpers" <|
|
||||||
Test.specify "fresh_names should provide fresh names" <|
|
Test.specify "fresh_names should provide fresh names" <|
|
||||||
used_names = ["A", "A_1"]
|
used_names = ["A", "A 1"]
|
||||||
preferred_names = ["A", "A", "B"]
|
preferred_names = ["A", "A", "B"]
|
||||||
fresh_names used_names preferred_names . should_equal ["A_2", "A_3", "B"]
|
fresh_names used_names preferred_names . should_equal ["A 2", "A 3", "B"]
|
||||||
|
|
||||||
Test.group "[Codegen] Aggregation" <|
|
Test.group "[Codegen] Aggregation" <|
|
||||||
Test.specify "should allow to count rows" <|
|
Test.specify "should allow to count rows" <|
|
||||||
|
@ -34,7 +34,7 @@ spec make_new_connection prefix persistent_connector=True =
|
|||||||
Test.group prefix+"Uploading an in-memory Table" <|
|
Test.group prefix+"Uploading an in-memory Table" <|
|
||||||
in_memory_table = Table.new [["X", [1, 2, 3]], ["Y", ['a', 'b', 'c']]]
|
in_memory_table = Table.new [["X", [1, 2, 3]], ["Y", ['a', 'b', 'c']]]
|
||||||
Test.specify "should include the created table in the tables directory" <|
|
Test.specify "should include the created table in the tables directory" <|
|
||||||
db_table = in_memory_table.create_database_table connection (Name_Generator.random_name "permanent_table_1") temporary=False
|
db_table = in_memory_table.create_database_table connection (Name_Generator.random_name "permanent_table 1") temporary=False
|
||||||
Panic.with_finalizer (connection.drop_table db_table.name) <|
|
Panic.with_finalizer (connection.drop_table db_table.name) <|
|
||||||
db_table.at "X" . to_vector . should_equal [1, 2, 3]
|
db_table.at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ spec make_new_connection prefix persistent_connector=True =
|
|||||||
connection.query db_table.name . at "X" . to_vector . should_equal [1, 2, 3]
|
connection.query db_table.name . at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
|
|
||||||
Test.specify "should include the temporary table in the tables directory" <|
|
Test.specify "should include the temporary table in the tables directory" <|
|
||||||
db_table = in_memory_table.create_database_table connection (Name_Generator.random_name "temporary_table_1") temporary=True
|
db_table = in_memory_table.create_database_table connection (Name_Generator.random_name "temporary_table 1") temporary=True
|
||||||
db_table.at "X" . to_vector . should_equal [1, 2, 3]
|
db_table.at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
connection.tables.at "Name" . to_vector . should_contain db_table.name
|
connection.tables.at "Name" . to_vector . should_contain db_table.name
|
||||||
connection.query db_table.name . at "X" . to_vector . should_equal [1, 2, 3]
|
connection.query db_table.name . at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
@ -50,7 +50,7 @@ spec make_new_connection prefix persistent_connector=True =
|
|||||||
if persistent_connector then
|
if persistent_connector then
|
||||||
Test.specify "should drop the temporary table after the connection is closed" <|
|
Test.specify "should drop the temporary table after the connection is closed" <|
|
||||||
tmp_connection = make_new_connection Nothing
|
tmp_connection = make_new_connection Nothing
|
||||||
db_table = in_memory_table.create_database_table tmp_connection (Name_Generator.random_name "temporary_table_2") temporary=True
|
db_table = in_memory_table.create_database_table tmp_connection (Name_Generator.random_name "temporary_table 2") temporary=True
|
||||||
name = db_table.name
|
name = db_table.name
|
||||||
tmp_connection.query (SQL_Query.Table_Name name) . at "X" . to_vector . should_equal [1, 2, 3]
|
tmp_connection.query (SQL_Query.Table_Name name) . at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
tmp_connection.close
|
tmp_connection.close
|
||||||
@ -58,7 +58,7 @@ spec make_new_connection prefix persistent_connector=True =
|
|||||||
|
|
||||||
Test.specify "should preserve the regular table after the connection is closed" <|
|
Test.specify "should preserve the regular table after the connection is closed" <|
|
||||||
tmp_connection = make_new_connection Nothing
|
tmp_connection = make_new_connection Nothing
|
||||||
db_table = in_memory_table.create_database_table tmp_connection (Name_Generator.random_name "permanent_table_1") temporary=False
|
db_table = in_memory_table.create_database_table tmp_connection (Name_Generator.random_name "permanent_table 1") temporary=False
|
||||||
name = db_table.name
|
name = db_table.name
|
||||||
Panic.with_finalizer (connection.drop_table name) <|
|
Panic.with_finalizer (connection.drop_table name) <|
|
||||||
tmp_connection.query (SQL_Query.Table_Name name) . at "X" . to_vector . should_equal [1, 2, 3]
|
tmp_connection.query (SQL_Query.Table_Name name) . at "X" . to_vector . should_equal [1, 2, 3]
|
||||||
@ -143,11 +143,11 @@ spec make_new_connection prefix persistent_connector=True =
|
|||||||
db_table_4 = db_table_2.join db_table_3 join_kind=Join_Kind.Left_Outer
|
db_table_4 = db_table_2.join db_table_3 join_kind=Join_Kind.Left_Outer
|
||||||
|
|
||||||
copied_table = db_table_4.create_database_table connection (Name_Generator.random_name "copied-table") temporary=True primary_key=Nothing
|
copied_table = db_table_4.create_database_table connection (Name_Generator.random_name "copied-table") temporary=True primary_key=Nothing
|
||||||
copied_table.column_names . should_equal ["X", "Y", "C1", "C2", "Right_X", "C3"]
|
copied_table.column_names . should_equal ["X", "Y", "C1", "C2", "Right X", "C3"]
|
||||||
copied_table.at "X" . to_vector . should_equal [1, 1, 2]
|
copied_table.at "X" . to_vector . should_equal [1, 1, 2]
|
||||||
copied_table.at "C1" . to_vector . should_equal [101, 102, 203]
|
copied_table.at "C1" . to_vector . should_equal [101, 102, 203]
|
||||||
copied_table.at "C2" . to_vector . should_equal ["constant_text", "constant_text", "constant_text"]
|
copied_table.at "C2" . to_vector . should_equal ["constant_text", "constant_text", "constant_text"]
|
||||||
copied_table.at "Right_X" . to_vector . should_equal [Nothing, Nothing, 2]
|
copied_table.at "Right X" . to_vector . should_equal [Nothing, Nothing, 2]
|
||||||
copied_table.at "C3" . to_vector . should_equal [Nothing, Nothing, 5]
|
copied_table.at "C3" . to_vector . should_equal [Nothing, Nothing, 5]
|
||||||
|
|
||||||
# We check that this is indeed querying a simple DB table and not a complex query like `db_table_4` would be,
|
# We check that this is indeed querying a simple DB table and not a complex query like `db_table_4` would be,
|
||||||
|
@ -30,28 +30,28 @@ spec =
|
|||||||
Test.specify 'should rename duplicates names' <|
|
Test.specify 'should rename duplicates names' <|
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
strategy.make_unique "A" . should_equal "A"
|
strategy.make_unique "A" . should_equal "A"
|
||||||
strategy.make_unique "A" . should_equal "A_1"
|
strategy.make_unique "A" . should_equal "A 1"
|
||||||
strategy.make_unique "A" . should_equal "A_2"
|
strategy.make_unique "A" . should_equal "A 2"
|
||||||
strategy.renames.length . should_equal 2
|
strategy.renames.length . should_equal 2
|
||||||
strategy.invalid_names.length . should_equal 0
|
strategy.invalid_names.length . should_equal 0
|
||||||
|
|
||||||
Test.specify 'should preserve existing suffix' <|
|
Test.specify 'should preserve existing suffix' <|
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
strategy.make_unique "A" . should_equal "A"
|
strategy.make_unique "A" . should_equal "A"
|
||||||
strategy.make_unique "A_1" . should_equal "A_1"
|
strategy.make_unique "A 1" . should_equal "A 1"
|
||||||
strategy.make_unique "A" . should_equal "A_2"
|
strategy.make_unique "A" . should_equal "A 2"
|
||||||
strategy.make_unique "A_1" . should_equal "A_1_1"
|
strategy.make_unique "A 1" . should_equal "A 1 1"
|
||||||
strategy.renames.length . should_equal 2
|
strategy.renames.length . should_equal 2
|
||||||
strategy.invalid_names.length . should_equal 0
|
strategy.invalid_names.length . should_equal 0
|
||||||
|
|
||||||
Test.specify "should always add a counter when renaming invalid names" <|
|
Test.specify "should always add a counter when renaming invalid names" <|
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
strategy.make_unique "" . should_equal "Column_1"
|
strategy.make_unique "" . should_equal "Column 1"
|
||||||
strategy.make_unique "" . should_equal "Column_2"
|
strategy.make_unique "" . should_equal "Column 2"
|
||||||
strategy.make_unique Nothing . should_equal "Column_3"
|
strategy.make_unique Nothing . should_equal "Column 3"
|
||||||
strategy.make_unique "Foo" . should_equal "Foo"
|
strategy.make_unique "Foo" . should_equal "Foo"
|
||||||
strategy.make_unique "Column" . should_equal "Column"
|
strategy.make_unique "Column" . should_equal "Column"
|
||||||
strategy.make_unique "" . should_equal "Column_4"
|
strategy.make_unique "" . should_equal "Column 4"
|
||||||
|
|
||||||
Test.specify 'should work as in examples' <|
|
Test.specify 'should work as in examples' <|
|
||||||
unique_name_strategy = Unique_Name_Strategy.new
|
unique_name_strategy = Unique_Name_Strategy.new
|
||||||
@ -60,19 +60,19 @@ spec =
|
|||||||
invalid = unique_name_strategy.invalid_names
|
invalid = unique_name_strategy.invalid_names
|
||||||
duplicates.should_equal ["A"]
|
duplicates.should_equal ["A"]
|
||||||
invalid.should_equal [""]
|
invalid.should_equal [""]
|
||||||
unique_names.should_equal ["A", "B", "A_1", "Column_1"]
|
unique_names.should_equal ["A", "B", "A 1", "Column 1"]
|
||||||
|
|
||||||
strategy_1 = Unique_Name_Strategy.new
|
strategy_1 = Unique_Name_Strategy.new
|
||||||
strategy_1.make_unique "A" . should_equal "A"
|
strategy_1.make_unique "A" . should_equal "A"
|
||||||
strategy_1.make_unique "A" . should_equal "A_1"
|
strategy_1.make_unique "A" . should_equal "A 1"
|
||||||
|
|
||||||
Test.group "Unique_Name_Strategy.combine_with_prefix" <|
|
Test.group "Unique_Name_Strategy.combine_with_prefix" <|
|
||||||
Test.specify "should work as in examples" <|
|
Test.specify "should work as in examples" <|
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
first = ["A", "B", "second_A"]
|
first = ["A", "B", "second_A"]
|
||||||
second = ["A", "B", "second_A_1", "C"]
|
second = ["A", "B", "second_A 1", "C"]
|
||||||
unique_second = strategy.combine_with_prefix first second "second_"
|
unique_second = strategy.combine_with_prefix first second "second_"
|
||||||
unique_second . should_equal ["second_A_2", "second_B", "second_A_1", "C"]
|
unique_second . should_equal ["second_A 2", "second_B", "second_A 1", "C"]
|
||||||
strategy.invalid_names . should_equal []
|
strategy.invalid_names . should_equal []
|
||||||
strategy.renames . should_equal ["second_A"]
|
strategy.renames . should_equal ["second_A"]
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ spec =
|
|||||||
second = ["B", "A", "C"]
|
second = ["B", "A", "C"]
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
r = strategy.combine_with_prefix first second ""
|
r = strategy.combine_with_prefix first second ""
|
||||||
r . should_equal ["B_1", "A_1", "C"]
|
r . should_equal ["B 1", "A 1", "C"]
|
||||||
|
|
||||||
Test.specify "should work for empty input" <|
|
Test.specify "should work for empty input" <|
|
||||||
Unique_Name_Strategy.new.combine_with_prefix [] [] "" . should_equal []
|
Unique_Name_Strategy.new.combine_with_prefix [] [] "" . should_equal []
|
||||||
@ -89,34 +89,34 @@ spec =
|
|||||||
Unique_Name_Strategy.new.combine_with_prefix [] ["a"] "" . should_equal ["a"]
|
Unique_Name_Strategy.new.combine_with_prefix [] ["a"] "" . should_equal ["a"]
|
||||||
|
|
||||||
Test.specify "should find the first free spot" <|
|
Test.specify "should find the first free spot" <|
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2"] ["A"] "" . should_equal ["A_3"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2"] ["A"] "" . should_equal ["A 3"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2"] ["A_4", "A_6", "A_100", "A", "A_3"] "" . should_equal ["A_4", "A_6", "A_100", "A_5", "A_3"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2"] ["A 4", "A 6", "A 100", "A", "A 3"] "" . should_equal ["A 4", "A 6", "A 100", "A 5", "A 3"]
|
||||||
|
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2"] ["A"] "P_" . should_equal ["P_A"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2"] ["A"] "P_" . should_equal ["P_A"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2", "P_A"] ["A"] "P_" . should_equal ["P_A_1"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2", "P_A"] ["A"] "P_" . should_equal ["P_A 1"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2", "P_A_1"] ["A"] "P_" . should_equal ["P_A"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2", "P_A 1"] ["A"] "P_" . should_equal ["P_A"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix ["A", "A_1", "A_2", "P_A_1"] ["A", "P_A", "P_A_2"] "P_" . should_equal ["P_A_3", "P_A", "P_A_2"]
|
Unique_Name_Strategy.new.combine_with_prefix ["A", "A 1", "A 2", "P_A 1"] ["A", "P_A", "P_A 2"] "P_" . should_equal ["P_A 3", "P_A", "P_A 2"]
|
||||||
|
|
||||||
Test.specify "will add a prefix/suffix, not increment an existing counter" <|
|
Test.specify "will add a prefix/suffix, not increment an existing counter" <|
|
||||||
first = ["A", "A_1", "A_2", "A_3"]
|
first = ["A", "A 1", "A 2", "A 3"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix first ["A_2"] "P_" . should_equal ["P_A_2"]
|
Unique_Name_Strategy.new.combine_with_prefix first ["A 2"] "P_" . should_equal ["P_A 2"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix first ["A_2"] "" . should_equal ["A_2_1"]
|
Unique_Name_Strategy.new.combine_with_prefix first ["A 2"] "" . should_equal ["A 2 1"]
|
||||||
Unique_Name_Strategy.new.combine_with_prefix first+["P_A_2"] ["A_2"] "P_" . should_equal ["P_A_2_1"]
|
Unique_Name_Strategy.new.combine_with_prefix first+["P_A 2"] ["A 2"] "P_" . should_equal ["P_A 2 1"]
|
||||||
|
|
||||||
Test.specify "should prioritize existing names when renaming conflicts and rename only ones that are clashing with the other list" <|
|
Test.specify "should prioritize existing names when renaming conflicts and rename only ones that are clashing with the other list" <|
|
||||||
first = ["A", "B"]
|
first = ["A", "B"]
|
||||||
second = ["B", "A", "B_1", "C", "B_2", "B_4"]
|
second = ["B", "A", "B 1", "C", "B 2", "B_4"]
|
||||||
strategy = Unique_Name_Strategy.new
|
strategy = Unique_Name_Strategy.new
|
||||||
r = strategy.combine_with_prefix first second ""
|
r = strategy.combine_with_prefix first second ""
|
||||||
r . should_equal ["B_3", "A_1", "B_1", "C", "B_2", "B_4"]
|
r . should_equal ["B 3", "A 1", "B 1", "C", "B 2", "B_4"]
|
||||||
strategy.invalid_names . should_equal []
|
strategy.invalid_names . should_equal []
|
||||||
strategy.renames . should_equal ["B", "A"]
|
strategy.renames . should_equal ["B", "A"]
|
||||||
|
|
||||||
r2 = Unique_Name_Strategy.new.combine_with_prefix first second "P_"
|
r2 = Unique_Name_Strategy.new.combine_with_prefix first second "P_"
|
||||||
r2 . should_equal ["P_B", "P_A", "B_1", "C", "B_2", "B_4"]
|
r2 . should_equal ["P_B", "P_A", "B 1", "C", "B 2", "B_4"]
|
||||||
|
|
||||||
third = ["B", "A", "P_B", "X", "P_B_1", "P_B_2"]
|
third = ["B", "A", "P_B", "X", "P_B 1", "P_B 2"]
|
||||||
r3 = Unique_Name_Strategy.new.combine_with_prefix first third "P_"
|
r3 = Unique_Name_Strategy.new.combine_with_prefix first third "P_"
|
||||||
r3 . should_equal ["P_B_3", "P_A", "P_B", "X", "P_B_1", "P_B_2"]
|
r3 . should_equal ["P_B 3", "P_A", "P_B", "X", "P_B 1", "P_B 2"]
|
||||||
|
|
||||||
main = Test_Suite.run_main spec
|
main = Test_Suite.run_main spec
|
||||||
|
@ -29,13 +29,13 @@ spec =
|
|||||||
|
|
||||||
Test.specify "should correctly infer types of varied-type columns" <|
|
Test.specify "should correctly infer types of varied-type columns" <|
|
||||||
varied_column = (enso_project.data / "varied_column.csv") . read
|
varied_column = (enso_project.data / "varied_column.csv") . read
|
||||||
c_1 = ["Column_1", ["2005-02-25", "2005-02-28", "4", "2005-03-02", Nothing, "2005-03-04", "2005-03-07", "2005-03-08"]]
|
c_1 = ["Column 1", ["2005-02-25", "2005-02-28", "4", "2005-03-02", Nothing, "2005-03-04", "2005-03-07", "2005-03-08"]]
|
||||||
# We can re-enable this once date support is improved.
|
# We can re-enable this once date support is improved.
|
||||||
#c_2 = ["Column_2", ["2005-02-25", "2005-02-28", "2005-03-01", Nothing, "2005-03-03", "2005-03-04", "2005-03-07", "2005-03-08"]]
|
#c_2 = ["Column 2", ["2005-02-25", "2005-02-28", "2005-03-01", Nothing, "2005-03-03", "2005-03-04", "2005-03-07", "2005-03-08"]]
|
||||||
c_3 = ["Column_3", [1, 2, 3, 4, 5, Nothing, 7, 8]]
|
c_3 = ["Column 3", [1, 2, 3, 4, 5, Nothing, 7, 8]]
|
||||||
c_4 = ["Column_4", [1, 2, 3, 4, 5, 6, 7, 8]]
|
c_4 = ["Column 4", [1, 2, 3, 4, 5, 6, 7, 8]]
|
||||||
c_5 = ["Column_5", [1.0, 2.0, 3.0, 4.0, 5.0, 6.25, 7.0, 8.0]]
|
c_5 = ["Column 5", [1.0, 2.0, 3.0, 4.0, 5.0, 6.25, 7.0, 8.0]]
|
||||||
c_6 = ["Column_6", ['1', '2', '3', '4', '5', '6.25', '7', 'osiem']]
|
c_6 = ["Column 6", ['1', '2', '3', '4', '5', '6.25', '7', 'osiem']]
|
||||||
|
|
||||||
expected = Table.new [c_1, c_3, c_4, c_5, c_6]
|
expected = Table.new [c_1, c_3, c_4, c_5, c_6]
|
||||||
varied_column.select_columns [0, 2, 3, 4, 5] . should_equal expected
|
varied_column.select_columns [0, 2, 3, 4, 5] . should_equal expected
|
||||||
@ -45,14 +45,14 @@ spec =
|
|||||||
name,x,y,x,y
|
name,x,y,x,y
|
||||||
foo,10,20,30,20
|
foo,10,20,30,20
|
||||||
t = Table.from csv (format = Delimited ",")
|
t = Table.from csv (format = Delimited ",")
|
||||||
t.columns.map .name . should_equal ['name', 'x', 'y', 'x_1', 'y_1']
|
t.columns.map .name . should_equal ['name', 'x', 'y', 'x 1', 'y 1']
|
||||||
|
|
||||||
Test.group 'Writing' <|
|
Test.group 'Writing' <|
|
||||||
Test.specify 'should properly serialize simple tables' <|
|
Test.specify 'should properly serialize simple tables' <|
|
||||||
varied_column = (enso_project.data / "varied_column.csv") . read
|
varied_column = (enso_project.data / "varied_column.csv") . read
|
||||||
res = Text.from varied_column format=(Delimited ",")
|
res = Text.from varied_column format=(Delimited ",")
|
||||||
exp = normalize_lines <| '''
|
exp = normalize_lines <| '''
|
||||||
Column_1,Column_2,Column_3,Column_4,Column_5,Column_6
|
Column 1,Column 2,Column 3,Column 4,Column 5,Column 6
|
||||||
2005-02-25,2005-02-25,1,1,1.0,1
|
2005-02-25,2005-02-25,1,1,1.0,1
|
||||||
2005-02-28,2005-02-28,2,2,2.0,2
|
2005-02-28,2005-02-28,2,2,2.0,2
|
||||||
4,2005-03-01,3,3,3.0,3
|
4,2005-03-01,3,3,3.0,3
|
||||||
@ -98,7 +98,7 @@ spec =
|
|||||||
out.delete_if_exists
|
out.delete_if_exists
|
||||||
varied_column.write out
|
varied_column.write out
|
||||||
exp = normalize_lines <| '''
|
exp = normalize_lines <| '''
|
||||||
Column_1,Column_2,Column_3,Column_4,Column_5,Column_6
|
Column 1,Column 2,Column 3,Column 4,Column 5,Column 6
|
||||||
2005-02-25,2005-02-25,1,1,1.0,1
|
2005-02-25,2005-02-25,1,1,1.0,1
|
||||||
2005-02-28,2005-02-28,2,2,2.0,2
|
2005-02-28,2005-02-28,2,2,2.0,2
|
||||||
4,2005-03-01,3,3,3.0,3
|
4,2005-03-01,3,3,3.0,3
|
||||||
|
@ -25,9 +25,9 @@ spec =
|
|||||||
simple_empty.should_equal expected_table
|
simple_empty.should_equal expected_table
|
||||||
|
|
||||||
Test.specify "should load a simple table without headers" <|
|
Test.specify "should load a simple table without headers" <|
|
||||||
c_1 = ["Column_1", ['a', '1', '4', '7', '10']]
|
c_1 = ["Column 1", ['a', '1', '4', '7', '10']]
|
||||||
c_2 = ["Column_2", ['b', '2', Nothing, '8', '11']]
|
c_2 = ["Column 2", ['b', '2', Nothing, '8', '11']]
|
||||||
c_3 = ["Column_3", ['c', Nothing, '6', '9', '12']]
|
c_3 = ["Column 3", ['c', Nothing, '6', '9', '12']]
|
||||||
expected_table = Table.new [c_1, c_2, c_3]
|
expected_table = Table.new [c_1, c_2, c_3]
|
||||||
simple_empty = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False value_formatter=Nothing)
|
simple_empty = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False value_formatter=Nothing)
|
||||||
simple_empty.should_equal expected_table
|
simple_empty.should_equal expected_table
|
||||||
@ -35,11 +35,11 @@ spec =
|
|||||||
Test.specify "should work in presence of missing headers" <|
|
Test.specify "should work in presence of missing headers" <|
|
||||||
action on_problems = Data.read (enso_project.data / "missing_header.csv") (Delimited "," headers=True value_formatter=Nothing) on_problems
|
action on_problems = Data.read (enso_project.data / "missing_header.csv") (Delimited "," headers=True value_formatter=Nothing) on_problems
|
||||||
tester table =
|
tester table =
|
||||||
table.columns.map .name . should_equal ["a", "Column_1", "c", "Column_2", "d"]
|
table.columns.map .name . should_equal ["a", "Column 1", "c", "Column 2", "d"]
|
||||||
table.at "a" . to_vector . should_equal ["1"]
|
table.at "a" . to_vector . should_equal ["1"]
|
||||||
table.at "Column_1" . to_vector . should_equal ["2"]
|
table.at "Column 1" . to_vector . should_equal ["2"]
|
||||||
table.at "c" . to_vector . should_equal ["3"]
|
table.at "c" . to_vector . should_equal ["3"]
|
||||||
table.at "Column_2" . to_vector . should_equal ["4"]
|
table.at "Column 2" . to_vector . should_equal ["4"]
|
||||||
table.at "d" . to_vector . should_equal ["5"]
|
table.at "d" . to_vector . should_equal ["5"]
|
||||||
problems = [Invalid_Output_Column_Names.Error [Nothing, Nothing]]
|
problems = [Invalid_Output_Column_Names.Error [Nothing, Nothing]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
@ -49,9 +49,9 @@ spec =
|
|||||||
t1.columns.map .name . should_equal ["Code", "Index", "Flag", "Value", "ValueWithNothing", "TextWithNothing", "Hexadecimal", "Leading0s", "QuotedNumbers", "Mixed Types"]
|
t1.columns.map .name . should_equal ["Code", "Index", "Flag", "Value", "ValueWithNothing", "TextWithNothing", "Hexadecimal", "Leading0s", "QuotedNumbers", "Mixed Types"]
|
||||||
|
|
||||||
t2 = Data.read (enso_project.data / "all_text.csv") (Delimited ",")
|
t2 = Data.read (enso_project.data / "all_text.csv") (Delimited ",")
|
||||||
t2.columns.map .name . should_equal ["Column_1", "Column_2"]
|
t2.columns.map .name . should_equal ["Column 1", "Column 2"]
|
||||||
t2.at "Column_1" . to_vector . should_equal ["a", "c", "e", "g"]
|
t2.at "Column 1" . to_vector . should_equal ["a", "c", "e", "g"]
|
||||||
t2.at "Column_2" . to_vector . should_equal ["b", "d", "f", "h"]
|
t2.at "Column 2" . to_vector . should_equal ["b", "d", "f", "h"]
|
||||||
|
|
||||||
t3 = Data.read (enso_project.data / "two_rows1.csv") (Delimited ",")
|
t3 = Data.read (enso_project.data / "two_rows1.csv") (Delimited ",")
|
||||||
t3.columns.map .name . should_equal ["a", "b", "c"]
|
t3.columns.map .name . should_equal ["a", "b", "c"]
|
||||||
@ -60,16 +60,16 @@ spec =
|
|||||||
t3.at "c" . to_vector . should_equal [Nothing]
|
t3.at "c" . to_vector . should_equal [Nothing]
|
||||||
|
|
||||||
t4 = Data.read (enso_project.data / "two_rows2.csv") (Delimited ",")
|
t4 = Data.read (enso_project.data / "two_rows2.csv") (Delimited ",")
|
||||||
t4.columns.map .name . should_equal ["Column_1", "Column_2", "Column_3"]
|
t4.columns.map .name . should_equal ["Column 1", "Column 2", "Column 3"]
|
||||||
t4.at "Column_1" . to_vector . should_equal ["a", "d"]
|
t4.at "Column 1" . to_vector . should_equal ["a", "d"]
|
||||||
t4.at "Column_2" . to_vector . should_equal ["b", "e"]
|
t4.at "Column 2" . to_vector . should_equal ["b", "e"]
|
||||||
t4.at "Column_3" . to_vector . should_equal ["c", "f"]
|
t4.at "Column 3" . to_vector . should_equal ["c", "f"]
|
||||||
|
|
||||||
t5 = Data.read (enso_project.data / "numbers_in_header.csv") (Delimited ",")
|
t5 = Data.read (enso_project.data / "numbers_in_header.csv") (Delimited ",")
|
||||||
t5.columns.map .name . should_equal ["Column_1", "Column_2", "Column_3"]
|
t5.columns.map .name . should_equal ["Column 1", "Column 2", "Column 3"]
|
||||||
t5.at "Column_1" . to_vector . should_equal ["a", "1"]
|
t5.at "Column 1" . to_vector . should_equal ["a", "1"]
|
||||||
t5.at "Column_2" . to_vector . should_equal ["b", "2"]
|
t5.at "Column 2" . to_vector . should_equal ["b", "2"]
|
||||||
t5.at "Column_3" . to_vector . should_equal [0, 3]
|
t5.at "Column 3" . to_vector . should_equal [0, 3]
|
||||||
|
|
||||||
t6 = Data.read (enso_project.data / "quoted_numbers_in_header.csv") (Delimited ",")
|
t6 = Data.read (enso_project.data / "quoted_numbers_in_header.csv") (Delimited ",")
|
||||||
t6.columns.map .name . should_equal ["1", "x"]
|
t6.columns.map .name . should_equal ["1", "x"]
|
||||||
@ -78,10 +78,10 @@ spec =
|
|||||||
|
|
||||||
Test.specify "should not use the first row as headers if it is the only row, unless specifically asked to" <|
|
Test.specify "should not use the first row as headers if it is the only row, unless specifically asked to" <|
|
||||||
t1 = Data.read (enso_project.data / "one_row.csv") (Delimited ",")
|
t1 = Data.read (enso_project.data / "one_row.csv") (Delimited ",")
|
||||||
t1.columns.map .name . should_equal ["Column_1", "Column_2", "Column_3"]
|
t1.columns.map .name . should_equal ["Column 1", "Column 2", "Column 3"]
|
||||||
t1.at "Column_1" . to_vector . should_equal ["x"]
|
t1.at "Column 1" . to_vector . should_equal ["x"]
|
||||||
t1.at "Column_2" . to_vector . should_equal ["y"]
|
t1.at "Column 2" . to_vector . should_equal ["y"]
|
||||||
t1.at "Column_3" . to_vector . should_equal ["z"]
|
t1.at "Column 3" . to_vector . should_equal ["z"]
|
||||||
|
|
||||||
t2 = Data.read (enso_project.data / "one_row.csv") (Delimited "," headers=True)
|
t2 = Data.read (enso_project.data / "one_row.csv") (Delimited "," headers=True)
|
||||||
t2.columns.map .name . should_equal ["x", "y", "z"]
|
t2.columns.map .name . should_equal ["x", "y", "z"]
|
||||||
@ -138,10 +138,10 @@ spec =
|
|||||||
|
|
||||||
format = Delimited ',' headers=False value_formatter=(Data_Formatter.Value trim_values=False)
|
format = Delimited ',' headers=False value_formatter=(Data_Formatter.Value trim_values=False)
|
||||||
|
|
||||||
reference_table = Table.new [["Column_1", ["a", "d", "1"]], ["Column_2", ["b", "e", "2"]], ["Column_3", ["c", "f", "3"]]]
|
reference_table = Table.new [["Column 1", ["a", "d", "1"]], ["Column 2", ["b", "e", "2"]], ["Column 3", ["c", "f", "3"]]]
|
||||||
collapsed_table = Table.new <|
|
collapsed_table = Table.new <|
|
||||||
['a', 'b', 'c\nd', 'e', 'f\n1', 2, 3].map_with_index i-> v->
|
['a', 'b', 'c\nd', 'e', 'f\n1', 2, 3].map_with_index i-> v->
|
||||||
["Column_" + (i+1).to_text, [v]]
|
["Column " + (i+1).to_text, [v]]
|
||||||
Data.read file format . should_equal reference_table
|
Data.read file format . should_equal reference_table
|
||||||
Data.read file (format.with_line_endings Line_Ending_Style.Unix) . should_equal reference_table
|
Data.read file (format.with_line_endings Line_Ending_Style.Unix) . should_equal reference_table
|
||||||
Data.read file (format.with_line_endings Line_Ending_Style.Mac_Legacy) . should_equal collapsed_table
|
Data.read file (format.with_line_endings Line_Ending_Style.Mac_Legacy) . should_equal collapsed_table
|
||||||
@ -201,9 +201,9 @@ spec =
|
|||||||
Test.specify "should handle duplicated columns" <|
|
Test.specify "should handle duplicated columns" <|
|
||||||
action on_problems = Data.read (enso_project.data / "duplicated_columns.csv") (Delimited "," headers=True value_formatter=Nothing) on_problems
|
action on_problems = Data.read (enso_project.data / "duplicated_columns.csv") (Delimited "," headers=True value_formatter=Nothing) on_problems
|
||||||
tester table =
|
tester table =
|
||||||
table.columns.map .name . should_equal ['a', 'b', 'c', 'a_1']
|
table.columns.map .name . should_equal ['a', 'b', 'c', 'a 1']
|
||||||
table.at 'a' . to_vector . should_equal ['1']
|
table.at 'a' . to_vector . should_equal ['1']
|
||||||
table.at 'a_1' . to_vector . should_equal ['4']
|
table.at 'a 1' . to_vector . should_equal ['4']
|
||||||
problems = [Duplicate_Output_Column_Names.Error ['a']]
|
problems = [Duplicate_Output_Column_Names.Error ['a']]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -337,7 +337,7 @@ spec =
|
|||||||
|
|
||||||
Test.specify "should allow to skip rows" <|
|
Test.specify "should allow to skip rows" <|
|
||||||
t1 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 value_formatter=Nothing)
|
t1 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 value_formatter=Nothing)
|
||||||
t1.at "Column_1" . to_vector . should_equal ['7', '10']
|
t1.at "Column 1" . to_vector . should_equal ['7', '10']
|
||||||
|
|
||||||
t2 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True skip_rows=3 value_formatter=Nothing)
|
t2 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True skip_rows=3 value_formatter=Nothing)
|
||||||
t2.columns.map .name . should_equal ['7', '8', '9']
|
t2.columns.map .name . should_equal ['7', '8', '9']
|
||||||
@ -345,16 +345,16 @@ spec =
|
|||||||
|
|
||||||
Test.specify "should allow to set a limit of rows to read" <|
|
Test.specify "should allow to set a limit of rows to read" <|
|
||||||
t1 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False row_limit=2 value_formatter=Nothing)
|
t1 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False row_limit=2 value_formatter=Nothing)
|
||||||
t1.at "Column_1" . to_vector . should_equal ['a', '1']
|
t1.at "Column 1" . to_vector . should_equal ['a', '1']
|
||||||
|
|
||||||
t2 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True row_limit=2 value_formatter=Nothing)
|
t2 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True row_limit=2 value_formatter=Nothing)
|
||||||
t2.at "a" . to_vector . should_equal ['1', '4']
|
t2.at "a" . to_vector . should_equal ['1', '4']
|
||||||
|
|
||||||
t3 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 row_limit=1 value_formatter=Nothing)
|
t3 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 row_limit=1 value_formatter=Nothing)
|
||||||
t3.at "Column_1" . to_vector . should_equal ['7']
|
t3.at "Column 1" . to_vector . should_equal ['7']
|
||||||
|
|
||||||
t4 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False row_limit=0 value_formatter=Nothing)
|
t4 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False row_limit=0 value_formatter=Nothing)
|
||||||
t4.columns.map .name . should_equal ['Column_1', 'Column_2', 'Column_3']
|
t4.columns.map .name . should_equal ['Column 1', 'Column 2', 'Column 3']
|
||||||
t4.row_count . should_equal 0
|
t4.row_count . should_equal 0
|
||||||
|
|
||||||
t5 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True row_limit=0 value_formatter=Nothing)
|
t5 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=True row_limit=0 value_formatter=Nothing)
|
||||||
@ -363,7 +363,7 @@ spec =
|
|||||||
t5.row_count . should_equal 0
|
t5.row_count . should_equal 0
|
||||||
|
|
||||||
t6 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 row_limit=1000 value_formatter=Nothing)
|
t6 = Data.read (enso_project.data / "simple_empty.csv") (Delimited "," headers=False skip_rows=3 row_limit=1000 value_formatter=Nothing)
|
||||||
t6.at "Column_1" . to_vector . should_equal ['7', '10']
|
t6.at "Column 1" . to_vector . should_equal ['7', '10']
|
||||||
|
|
||||||
Test.specify "should check arguments" <|
|
Test.specify "should check arguments" <|
|
||||||
path = (enso_project.data / "simple_empty.csv")
|
path = (enso_project.data / "simple_empty.csv")
|
||||||
|
@ -347,7 +347,7 @@ spec =
|
|||||||
with_headers = base_format . with_headers
|
with_headers = base_format . with_headers
|
||||||
|
|
||||||
expected_table_with_headers = Table.new [["A", [1,2,33,44]], ["B", [1.0,1.5,Nothing,0]], ["C", ["x","y","a","BB"]]]
|
expected_table_with_headers = Table.new [["A", [1,2,33,44]], ["B", [1.0,1.5,Nothing,0]], ["C", ["x","y","a","BB"]]]
|
||||||
expected_table_without_headers = expected_table_with_headers.rename_columns ["Column_1", "Column_2", "Column_3"]
|
expected_table_without_headers = expected_table_with_headers.rename_columns ["Column 1", "Column 2", "Column 3"]
|
||||||
|
|
||||||
test_append initial_file_format=with_headers append_format=no_headers expected_table_with_headers
|
test_append initial_file_format=with_headers append_format=no_headers expected_table_with_headers
|
||||||
test_append initial_file_format=with_headers append_format=base_format expected_table_with_headers
|
test_append initial_file_format=with_headers append_format=base_format expected_table_with_headers
|
||||||
|
@ -47,8 +47,8 @@ spec_fmt header file read_method sheet_count=5 =
|
|||||||
|
|
||||||
Test.specify "should gracefully handle duplicate column names and formulas" <|
|
Test.specify "should gracefully handle duplicate column names and formulas" <|
|
||||||
t = read_method file (Excel (Worksheet "Duplicate Columns"))
|
t = read_method file (Excel (Worksheet "Duplicate Columns"))
|
||||||
t.columns.map .name . should_equal ['Item', 'Price', 'Quantity', 'Price_1']
|
t.columns.map .name . should_equal ['Item', 'Price', 'Quantity', 'Price 1']
|
||||||
t.at 'Price_1' . to_vector . should_equal [20, 40, 0, 60, 0, 10]
|
t.at 'Price 1' . to_vector . should_equal [20, 40, 0, 60, 0, 10]
|
||||||
|
|
||||||
Test.specify "should allow reading with cell range specified" <|
|
Test.specify "should allow reading with cell range specified" <|
|
||||||
t_1 = read_method file (Excel (Cell_Range "Simple!B:C"))
|
t_1 = read_method file (Excel (Cell_Range "Simple!B:C"))
|
||||||
@ -292,8 +292,8 @@ spec_write suffix test_sheet_name =
|
|||||||
Test.specify 'should be able to append to a range by name after deduplication of names' <|
|
Test.specify 'should be able to append to a range by name after deduplication of names' <|
|
||||||
out.delete_if_exists
|
out.delete_if_exists
|
||||||
(enso_project.data / test_sheet_name) . copy_to out
|
(enso_project.data / test_sheet_name) . copy_to out
|
||||||
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['AA_1',[True, False]], ['BB_1', ['2022-01-20', '2022-01-21']]]
|
extra_another = Table.new [['AA', ['d', 'e']], ['BB',[4, 5]], ['AA 1',[True, False]], ['BB 1', ['2022-01-20', '2022-01-21']]]
|
||||||
expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['AA_1',[True, False, False, True, False]]]
|
expected = Table.new [['AA', ['f', 'g', 'h', 'd', 'e']], ['BB',[1, 2, 3, 4, 5]], ['AA 1',[True, False, False, True, False]]]
|
||||||
extra_another.write out (Excel (Cell_Range "Random!S3")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
|
extra_another.write out (Excel (Cell_Range "Random!S3")) on_existing_file=Existing_File_Behavior.Append on_problems=Report_Error . should_succeed
|
||||||
written = out.read (Excel (Cell_Range "Random!S3")) . select_columns [0, 1, 2]
|
written = out.read (Excel (Cell_Range "Random!S3")) . select_columns [0, 1, 2]
|
||||||
written.should_equal expected
|
written.should_equal expected
|
||||||
@ -725,10 +725,10 @@ spec =
|
|||||||
check_table (file.read (Excel (Cell_Range "Sheet1!B2"))) ["B"] [["A","B","C","D","E","F"]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!B2"))) ["B"] [["A","B","C","D","E","F"]]
|
||||||
|
|
||||||
Test.specify "Patchy table" <|
|
Test.specify "Patchy table" <|
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!D1"))) ["A", "B", "Column_1"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!D1"))) ["A", "B", "Column 1"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!D2"))) ["D", "E", "F"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!D2"))) ["D", "E", "F"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!E"))) ["B"] [[4,4,Nothing,Nothing,Nothing,Nothing]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!E"))) ["B"] [[4,4,Nothing,Nothing,Nothing,Nothing]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!E1"))) ["B", "Column_1"] [[4,4,Nothing], [6,Nothing,6]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!E1"))) ["B", "Column 1"] [[4,4,Nothing], [6,Nothing,6]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!E2"))) ["E", "F"] [[4,4,Nothing], [6,Nothing,6]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!E2"))) ["E", "F"] [[4,4,Nothing], [6,Nothing,6]]
|
||||||
|
|
||||||
Test.specify "Single cell" <|
|
Test.specify "Single cell" <|
|
||||||
@ -739,19 +739,19 @@ spec =
|
|||||||
check_table (file.read (Excel (Cell_Range "Sheet1!J1"))) ["J", "K", "L"] [["Just"],["Some"],["Headers"]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!J1"))) ["J", "K", "L"] [["Just"],["Some"],["Headers"]]
|
||||||
|
|
||||||
Test.specify "Growing table" <|
|
Test.specify "Growing table" <|
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!N1"))) ["A", "Full", "Table", "Column_1"] [["Hello","World",Nothing,"Extend"],[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!N1"))) ["A", "Full", "Table", "Column 1"] [["Hello","World",Nothing,"Extend"],[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!O1"))) ["Full", "Table", "Column_1"] [[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!O1"))) ["Full", "Table", "Column 1"] [[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
||||||
check_table (file.read (Excel (Cell_Range "Sheet1!O2"))) ["O", "P", "Q"] [[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
check_table (file.read (Excel (Cell_Range "Sheet1!O2"))) ["O", "P", "Q"] [[1,Nothing,"Gap",3],[2,2,"Here",5],[Nothing,Nothing,"To","Hello"]]
|
||||||
|
|
||||||
Test.specify "Should handle invalid headers with warnings" <|
|
Test.specify "Should handle invalid headers with warnings" <|
|
||||||
action = file.read (Excel (Cell_Range "Sheet1!D1")) on_problems=_
|
action = file.read (Excel (Cell_Range "Sheet1!D1")) on_problems=_
|
||||||
tester = check_table _ ["A", "B", "Column_1"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
tester = check_table _ ["A", "B", "Column 1"] [[1,2,4], [4,4,Nothing], [6,Nothing,6]]
|
||||||
problems = [Invalid_Output_Column_Names.Error [""]]
|
problems = [Invalid_Output_Column_Names.Error [""]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
Test.specify "Should handle duplicate headers with warnings" <|
|
Test.specify "Should handle duplicate headers with warnings" <|
|
||||||
action = file.read (Excel (Cell_Range "Sheet1!S1")) on_problems=_
|
action = file.read (Excel (Cell_Range "Sheet1!S1")) on_problems=_
|
||||||
tester = check_table _ ["DD", "DD_1"] [[1,3], [2,4]]
|
tester = check_table _ ["DD", "DD 1"] [[1,3], [2,4]]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["DD"]]
|
problems = [Duplicate_Output_Column_Names.Error ["DD"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
|
@ -66,10 +66,10 @@ spec = Test.group "Columns" <|
|
|||||||
r.to_vector . should_equal [0, 2, 4, 5, Nothing, 30]
|
r.to_vector . should_equal [0, 2, 4, 5, Nothing, 30]
|
||||||
|
|
||||||
Test.specify "should allow to count duplicate value occurences" <|
|
Test.specify "should allow to count duplicate value occurences" <|
|
||||||
c_1 = Column.from_vector "c_1" [0, 1, 2, 2, 1, 0, 2]
|
c_1 = Column.from_vector "c 1" [0, 1, 2, 2, 1, 0, 2]
|
||||||
c_1.duplicate_count.to_vector.should_equal [0, 0, 0, 1, 1, 1, 2]
|
c_1.duplicate_count.to_vector.should_equal [0, 0, 0, 1, 1, 1, 2]
|
||||||
|
|
||||||
c_2 = Column.from_vector "c_2" ["foo", "bar", "foo", "baz", "bar"]
|
c_2 = Column.from_vector "c 2" ["foo", "bar", "foo", "baz", "bar"]
|
||||||
c_2.duplicate_count.to_vector.should_equal [0, 0, 1, 0, 1]
|
c_2.duplicate_count.to_vector.should_equal [0, 0, 1, 0, 1]
|
||||||
|
|
||||||
Test.specify "should result in correct Storage if operation allows it" <|
|
Test.specify "should result in correct Storage if operation allows it" <|
|
||||||
|
@ -76,7 +76,7 @@ spec =
|
|||||||
t4 = r2.second . order_by "N"
|
t4 = r2.second . order_by "N"
|
||||||
t4.row_count . should_equal n
|
t4.row_count . should_equal n
|
||||||
t4.at "X" . to_vector . should_equal lowers
|
t4.at "X" . to_vector . should_equal lowers
|
||||||
t4.at "Right_X" . to_vector . should_equal uppers
|
t4.at "Right X" . to_vector . should_equal uppers
|
||||||
t4.at "Z" . to_vector . should_equal <| 1.up_to n+1 . to_vector . reverse
|
t4.at "Z" . to_vector . should_equal <| 1.up_to n+1 . to_vector . reverse
|
||||||
|
|
||||||
base_ms = r1.first.total_milliseconds
|
base_ms = r1.first.total_milliseconds
|
||||||
|
@ -14,7 +14,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c", Nothing], [1, "c", "d", "ef"], [2, "gh", "ij", "u"]]
|
expected_rows = [[0, "a", "c", Nothing], [1, "c", "d", "ef"], [2, "gh", "ij", "u"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.split_to_columns "bar" "b"
|
t2 = t.split_to_columns "bar" "b"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2, 3]], ["bar", ["abc", "cbdbef", Nothing, "ghbijbu"]]]
|
cols = [["foo", [0, 1, 2, 3]], ["bar", ["abc", "cbdbef", Nothing, "ghbijbu"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c", Nothing], [1, "c", "d", "ef"], [2, Nothing, Nothing, Nothing], [3, "gh", "ij", "u"]]
|
expected_rows = [[0, "a", "c", Nothing], [1, "c", "d", "ef"], [2, Nothing, Nothing, Nothing], [3, "gh", "ij", "u"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.split_to_columns "bar" "b"
|
t2 = t.split_to_columns "bar" "b"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["a12b34r5", "23", "2r4r55"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["a12b34r5", "23", "2r4r55"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "12", "34", "5"], [1, "23", Nothing, Nothing], [2, "2", "4", "55"]]
|
expected_rows = [[0, "12", "34", "5"], [1, "23", Nothing, Nothing], [2, "2", "4", "55"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.tokenize_to_columns "bar" "\d+"
|
t2 = t.tokenize_to_columns "bar" "\d+"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2, 3]], ["bar", ["a12b34r5", Nothing, "23", "2r4r55"]]]
|
cols = [["foo", [0, 1, 2, 3]], ["bar", ["a12b34r5", Nothing, "23", "2r4r55"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "12", "34", "5"], [1, Nothing, Nothing, Nothing], [2, "23", Nothing, Nothing], [3, "2", "4", "55"]]
|
expected_rows = [[0, "12", "34", "5"], [1, Nothing, Nothing, Nothing], [2, "23", Nothing, Nothing], [3, "2", "4", "55"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.tokenize_to_columns "bar" "\d+"
|
t2 = t.tokenize_to_columns "bar" "\d+"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1]], ["bar", ["r a-1, b-12,qd-50", "ab-10:bc-20c"]]]
|
cols = [["foo", [0, 1]], ["bar", ["r a-1, b-12,qd-50", "ab-10:bc-20c"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a1", "b12", "d50"], [1, "b10", "c20", Nothing]]
|
expected_rows = [[0, "a1", "b12", "d50"], [1, "b10", "c20", Nothing]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.tokenize_to_columns "bar" "([a-z]).(\d+)"
|
t2 = t.tokenize_to_columns "bar" "([a-z]).(\d+)"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["aBqcE", "qcBr", "cCb"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["aBqcE", "qcBr", "cCb"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "B", "c", Nothing], [1, "c", "B", Nothing], [2, "c", "C", "b"]]
|
expected_rows = [[0, "B", "c", Nothing], [1, "c", "B", Nothing], [2, "c", "C", "b"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3"] expected_rows
|
||||||
t2 = t.tokenize_to_columns "bar" "[bc]" case_sensitivity=Case_Sensitivity.Insensitive
|
t2 = t.tokenize_to_columns "bar" "[bc]" case_sensitivity=Case_Sensitivity.Insensitive
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c", Nothing, Nothing], [1, "c", "d", "ef", Nothing], [2, "gh", "ij", "u", Nothing]]
|
expected_rows = [[0, "a", "c", Nothing, Nothing], [1, "c", "d", "ef", Nothing], [2, "gh", "ij", "u", Nothing]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2", "bar 3"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3", "bar 3"] expected_rows
|
||||||
t2 = t.split_to_columns "bar" "b" column_count=4
|
t2 = t.split_to_columns "bar" "b" column_count=4
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
t2.at "bar 3" . value_type . is_text . should_be_true
|
t2.at "bar 3" . value_type . is_text . should_be_true
|
||||||
@ -141,7 +141,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c"], [1, "c", "d"], [2, "gh", "ij"]]
|
expected_rows = [[0, "a", "c"], [1, "c", "d"], [2, "gh", "ij"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2"] expected_rows
|
||||||
action = t.split_to_columns "bar" "b" column_count=2 on_problems=_
|
action = t.split_to_columns "bar" "b" column_count=2 on_problems=_
|
||||||
tester = t-> t.should_equal expected
|
tester = t-> t.should_equal expected
|
||||||
problems = [Column_Count_Exceeded.Error 2 3]
|
problems = [Column_Count_Exceeded.Error 2 3]
|
||||||
@ -151,7 +151,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1]], ["bar", ["r a-1, b-12,qd-50", "ab-10:bc-20c"]]]
|
cols = [["foo", [0, 1]], ["bar", ["r a-1, b-12,qd-50", "ab-10:bc-20c"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a1", "b12", "d50"], [1, "b10", "c20", Nothing]]
|
expected_rows = [[0, "a1", "b12", "d50"], [1, "b10", "c20", Nothing]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2"] expected_rows
|
||||||
action = t.tokenize_to_columns "bar" "([a-z]).(\d+)" column_count=2 on_problems=_
|
action = t.tokenize_to_columns "bar" "([a-z]).(\d+)" column_count=2 on_problems=_
|
||||||
tester = t-> t.should_equal expected
|
tester = t-> t.should_equal expected
|
||||||
problems = [Column_Count_Exceeded.Error 2 3]
|
problems = [Column_Count_Exceeded.Error 2 3]
|
||||||
@ -161,7 +161,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["ghbijbu", "cbdbef", "abc"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["ghbijbu", "cbdbef", "abc"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "gh", "ij", "u", Nothing], [1, "c", "d", "ef", Nothing], [2, "a", "c", Nothing, Nothing]]
|
expected_rows = [[0, "gh", "ij", "u", Nothing], [1, "c", "d", "ef", Nothing], [2, "a", "c", Nothing, Nothing]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2", "bar 3"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3", "bar 3"] expected_rows
|
||||||
t2 = t.split_to_columns "bar" "b" column_count=4
|
t2 = t.split_to_columns "bar" "b" column_count=4
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
t2.at "bar 3" . value_type . is_text . should_be_true
|
t2.at "bar 3" . value_type . is_text . should_be_true
|
||||||
@ -198,7 +198,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]], ["bar 1", ["a", "b", "c"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]], ["bar 1", ["a", "b", "c"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c", Nothing, "a"], [1, "c", "d", "ef", "b"], [2, "gh", "ij", "u", "c"]]
|
expected_rows = [[0, "a", "c", Nothing, "a"], [1, "c", "d", "ef", "b"], [2, "gh", "ij", "u", "c"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1_1", "bar 2", "bar 1"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1 1", "bar 2", "bar 3", "bar 1"] expected_rows
|
||||||
action = t.split_to_columns "bar" "b" on_problems=_
|
action = t.split_to_columns "bar" "b" on_problems=_
|
||||||
tester = t-> t.should_equal expected
|
tester = t-> t.should_equal expected
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["bar 1"]]
|
problems = [Duplicate_Output_Column_Names.Error ["bar 1"]]
|
||||||
@ -208,7 +208,7 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["a12b34r5", "23", "2r4r55"]], ["bar 1", ["a", "b", "c"]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["a12b34r5", "23", "2r4r55"]], ["bar 1", ["a", "b", "c"]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "12", "34", "5", "a"], [1, "23", Nothing, Nothing, "b"], [2, "2", "4", "55", "c"]]
|
expected_rows = [[0, "12", "34", "5", "a"], [1, "23", Nothing, Nothing, "b"], [2, "2", "4", "55", "c"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1_1", "bar 2", "bar 1"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1 1", "bar 2", "bar 3", "bar 1"] expected_rows
|
||||||
action = t.tokenize_to_columns "bar" "\d+" on_problems=_
|
action = t.tokenize_to_columns "bar" "\d+" on_problems=_
|
||||||
tester = t-> t.should_equal expected
|
tester = t-> t.should_equal expected
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["bar 1"]]
|
problems = [Duplicate_Output_Column_Names.Error ["bar 1"]]
|
||||||
@ -219,14 +219,14 @@ spec =
|
|||||||
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]], ["baz", [1, 2, 3]]]
|
cols = [["foo", [0, 1, 2]], ["bar", ["abc", "cbdbef", "ghbijbu"]], ["baz", [1, 2, 3]]]
|
||||||
t = Table.new cols
|
t = Table.new cols
|
||||||
expected_rows = [[0, "a", "c", Nothing, 1], [1, "c", "d", "ef", 2], [2, "gh", "ij", "u", 3]]
|
expected_rows = [[0, "a", "c", Nothing, 1], [1, "c", "d", "ef", 2], [2, "gh", "ij", "u", 3]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2", "baz"] expected_rows
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3", "baz"] expected_rows
|
||||||
t2 = t.split_to_columns "bar" "b"
|
t2 = t.split_to_columns "bar" "b"
|
||||||
t2.should_equal expected
|
t2.should_equal expected
|
||||||
|
|
||||||
Test.group "Table.parse_to_columns" <|
|
Test.group "Table.parse_to_columns" <|
|
||||||
Test.specify "can parse to columns" <|
|
Test.specify "can parse to columns" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "baz"] [["x", 1, 2, "y"], ["x", 3, 4, "y"], ["x", 5, 6, "y"], ["xx", 4, 8, "yy"], ["xx", 5, 9, "yy"]]
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "baz"] [["x", 1, 2, "y"], ["x", 3, 4, "y"], ["x", 5, 6, "y"], ["xx", 4, 8, "yy"], ["xx", 5, 9, "yy"]]
|
||||||
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
@ -244,31 +244,31 @@ spec =
|
|||||||
|
|
||||||
Test.specify "non-participating groups" <|
|
Test.specify "non-participating groups" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "q1", "y"], ["xx", "qp", "yy"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "q1", "y"], ["xx", "qp", "yy"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "bar 2", "baz"] [["x", "1", 1, Nothing, "y"], ["xx", "p", Nothing, "p", "yy"]]
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "bar 3", "baz"] [["x", "1", 1, Nothing, "y"], ["xx", "p", Nothing, "p", "yy"]]
|
||||||
actual = t.parse_to_columns "bar" "q((\d)|([a-z]))"
|
actual = t.parse_to_columns "bar" "q((\d)|([a-z]))"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "case-insensitive" <|
|
Test.specify "case-insensitive" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "qq", "y"], ["xx", "qQ", "yy"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "qq", "y"], ["xx", "qQ", "yy"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "baz"] [["x", "q", "y"], ["xx", "Q", "yy"]]
|
expected = Table.from_rows ["foo", "bar 1", "baz"] [["x", "q", "y"], ["xx", "Q", "yy"]]
|
||||||
actual = t.parse_to_columns "bar" "q(q)" case_sensitivity=Case_Sensitivity.Insensitive
|
actual = t.parse_to_columns "bar" "q(q)" case_sensitivity=Case_Sensitivity.Insensitive
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "no post-parsing" <|
|
Test.specify "no post-parsing" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "baz"] [["x", "1", "2", "y"], ["x", "3", "4", "y"], ["x", "5", "6", "y"], ["xx", "4", "8", "yy"], ["xx", "5", "9", "yy"]]
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "baz"] [["x", "1", "2", "y"], ["x", "3", "4", "y"], ["x", "5", "6", "y"], ["xx", "4", "8", "yy"], ["xx", "5", "9", "yy"]]
|
||||||
actual = t.parse_to_columns "bar" "(\d)(\d)" parse_values=False
|
actual = t.parse_to_columns "bar" "(\d)(\d)" parse_values=False
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "column name clash" <|
|
Test.specify "column name clash" <|
|
||||||
t = Table.from_rows ["foo", "bar", "bar 1"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
t = Table.from_rows ["foo", "bar", "bar 1"] [["x", "12 34p q56", "y"], ["xx", "a48 59b", "yy"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1_1", "bar 1"] [["x", 1, 2, "y"], ["x", 3, 4, "y"], ["x", 5, 6, "y"], ["xx", 4, 8, "yy"], ["xx", 5, 9, "yy"]]
|
expected = Table.from_rows ["foo", "bar 1 1", "bar 2", "bar 1"] [["x", 1, 2, "y"], ["x", 3, 4, "y"], ["x", 5, 6, "y"], ["xx", 4, 8, "yy"], ["xx", 5, 9, "yy"]]
|
||||||
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "column and group name clash" <|
|
Test.specify "column and group name clash" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "123", "y"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "123", "y"]]
|
||||||
expected = Table.from_rows ["foo", "bar", "baz_1", "quux", "baz"] [["x", 1, 2, 3, "y"]]
|
expected = Table.from_rows ["foo", "bar", "baz 1", "quux", "baz"] [["x", 1, 2, 3, "y"]]
|
||||||
actual = t.parse_to_columns "bar" "(?<bar>\d)(?<baz>\d)(?<quux>\d)"
|
actual = t.parse_to_columns "bar" "(?<bar>\d)(?<baz>\d)(?<quux>\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
@ -280,13 +280,13 @@ spec =
|
|||||||
|
|
||||||
Test.specify "empty table, with regex groups" <|
|
Test.specify "empty table, with regex groups" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]] . take 0
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]] . take 0
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "baz"] [["x", "a", "a", "y"]] . take 0
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "baz"] [["x", "a", "a", "y"]] . take 0
|
||||||
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "empty table, with named and unnamed regex groups" <|
|
Test.specify "empty table, with named and unnamed regex groups" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]] . take 0
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]] . take 0
|
||||||
expected = Table.from_rows ["foo", "quux", "bar 0", "foo_1", "bar 1", "baz"] [["x", "a", "a", "a", "a", "y"]] . take 0
|
expected = Table.from_rows ["foo", "quux", "bar 1", "foo 1", "bar 2", "baz"] [["x", "a", "a", "a", "a", "y"]] . take 0
|
||||||
actual = t.parse_to_columns "bar" "(?<quux>)(\d)(?<foo>\d)(\d)"
|
actual = t.parse_to_columns "bar" "(?<quux>)(\d)(?<foo>\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
@ -298,13 +298,13 @@ spec =
|
|||||||
|
|
||||||
Test.specify "input with no matches, with regex groups" <|
|
Test.specify "input with no matches, with regex groups" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]]
|
||||||
expected = Table.from_rows ["foo", "bar 0", "bar 1", "baz"] []
|
expected = Table.from_rows ["foo", "bar 1", "bar 2", "baz"] []
|
||||||
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
actual = t.parse_to_columns "bar" "(\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
Test.specify "input with no matches, with named and unnamed regex groups" <|
|
Test.specify "input with no matches, with named and unnamed regex groups" <|
|
||||||
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]]
|
t = Table.from_rows ["foo", "bar", "baz"] [["x", "a", "y"]]
|
||||||
expected = Table.from_rows ["foo", "quux", "bar 0", "foo_1", "bar 1", "baz"] []
|
expected = Table.from_rows ["foo", "quux", "bar 1", "foo 1", "bar 2", "baz"] []
|
||||||
actual = t.parse_to_columns "bar" "(?<quux>)(\d)(?<foo>\d)(\d)"
|
actual = t.parse_to_columns "bar" "(?<quux>)(\d)(?<foo>\d)(\d)"
|
||||||
actual.should_equal expected
|
actual.should_equal expected
|
||||||
|
|
||||||
|
@ -541,7 +541,7 @@ spec =
|
|||||||
c_4 = ['Z', [True, False, True]]
|
c_4 = ['Z', [True, False, True]]
|
||||||
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
||||||
action = table.use_first_row_as_names on_problems=_
|
action = table.use_first_row_as_names on_problems=_
|
||||||
tester = expect_column_names ["Column_1", "1980-01-01", "1", "5.3", "True"]
|
tester = expect_column_names ["Column 1", "1980-01-01", "1", "5.3", "True"]
|
||||||
problems = [Invalid_Output_Column_Names.Error [""]]
|
problems = [Invalid_Output_Column_Names.Error [""]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -553,7 +553,7 @@ spec =
|
|||||||
c_4 = ['Z', [True, False, True]]
|
c_4 = ['Z', [True, False, True]]
|
||||||
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
||||||
action = table.use_first_row_as_names on_problems=_
|
action = table.use_first_row_as_names on_problems=_
|
||||||
tester = expect_column_names ["A", "1980-01-01", "Column_1", "5.3", "True"]
|
tester = expect_column_names ["A", "1980-01-01", "Column 1", "5.3", "True"]
|
||||||
problems = [Invalid_Output_Column_Names.Error [Nothing]]
|
problems = [Invalid_Output_Column_Names.Error [Nothing]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -565,7 +565,7 @@ spec =
|
|||||||
c_4 = ['Z', [True, False, True]]
|
c_4 = ['Z', [True, False, True]]
|
||||||
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
table = Table.new [c_0, c_1, c_2, c_3, c_4]
|
||||||
action = table.use_first_row_as_names on_problems=_
|
action = table.use_first_row_as_names on_problems=_
|
||||||
tester = expect_column_names ["Column_1", "1980-01-01", "Column_2", "5.3", "True"]
|
tester = expect_column_names ["Column 1", "1980-01-01", "Column 2", "5.3", "True"]
|
||||||
problems = [Invalid_Output_Column_Names.Error ["", Nothing]]
|
problems = [Invalid_Output_Column_Names.Error ["", Nothing]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
@ -576,7 +576,7 @@ spec =
|
|||||||
c_3 = ['C', ["A", "B", "C"]]
|
c_3 = ['C', ["A", "B", "C"]]
|
||||||
table = Table.new [c_0, c_1, c_2, c_3]
|
table = Table.new [c_0, c_1, c_2, c_3]
|
||||||
action = table.use_first_row_as_names on_problems=_
|
action = table.use_first_row_as_names on_problems=_
|
||||||
tester = expect_column_names ["A", "A_1", "A_2", "A_3"]
|
tester = expect_column_names ["A", "A 1", "A 2", "A 3"]
|
||||||
problems = [Duplicate_Output_Column_Names.Error ["A", "A", "A"]]
|
problems = [Duplicate_Output_Column_Names.Error ["A", "A", "A"]]
|
||||||
Problems.test_problem_handling action problems tester
|
Problems.test_problem_handling action problems tester
|
||||||
|
|
||||||
|
@ -4,27 +4,36 @@ from Standard.Table import Table, Column
|
|||||||
|
|
||||||
from Standard.Test import Test
|
from Standard.Test import Test
|
||||||
import Standard.Test.Extensions
|
import Standard.Test.Extensions
|
||||||
|
import Standard.Test.Test_Result.Test_Result
|
||||||
|
|
||||||
polyglot java import org.enso.base_test_helpers.FileSystemHelper
|
polyglot java import org.enso.base_test_helpers.FileSystemHelper
|
||||||
|
|
||||||
Table.should_equal self expected = case expected of
|
Table.should_equal : Any -> Integer -> Test_Result
|
||||||
_ : Table ->
|
Table.should_equal self expected frames_to_skip=0 =
|
||||||
tables_equal t0 t1 =
|
loc = Meta.get_source_location 1+frames_to_skip
|
||||||
same_headers = (t0.columns.map .name) == (t1.columns.map .name)
|
case expected of
|
||||||
same_columns = (t0.columns.map .to_vector) == (t1.columns.map .to_vector)
|
_ : Table ->
|
||||||
same_headers && same_columns
|
tables_equal t0 t1 =
|
||||||
equal = tables_equal self expected
|
same_headers = (t0.columns.map .name) == (t1.columns.map .name)
|
||||||
if equal.not then
|
same_columns = (t0.columns.map .to_vector) == (t1.columns.map .to_vector)
|
||||||
msg = 'Tables differ.\nActual:\n' + self.display + '\nExpected:\n' + expected.display
|
same_headers && same_columns
|
||||||
Test.fail msg
|
equal = tables_equal self expected
|
||||||
_ -> Test.fail "Got a Table, but expected a "+expected.to_display_text
|
if equal.not then
|
||||||
|
msg = 'Tables differ at '+loc+'.\nActual:\n' + self.display + '\nExpected:\n' + expected.display
|
||||||
|
Test.fail msg
|
||||||
|
_ -> Test.fail "Got a Table, but expected a "+expected.to_display_text+' (at '+loc+').'
|
||||||
|
|
||||||
Column.should_equal self expected =
|
Column.should_equal : Any -> Integer -> Test_Result
|
||||||
if self.name != expected.name then
|
Column.should_equal self expected frames_to_skip=0 =
|
||||||
Test.fail "Expected column name "+expected.name+", but got "+self.name+"."
|
loc = Meta.get_source_location 1+frames_to_skip
|
||||||
if self.length != expected.length then
|
case expected of
|
||||||
Test.fail "Expected column length "+expected.length.to_text+", but got "+self.length.to_text+"."
|
_ : Column ->
|
||||||
self.to_vector.should_equal expected.to_vector
|
if self.name != expected.name then
|
||||||
|
Test.fail "Expected column name "+expected.name+", but got "+self.name+" (at "+loc+")."
|
||||||
|
if self.length != expected.length then
|
||||||
|
Test.fail "Expected column length "+expected.length.to_text+", but got "+self.length.to_text+" (at "+loc+")."
|
||||||
|
self.to_vector.should_equal expected.to_vector
|
||||||
|
_ -> Test.fail "Got a Column, but expected a "+expected.to_display_text+' (at '+loc+').'
|
||||||
|
|
||||||
normalize_lines string line_separator=Line_Ending_Style.Unix.to_text newline_at_end=True =
|
normalize_lines string line_separator=Line_Ending_Style.Unix.to_text newline_at_end=True =
|
||||||
case newline_at_end of
|
case newline_at_end of
|
||||||
|
@ -229,6 +229,22 @@ spec_with name create_new_date parse_date =
|
|||||||
(create_new_date 2000 7 1).end_of Date_Period.Quarter . should_equal (Date.new 2000 9 30)
|
(create_new_date 2000 7 1).end_of Date_Period.Quarter . should_equal (Date.new 2000 9 30)
|
||||||
(create_new_date 2000 6 30).end_of Date_Period.Quarter . should_equal (Date.new 2000 6 30)
|
(create_new_date 2000 6 30).end_of Date_Period.Quarter . should_equal (Date.new 2000 6 30)
|
||||||
|
|
||||||
|
Test.specify "should allow to compute the number of days until a date" <|
|
||||||
|
create_new_date 2000 2 1 . days_until (create_new_date 2000 2 1) . should_equal 0
|
||||||
|
create_new_date 2000 2 1 . days_until (create_new_date 2000 2 2) . should_equal 1
|
||||||
|
create_new_date 2000 2 2 . days_until (create_new_date 2000 2 1) . should_equal -1
|
||||||
|
create_new_date 2001 3 1 . days_until (create_new_date 2001 4 1) . should_equal 31
|
||||||
|
create_new_date 2000 3 1 . days_until (create_new_date 2001 3 1) . should_equal 365
|
||||||
|
create_new_date 2001 3 1 . days_until (create_new_date 2000 3 1) . should_equal -365
|
||||||
|
|
||||||
|
Test.specify "should allow to compute the number of days until a date including the end date" <|
|
||||||
|
create_new_date 2000 2 1 . days_until (create_new_date 2000 2 1) include_end_date=True . should_equal 1
|
||||||
|
create_new_date 2000 2 1 . days_until (create_new_date 2000 2 2) include_end_date=True . should_equal 2
|
||||||
|
create_new_date 2000 2 2 . days_until (create_new_date 2000 2 1) include_end_date=True . should_equal -2
|
||||||
|
create_new_date 2001 3 1 . days_until (create_new_date 2001 4 1) include_end_date=True . should_equal 32
|
||||||
|
create_new_date 2000 3 1 . days_until (create_new_date 2001 3 1) include_end_date=True . should_equal 366
|
||||||
|
create_new_date 2001 3 1 . days_until (create_new_date 2000 3 1) include_end_date=True . should_equal -366
|
||||||
|
|
||||||
Test.specify "should allow to compute the number of working days until a later date" <|
|
Test.specify "should allow to compute the number of working days until a later date" <|
|
||||||
# 2000-2-1 is a Tuesday
|
# 2000-2-1 is a Tuesday
|
||||||
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 1) . should_equal 0
|
create_new_date 2000 2 1 . work_days_until (create_new_date 2000 2 1) . should_equal 0
|
||||||
|
@ -16,8 +16,8 @@ sample_table =
|
|||||||
col1 = ["foo", [123456789,23456789,987654321]]
|
col1 = ["foo", [123456789,23456789,987654321]]
|
||||||
col2 = ["bar", [4,5,6]]
|
col2 = ["bar", [4,5,6]]
|
||||||
col3 = ["Baz", [7,8,9]]
|
col3 = ["Baz", [7,8,9]]
|
||||||
col4 = ["foo_1", [10,11,12]]
|
col4 = ["foo 1", [10,11,12]]
|
||||||
col5 = ["foo_2", [13,14,15]]
|
col5 = ["foo 2", [13,14,15]]
|
||||||
col6 = ["ab.+123", [16,17,18]]
|
col6 = ["ab.+123", [16,17,18]]
|
||||||
col7 = ["abcd123", ["19",20, t1]]
|
col7 = ["abcd123", ["19",20, t1]]
|
||||||
Table.new [col1, col2, col3, col4, col5, col6, col7]
|
Table.new [col1, col2, col3, col4, col5, col6, col7]
|
||||||
|
Loading…
Reference in New Issue
Block a user