mirror of
https://github.com/enso-org/enso.git
synced 2024-11-26 08:52:58 +03:00
Improving widgets for take/drop (#6641)
Related to #6410 # Important Notes - Updated some `Meta` methods (needed for error handling): - `Meta.Type` now has `name` and `qualified_name`. - `Meta.Constructor` has `declaring_type` allowing to get the type that this constructor is associated with.
This commit is contained in:
parent
e62f97f26a
commit
f5071a17fd
@ -241,6 +241,7 @@ type Array
|
||||
If an `Index_Sub_Range`, then the selection is interpreted following
|
||||
the rules of that type.
|
||||
If a `Range`, the selection is specified by two indices, from and to.
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Vector Any
|
||||
take self range=(Index_Sub_Range.First 1) = Vector.take self range
|
||||
|
||||
@ -251,6 +252,7 @@ type Array
|
||||
If an `Index_Sub_Range`, then the selection is interpreted following
|
||||
the rules of that type.
|
||||
If a `Range`, the selection is specified by two indices, from and to.
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Vector Any
|
||||
drop self range=(Index_Sub_Range.First 1) = Vector.drop self range
|
||||
|
||||
|
@ -5,15 +5,22 @@ import project.Data.Range.Extensions
|
||||
import project.Data.Text.Text
|
||||
import project.Data.Vector.Vector
|
||||
import project.Errors.Common.Index_Out_Of_Bounds
|
||||
import project.Errors.Common.Type_Error
|
||||
import project.Error.Error
|
||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||
import project.Function.Function
|
||||
import project.Math
|
||||
import project.Meta
|
||||
import project.Panic.Panic
|
||||
import project.Random
|
||||
import project.Runtime.Ref.Ref
|
||||
|
||||
from project.Data.Boolean import Boolean, True, False
|
||||
|
||||
from project.Metadata.Widget import Single_Choice
|
||||
from project.Metadata.Choice import Option
|
||||
import project.Metadata.Display
|
||||
|
||||
type Index_Sub_Range
|
||||
## Select the first `count` items.
|
||||
|
||||
@ -40,7 +47,7 @@ type Index_Sub_Range
|
||||
Only ranges with positive step and positive indices are supported.
|
||||
Individual integer indices can be negative which allows for indexing
|
||||
from the end of the collection.
|
||||
By_Index (indexes : (Integer | Range | Vector (Integer | Range)) = [0])
|
||||
By_Index (indexes : (Integer | Range | Vector (Integer | Range)))
|
||||
|
||||
## Gets a random sample of entries, without repetitions.
|
||||
|
||||
@ -67,6 +74,26 @@ type Index_Sub_Range
|
||||
Index_Sub_Range.Sample count _ -> "Sample " + count.to_display_text
|
||||
Index_Sub_Range.Every step first -> "Every " + step.to_display_text + (if first == 0 then "" else " from " + first.to_display_text)
|
||||
|
||||
## PRIVATE
|
||||
It includes all constructors of `Index_Sub_Range` but also `Range`, since
|
||||
the `Index_Sub_Range` type is by default used in sum types containing
|
||||
`Range` too.
|
||||
default_options : Vector Option
|
||||
default_options =
|
||||
o1 = Option "First" "(Index_Sub_Range.First 1)"
|
||||
o2 = Option "Last" "(Index_Sub_Range.Last 1)"
|
||||
o3 = Option "While" "(Index_Sub_Range.While (x-> False))"
|
||||
o4 = Option "By_Index" "(Index_Sub_Range.By_Index [0])"
|
||||
o5 = Option "Sample" "(Index_Sub_Range.Sample 10)"
|
||||
o6 = Option "Every" "(Index_Sub_Range.Every 2)"
|
||||
o7 = Option "Range" "(Range.new 0 100)"
|
||||
[o1, o2, o3, o4, o5, o6, o7]
|
||||
|
||||
## PRIVATE
|
||||
default_widget : Single_Choice
|
||||
default_widget =
|
||||
Single_Choice display=Display.Always Index_Sub_Range.default_options
|
||||
|
||||
## PRIVATE
|
||||
Resolves a vector of ranges or indices into a vector of ranges that fit
|
||||
within a sequence.
|
||||
@ -169,9 +196,9 @@ sort_and_merge_ranges ranges =
|
||||
normalization on its own.
|
||||
- range: The `Index_Sub_Range` to take from the collection.
|
||||
take_helper : Integer -> (Integer -> Any) -> (Integer -> Integer -> Any) -> (Vector (Integer | Range) -> Vector Any) -> (Index_Sub_Range | Range | Integer) -> Any
|
||||
take_helper length at single_slice slice_ranges index_sub_range = case index_sub_range of
|
||||
take_helper length at single_slice slice_ranges range = case range of
|
||||
count : Integer -> take_helper length at single_slice slice_ranges (Index_Sub_Range.First count)
|
||||
_ : Range -> take_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index index_sub_range)
|
||||
_ : Range -> take_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index range)
|
||||
Index_Sub_Range.First count -> single_slice 0 (Math.min length count)
|
||||
Index_Sub_Range.Last count -> single_slice length-count length
|
||||
Index_Sub_Range.While predicate ->
|
||||
@ -193,6 +220,7 @@ take_helper length at single_slice slice_ranges index_sub_range = case index_sub
|
||||
if start >= length then single_slice 0 0 else
|
||||
range = start.up_to length . with_step step
|
||||
take_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index range)
|
||||
_ -> handle_unmatched_type [Index_Sub_Range, Range, Integer] range
|
||||
|
||||
## PRIVATE
|
||||
A helper that implements dropping from an arbitrary collection using a set of
|
||||
@ -219,9 +247,9 @@ take_helper length at single_slice slice_ranges index_sub_range = case index_sub
|
||||
normalized.
|
||||
- range: The `Index_Sub_Range` to drop from the collection.
|
||||
drop_helper : Integer -> (Integer -> Any) -> (Integer -> Integer -> Any) -> (Vector (Integer | Range) -> Vector Any) -> (Index_Sub_Range | Range | Integer) -> Any
|
||||
drop_helper length at single_slice slice_ranges index_sub_range = case index_sub_range of
|
||||
_ : Integer -> single_slice index_sub_range length
|
||||
_ : Range -> drop_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index index_sub_range)
|
||||
drop_helper length at single_slice slice_ranges range = case range of
|
||||
_ : Integer -> single_slice range length
|
||||
_ : Range -> drop_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index range)
|
||||
Index_Sub_Range.First count -> single_slice count length
|
||||
Index_Sub_Range.Last count -> single_slice 0 length-count
|
||||
Index_Sub_Range.While predicate ->
|
||||
@ -245,3 +273,21 @@ drop_helper length at single_slice slice_ranges index_sub_range = case index_sub
|
||||
if start >= length then single_slice 0 length else
|
||||
range = start.up_to length . with_step step
|
||||
drop_helper length at single_slice slice_ranges (Index_Sub_Range.By_Index range)
|
||||
_ -> handle_unmatched_type [Index_Sub_Range, Range, Integer] range
|
||||
|
||||
## PRIVATE
|
||||
handle_unmatched_type expected_types actual_value =
|
||||
m = Meta.meta actual_value
|
||||
return_type_error =
|
||||
expected_types_str = expected_types . map .to_text . join " | "
|
||||
Error.throw (Type_Error.Error expected_types_str actual_value "range")
|
||||
case m of
|
||||
_ : Meta.Constructor ->
|
||||
declaring_type = m.declaring_type
|
||||
is_expected_constructor = expected_types.map Meta.meta . contains declaring_type
|
||||
if is_expected_constructor.not then return_type_error else
|
||||
msg = "The constructor " + m.name + " is missing some arguments."
|
||||
Error.throw (Illegal_Argument.Error msg)
|
||||
_ -> case actual_value.is_a Function of
|
||||
True -> Error.throw (Illegal_Argument.Error "Got a Function instead of a range, is a constructor argument missing?")
|
||||
False -> return_type_error
|
||||
|
@ -939,6 +939,7 @@ Text.repeat self count=1 =
|
||||
"Hello World!".take (By_Index [1, 0, 0, 6, 0]) == "eHHWH"
|
||||
"Hello World!".take (By_Index [Range 0 3, 6, Range 6 12 2]) == "HelWWrd"
|
||||
"Hello World!".take (Sample 3 seed=42) == "l d"
|
||||
@range Text_Sub_Range.default_widget
|
||||
Text.take : (Text_Sub_Range | Index_Sub_Range | Range | Integer) -> Text ! Index_Out_Of_Bounds
|
||||
Text.take self range=(Index_Sub_Range.First 1) =
|
||||
ranges = Codepoint_Ranges.resolve self range
|
||||
@ -985,6 +986,7 @@ Text.take self range=(Index_Sub_Range.First 1) =
|
||||
"Hello World!".drop (By_Index [1, 0, 0, 6, 0]) == "llo orld!"
|
||||
"Hello World!".drop (By_Index [Range 0 3, 6, Range 6 12 2]) == "lo ol!"
|
||||
"Hello World!".drop (Sample 3 seed=42) == "HeloWorl!"
|
||||
@range Text_Sub_Range.default_widget
|
||||
Text.drop : (Text_Sub_Range | Index_Sub_Range | Range) -> Text ! Index_Out_Of_Bounds
|
||||
Text.drop self range=(Index_Sub_Range.First 1) =
|
||||
ranges = Codepoint_Ranges.resolve self range
|
||||
|
@ -6,6 +6,7 @@ import project.Data.Range.Range
|
||||
import project.Data.Text.Text
|
||||
import project.Data.Vector.Vector
|
||||
import project.Errors.Common.Index_Out_Of_Bounds
|
||||
import project.Errors.Common.Type_Error
|
||||
import project.Error.Error
|
||||
import project.Errors.Illegal_Argument.Illegal_Argument
|
||||
import project.Nothing.Nothing
|
||||
@ -16,6 +17,11 @@ from project.Data.Boolean import Boolean, True, False
|
||||
|
||||
import project.Data.Index_Sub_Range as Index_Sub_Range_Module
|
||||
import project.Data.Text.Span as Span_Module
|
||||
from project.Data.Index_Sub_Range import handle_unmatched_type
|
||||
|
||||
from project.Metadata.Widget import Single_Choice
|
||||
from project.Metadata.Choice import Option
|
||||
import project.Metadata.Display
|
||||
|
||||
polyglot java import com.ibm.icu.text.BreakIterator
|
||||
polyglot java import org.enso.base.Text_Utils
|
||||
@ -41,13 +47,31 @@ type Text_Sub_Range
|
||||
After_Last (delimiter : Text)
|
||||
|
||||
## PRIVATE
|
||||
Convert to a display representation of this Index_Sub_Range.
|
||||
Convert to a display representation of this `Text_Sub_Range`.
|
||||
to_display_text : Text
|
||||
to_display_text self = case self of
|
||||
Text_Sub_Range.Before delimiter -> "Before " + delimiter.to_display_text
|
||||
Text_Sub_Range.Before_Last delimiter -> "Before Last " + delimiter.to_display_text
|
||||
Text_Sub_Range.After delimiter -> "After " + delimiter.to_display_text
|
||||
Text_Sub_Range.After_Last delimiter -> "After Last " + delimiter.to_display_text
|
||||
Text_Sub_Range.Before delimiter -> "Before " + delimiter.pretty
|
||||
Text_Sub_Range.Before_Last delimiter -> "Before Last " + delimiter.pretty
|
||||
Text_Sub_Range.After delimiter -> "After " + delimiter.pretty
|
||||
Text_Sub_Range.After_Last delimiter -> "After Last " + delimiter.pretty
|
||||
|
||||
## PRIVATE
|
||||
default_options : Vector Option
|
||||
default_options =
|
||||
o1 = Option "Before" "(Text_Sub_Range.Before ' ')"
|
||||
o2 = Option "Before_Last" "(Text_Sub_Range.Before_Last ' ')"
|
||||
o3 = Option "After" "(Text_Sub_Range.After ' ')"
|
||||
o4 = Option "After_Last" "(Text_Sub_Range.After_Last ' ')"
|
||||
[o1, o2, o3, o4]
|
||||
|
||||
## PRIVATE
|
||||
The widget for `Text_Sub_Range` also displays options for
|
||||
`Index_Sub_Range` since the former is supposed to 'expand' the latter and
|
||||
is always used together with it.
|
||||
default_widget : Single_Choice
|
||||
default_widget =
|
||||
options = Index_Sub_Range.default_options + Text_Sub_Range.default_options
|
||||
Single_Choice display=Display.Always options
|
||||
|
||||
type Codepoint_Ranges
|
||||
## PRIVATE
|
||||
@ -64,7 +88,7 @@ type Codepoint_Ranges
|
||||
Returns a new sorted list of ranges where intersecting ranges have been
|
||||
merged.
|
||||
|
||||
Empty subranges are not discarded.
|
||||
Empty ranges are not discarded.
|
||||
sorted_and_distinct_ranges : Vector Range
|
||||
sorted_and_distinct_ranges self = if self.is_sorted_and_distinct then self.ranges else
|
||||
Index_Sub_Range_Module.sort_and_merge_ranges self.ranges
|
||||
@ -80,8 +104,8 @@ type Codepoint_Ranges
|
||||
in such a way that the ranges returned by this method always have a step
|
||||
equal to 1.
|
||||
resolve : Text -> (Text_Sub_Range | Index_Sub_Range | Range | Integer) -> (Range | Codepoint_Ranges)
|
||||
resolve text subrange =
|
||||
case subrange of
|
||||
resolve text range =
|
||||
case range of
|
||||
Text_Sub_Range.Before delimiter ->
|
||||
if delimiter.is_empty then (0.up_to 0) else
|
||||
span = Text_Utils.span_of text delimiter
|
||||
@ -134,12 +158,14 @@ type Codepoint_Ranges
|
||||
if step <= 0 then Error.throw (Illegal_Argument.Error "Step within Every must be positive.") else
|
||||
len = text.length
|
||||
if start >= len then 0.up_to 0 else
|
||||
range = start.up_to text.length . with_step step
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.By_Index range)
|
||||
simple_range = start.up_to text.length . with_step step
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.By_Index simple_range)
|
||||
_ : Range ->
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.By_Index subrange)
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.By_Index range)
|
||||
_ : Integer ->
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.First subrange)
|
||||
Codepoint_Ranges.resolve text (Index_Sub_Range.First range)
|
||||
_ -> handle_unmatched_type [Text_Sub_Range, Index_Sub_Range, Range, Integer] range
|
||||
|
||||
|
||||
## PRIVATE
|
||||
Utility function to find char indices for Text_Sub_Range.
|
||||
|
@ -758,6 +758,7 @@ type Vector a
|
||||
If an `Index_Sub_Range`, then the selection is interpreted following
|
||||
the rules of that type.
|
||||
If a `Range`, the selection is specified by two indices, from and to.
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Vector Any
|
||||
take self range=(Index_Sub_Range.First 1) = case range of
|
||||
## We are using a specialized implementation for `take Sample`, because
|
||||
@ -777,6 +778,7 @@ type Vector a
|
||||
If an `Index_Sub_Range`, then the selection is interpreted following
|
||||
the rules of that type.
|
||||
If a `Range`, the selection is specified by two indices, from and to.
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Vector Any
|
||||
drop self range=(Index_Sub_Range.First 1) =
|
||||
drop_helper self.length (self.at _) self.slice (slice_ranges self) range
|
||||
|
@ -44,10 +44,18 @@ type Type
|
||||
## ADVANCED
|
||||
|
||||
Returns the fully qualified name of the type.
|
||||
qualified_name : Text
|
||||
qualified_name self =
|
||||
c = self.value
|
||||
get_qualified_type_name c
|
||||
|
||||
## ADVANCED
|
||||
|
||||
Returns the short name of the type.
|
||||
name : Text
|
||||
name self =
|
||||
c = self.value ...
|
||||
get_constructor_name c
|
||||
c = self.value
|
||||
get_short_type_name c
|
||||
|
||||
type Atom
|
||||
## PRIVATE
|
||||
@ -111,6 +119,13 @@ type Constructor
|
||||
ctor = self.value ...
|
||||
new_atom ctor fields.to_array
|
||||
|
||||
## ADVANCED
|
||||
Returns the type that this constructor is a part of.
|
||||
declaring_type : Type
|
||||
declaring_type self =
|
||||
c = self.value ...
|
||||
Type.Value (get_constructor_declaring_type c)
|
||||
|
||||
type Primitive
|
||||
## PRIVATE
|
||||
ADVANCED
|
||||
@ -504,3 +519,19 @@ get_simple_type_name value = @Builtin_Method "Meta.get_simple_type_name"
|
||||
- value: the value to get the type of.
|
||||
get_qualified_type_name : Any -> Text
|
||||
get_qualified_type_name value = @Builtin_Method "Meta.get_qualified_type_name"
|
||||
|
||||
## PRIVATE
|
||||
Returns a short name of a type (the last part of its qualified name).
|
||||
|
||||
Arguments:
|
||||
- typ: the type to get the short name of.
|
||||
get_short_type_name : Any -> Text
|
||||
get_short_type_name typ = @Builtin_Method "Meta.get_short_type_name"
|
||||
|
||||
## PRIVATE
|
||||
Returns the type that this constructor is a part of.
|
||||
|
||||
Arguments:
|
||||
- constructor: the constructor to get the declaring type of.
|
||||
get_constructor_declaring_type : Any -> Any
|
||||
get_constructor_declaring_type constructor = @Builtin_Method "Meta.get_constructor_declaring_type"
|
||||
|
@ -749,6 +749,7 @@ type Column
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to return.
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Column
|
||||
take self range=(First 1) =
|
||||
_ = range
|
||||
@ -761,6 +762,7 @@ type Column
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to remove.
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Column
|
||||
drop self range=(First 1) =
|
||||
_ = range
|
||||
|
@ -522,6 +522,7 @@ type Table
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to return.
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Table
|
||||
take self range=(First 1) =
|
||||
_ = range
|
||||
@ -535,6 +536,7 @@ type Table
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to remove.
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Table
|
||||
drop self range=(First 1) =
|
||||
_ = range
|
||||
|
@ -1547,6 +1547,7 @@ type Column
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to return.
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Column
|
||||
take self range=(First 1) =
|
||||
Index_Sub_Range_Module.take_helper self.length self.at self.slice (slice_ranges self) range
|
||||
@ -1556,6 +1557,7 @@ type Column
|
||||
|
||||
Arguments:
|
||||
- range: The selection of rows from the table to remove.
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Column
|
||||
drop self range=(First 1) =
|
||||
Index_Sub_Range_Module.drop_helper self.length self.at self.slice (slice_ranges self) range
|
||||
|
@ -1148,6 +1148,7 @@ type Table
|
||||
Take rows from the top of the table as long as their values sum to 10.
|
||||
|
||||
table.take (While row-> row.to_vector.compute Statistic.Sum == 10)
|
||||
@range Index_Sub_Range.default_widget
|
||||
take : (Index_Sub_Range | Range | Integer) -> Table
|
||||
take self range=(First 1) =
|
||||
Index_Sub_Range_Module.take_helper self.row_count self.rows.at self.slice (slice_ranges self) range
|
||||
@ -1170,6 +1171,7 @@ type Table
|
||||
Drop rows from the top of the table as long as their values sum to 10.
|
||||
|
||||
table.drop (While row-> row.to_vector.compute Statistic.Sum == 10)
|
||||
@range Index_Sub_Range.default_widget
|
||||
drop : (Index_Sub_Range | Range | Integer) -> Table
|
||||
drop self range=(First 1) =
|
||||
Index_Sub_Range_Module.drop_helper self.row_count self.rows.at self.slice (slice_ranges self) range
|
||||
|
@ -0,0 +1,17 @@
|
||||
package org.enso.interpreter.node.expression.builtin.meta;
|
||||
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.data.Type;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_constructor_declaring_type",
|
||||
description = "Gets the type that declared this constructor.",
|
||||
autoRegister = false)
|
||||
public class GetConstructorDeclaringTypeNode extends Node {
|
||||
Type execute(AtomConstructor cons) {
|
||||
return cons.getType();
|
||||
}
|
||||
}
|
@ -12,20 +12,8 @@ import org.enso.interpreter.runtime.data.text.Text;
|
||||
name = "get_constructor_name",
|
||||
description = "Gets the name of a constructor.",
|
||||
autoRegister = false)
|
||||
public abstract class GetConstructorNameNode extends Node {
|
||||
static GetConstructorNameNode build() {
|
||||
return GetConstructorNameNodeGen.create();
|
||||
}
|
||||
|
||||
abstract Text execute(Object atom_constructor);
|
||||
|
||||
@Specialization
|
||||
Text doConstructor(AtomConstructor cons) {
|
||||
public class GetConstructorNameNode extends Node {
|
||||
Text execute(AtomConstructor cons) {
|
||||
return Text.create(cons.getName());
|
||||
}
|
||||
|
||||
@Specialization
|
||||
Text doType(Type type) {
|
||||
return Text.create(type.getQualifiedName().toString());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package org.enso.interpreter.node.expression.builtin.meta;
|
||||
|
||||
import com.oracle.truffle.api.dsl.Specialization;
|
||||
import com.oracle.truffle.api.nodes.Node;
|
||||
import org.enso.interpreter.dsl.BuiltinMethod;
|
||||
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
|
||||
import org.enso.interpreter.runtime.data.Type;
|
||||
import org.enso.interpreter.runtime.data.text.Text;
|
||||
|
||||
@BuiltinMethod(
|
||||
type = "Meta",
|
||||
name = "get_short_type_name",
|
||||
description = "Gets the short name of a Type.",
|
||||
autoRegister = false)
|
||||
public class GetShortTypeNameNode extends Node {
|
||||
Text execute(Type type) {
|
||||
return Text.create(type.getName());
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
from Standard.Base import all
|
||||
from Standard.Base.Data.Index_Sub_Range.Index_Sub_Range import While, Sample, Every
|
||||
import Standard.Base.Errors.Common.Index_Out_Of_Bounds
|
||||
import Standard.Base.Errors.Common.Type_Error
|
||||
import Standard.Base.Errors.Illegal_Argument.Illegal_Argument
|
||||
|
||||
from Standard.Table.Errors import all
|
||||
@ -151,8 +152,30 @@ spec setup =
|
||||
rnd.at "alpha" . to_vector . should_equal alpha_sample
|
||||
rnd.at "beta" . to_vector . should_equal beta_sample
|
||||
|
||||
Test.specify "should allow selecting rows as long as they satisfy a predicate" pending="While is not implemented for Table until the Row type is implemented." <|
|
||||
Nothing
|
||||
Test.specify "should allow selecting rows as long as they satisfy a predicate" <|
|
||||
t = table_builder [["a", [1, 2, 3, 4]], ["b", [5, 6, 7, 8]]]
|
||||
|
||||
t2 = t.take (While (row -> row.at "a" < 3))
|
||||
t2.row_count . should_equal 2
|
||||
t2.at "a" . to_vector . should_equal [1, 2]
|
||||
t2.at "b" . to_vector . should_equal [5, 6]
|
||||
|
||||
Test.specify "should gracefully handle missing constructor arguments" <|
|
||||
t = table_builder [["X", [1, 2, 3]]]
|
||||
t.take "FOO" . should_fail_with Type_Error
|
||||
t.drop "FOO" . should_fail_with Type_Error
|
||||
|
||||
r1 = t.take (Index_Sub_Range.While)
|
||||
r1.should_fail_with Illegal_Argument
|
||||
r1.catch.to_display_text . should_contain "The constructor While is missing some arguments"
|
||||
|
||||
r2 = t.drop (Index_Sub_Range.Every ...)
|
||||
r2.should_fail_with Illegal_Argument
|
||||
r2.catch.to_display_text . should_contain "The constructor Every is missing some arguments"
|
||||
|
||||
r3 = t.take (Index_Sub_Range.First _)
|
||||
r3.should_fail_with Illegal_Argument
|
||||
r3.catch.to_display_text . should_contain "Got a Function instead of a range, is a constructor argument missing?"
|
||||
|
||||
Test.group prefix+"Column.take/drop" pending=take_drop_by_pending <|
|
||||
table =
|
||||
@ -310,3 +333,20 @@ spec setup =
|
||||
|
||||
three.drop (While (_ > 10)) . should_equal three
|
||||
three.drop (While (_ < 10)) . should_equal empty
|
||||
|
||||
Test.specify "should gracefully handle missing constructor arguments" <|
|
||||
c = table_builder [["X", [1, 2, 3]]] . at "X"
|
||||
c.take "FOO" . should_fail_with Type_Error
|
||||
c.drop "FOO" . should_fail_with Type_Error
|
||||
|
||||
r1 = c.take (Index_Sub_Range.While)
|
||||
r1.should_fail_with Illegal_Argument
|
||||
r1.catch.to_display_text . should_contain "The constructor While is missing some arguments"
|
||||
|
||||
r2 = c.drop (Index_Sub_Range.Every ...)
|
||||
r2.should_fail_with Illegal_Argument
|
||||
r2.catch.to_display_text . should_contain "The constructor Every is missing some arguments"
|
||||
|
||||
r3 = c.take (Index_Sub_Range.First _)
|
||||
r3.should_fail_with Illegal_Argument
|
||||
r3.catch.to_display_text . should_contain "Got a Function instead of a range, is a constructor argument missing?"
|
||||
|
@ -736,6 +736,25 @@ spec =
|
||||
"".drop (Sample 0) . should_equal ""
|
||||
"".drop (Sample 100) . should_equal ""
|
||||
|
||||
Test.specify "take and drop should gracefully handle missing constructor arguments" <|
|
||||
"".take "FOO" . should_fail_with Type_Error
|
||||
"".drop "FOO" . should_fail_with Type_Error
|
||||
|
||||
r1 = "".take (Index_Sub_Range.While)
|
||||
r1.should_fail_with Illegal_Argument
|
||||
r1.catch.to_display_text . should_contain "The constructor While is missing some arguments"
|
||||
|
||||
r2 = "".drop (Text_Sub_Range.Before ...)
|
||||
r2.should_fail_with Illegal_Argument
|
||||
r2.catch.to_display_text . should_contain "The constructor Before is missing some arguments"
|
||||
|
||||
r3 = "".take (Index_Sub_Range.First _)
|
||||
r3.should_fail_with Illegal_Argument
|
||||
r3.catch.to_display_text . should_contain "Got a Function instead of a range, is a constructor argument missing?"
|
||||
|
||||
# Double-check that constructors of _unexpected_ types are still yielding a type error.
|
||||
"".take (Case_Sensitivity.Insensitive ...) . should_fail_with Type_Error
|
||||
|
||||
Test.specify "should correctly convert character case" <|
|
||||
"FooBar Baz".to_case Case.Lower . should_equal "foobar baz"
|
||||
"FooBar Baz".to_case Case.Upper . should_equal "FOOBAR BAZ"
|
||||
|
@ -413,7 +413,7 @@ type_spec name alter = Test.group name <|
|
||||
vec.slice 1 1 . should_equal []
|
||||
vec.slice 0 100 . should_equal [1, 2, 3, 4, 5, 6]
|
||||
Meta.is_same_object vec (vec.slice 0 100) . should_be_true
|
||||
Meta.meta Vector . name . should_equal (Meta.get_qualified_type_name (vec.slice 1 1))
|
||||
Meta.get_qualified_type_name (vec.slice 1 1) . should_equal (Meta.meta Vector . qualified_name)
|
||||
|
||||
Test.specify "should define take and drop family of operations" <|
|
||||
vec = alter [1, 2, 3, 4, 5, 6]
|
||||
@ -536,6 +536,22 @@ type_spec name alter = Test.group name <|
|
||||
alter ["a", "a", "a"] . drop (Sample 1) . should_equal ["a", "a"]
|
||||
alter ["a", "a", "a"] . drop (Sample 100) . should_equal []
|
||||
|
||||
Test.specify "take/drop should gracefully handle missing constructor arguments" <|
|
||||
[].take "FOO" . should_fail_with Type_Error
|
||||
[].drop "FOO" . should_fail_with Type_Error
|
||||
|
||||
r1 = [].take (Index_Sub_Range.While)
|
||||
r1.should_fail_with Illegal_Argument
|
||||
r1.catch.to_display_text . should_contain "The constructor While is missing some arguments"
|
||||
|
||||
r2 = [].drop (Index_Sub_Range.Every ...)
|
||||
r2.should_fail_with Illegal_Argument
|
||||
r2.catch.to_display_text . should_contain "The constructor Every is missing some arguments"
|
||||
|
||||
r3 = [].take (Index_Sub_Range.First _)
|
||||
r3.should_fail_with Illegal_Argument
|
||||
r3.catch.to_display_text . should_contain "Got a Function instead of a range, is a constructor argument missing?"
|
||||
|
||||
Test.specify "should allow getting the last element of the vector" <|
|
||||
non_empty_vec = alter [1, 2, 3, 4, 5]
|
||||
singleton_vec = alter [1]
|
||||
@ -763,5 +779,10 @@ spec =
|
||||
arr
|
||||
type_spec "Use Array_Proxy as vectors" v->
|
||||
Array_Proxy.new v.length (ix -> v.at ix)
|
||||
type_spec "Use a slice of an array as vectors" v->
|
||||
v2 = v+[Nothing]
|
||||
sliced_vector = v2.slice 0 v.length
|
||||
sliced_array = sliced_vector.to_array
|
||||
sliced_array
|
||||
|
||||
main = Test_Suite.run_main spec
|
||||
|
@ -207,6 +207,7 @@ spec =
|
||||
Meta.is_atom typ . should_be_false
|
||||
meta_typ = Meta.meta typ
|
||||
meta_typ . should_be_a Meta.Type
|
||||
meta_typ.name . should_equal "Boolean"
|
||||
cons = case meta_typ of
|
||||
Meta.Type.Value _ -> meta_typ.constructors
|
||||
_ -> Test.fail "Should be a Meta.Type.Value: " + meta_typ.to_text
|
||||
@ -222,6 +223,7 @@ spec =
|
||||
Meta.is_atom typ . should_be_false
|
||||
meta_typ = Meta.meta typ
|
||||
meta_typ . should_be_a Meta.Type
|
||||
meta_typ.name . should_equal "My_Type"
|
||||
cons = case meta_typ of
|
||||
Meta.Type.Value _ -> meta_typ.constructors
|
||||
_ -> Test.fail "Should be a Meta.Type.Value: " + meta_typ.to_text
|
||||
@ -229,6 +231,8 @@ spec =
|
||||
cons.length . should_equal 1
|
||||
cons.at 0 . should_be_a Meta.Constructor
|
||||
cons . map (x -> x.name) . sort . should_equal [ "Value" ]
|
||||
cons.each ctor->
|
||||
ctor.declaring_type . should_equal meta_typ
|
||||
|
||||
Test.specify "methods of MyType" <|
|
||||
typ = My_Type
|
||||
|
35
test/Visualization_Tests/src/Widgets/Text_Widgets_Spec.enso
Normal file
35
test/Visualization_Tests/src/Widgets/Text_Widgets_Spec.enso
Normal file
@ -0,0 +1,35 @@
|
||||
from Standard.Base import all
|
||||
import Standard.Base.Runtime.State
|
||||
|
||||
import Standard.Base.Metadata.Choice
|
||||
import Standard.Base.Metadata.Widget
|
||||
import Standard.Base.Metadata.Display
|
||||
|
||||
import Standard.Visualization.Widgets
|
||||
|
||||
from Standard.Test import Test, Test_Suite
|
||||
import Standard.Test.Extensions
|
||||
|
||||
spec =
|
||||
Test.group "Widgets for the Text type" <|
|
||||
Test.specify "works for `take` and `drop`" <|
|
||||
mock_text = "abc def"
|
||||
default_widget = Text_Sub_Range.default_widget
|
||||
expect = [["range", default_widget]] . to_json
|
||||
json = Widgets.get_widget_json mock_text "take" ["range"]
|
||||
json . should_equal expect
|
||||
Widgets.get_widget_json mock_text "drop" ["range"] . should_equal expect
|
||||
obj = json.parse_json
|
||||
widget = obj.first.second
|
||||
options = widget . at "values"
|
||||
options.each o-> Test.with_clue o.to_text+": " <|
|
||||
o.should_be_a JS_Object
|
||||
labels = options.map o->
|
||||
o.at "label"
|
||||
labels.should_be_a Vector
|
||||
labels.should_contain "First"
|
||||
labels.should_contain "While"
|
||||
labels.should_contain "After"
|
||||
labels.should_contain "Before_Last"
|
||||
|
||||
main = Test_Suite.run_main spec
|
@ -4,9 +4,11 @@ from Standard.Test import Test_Suite
|
||||
|
||||
import project.Widgets.Database_Widgets_Spec
|
||||
import project.Widgets.Table_Widgets_Spec
|
||||
import project.Widgets.Text_Widgets_Spec
|
||||
|
||||
spec =
|
||||
Table_Widgets_Spec.spec
|
||||
Database_Widgets_Spec.spec
|
||||
Text_Widgets_Spec.spec
|
||||
|
||||
main = Test_Suite.run_main spec
|
||||
|
Loading…
Reference in New Issue
Block a user