mirror of
https://github.com/enso-org/enso.git
synced 2024-11-23 08:08:34 +03:00
Remove Array.set_at
(#3634)
Implements https://www.pivotaltracker.com/story/show/182879865 # Important Notes Note that removing `set_at` still does not make our arrays fully immutable - `Array.copy` can still be used to mutate them.
This commit is contained in:
parent
14c516aff3
commit
fd318cfa96
@ -184,6 +184,7 @@
|
||||
- [Short-hand syntax for `order_by` added.][3643]
|
||||
- [Expanded `Table.at` to support index access and added `Table.column_count`
|
||||
method.][3644]
|
||||
- [Removed `Array.set_at`.][3634]
|
||||
|
||||
[debug-shortcuts]:
|
||||
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
|
||||
@ -290,6 +291,7 @@
|
||||
[3644]: https://github.com/enso-org/enso/pull/3644
|
||||
[3648]: https://github.com/enso-org/enso/pull/3648
|
||||
[5250]: https://github.com/enso-org/enso/pull/5250
|
||||
[3634]: https://github.com/enso-org/enso/pull/3634
|
||||
|
||||
#### Enso Compiler
|
||||
|
||||
@ -370,7 +372,7 @@
|
||||
[3631]: https://github.com/enso-org/enso/pull/3631
|
||||
[3633]: https://github.com/enso-org/enso/pull/3633
|
||||
[3637]: https://github.com/enso-org/enso/pull/3637
|
||||
[3633]: https://github.com/enso-org/enso/pull/3641
|
||||
[3641]: https://github.com/enso-org/enso/pull/3641
|
||||
[3658]: https://github.com/enso-org/enso/pull/3658
|
||||
|
||||
# Enso 2.0.0-alpha.18 (2021-10-12)
|
||||
|
@ -23,22 +23,6 @@ type Array
|
||||
at : Integer -> Any
|
||||
at self index = @Builtin_Method "Array.at"
|
||||
|
||||
## Set the cell at the specified index to the provided value, returning
|
||||
the array.
|
||||
|
||||
Arguments:
|
||||
- index: The position in the array to set.
|
||||
- value: The value to set at position index.
|
||||
|
||||
The array is mutated in place, and only returned to facilitate a natural
|
||||
programming style in Enso.
|
||||
|
||||
? Safety
|
||||
If index < 0 or index >= self.length, then this operation will result
|
||||
in an Invalid_Array_Index_Error exception.
|
||||
set_at : Integer -> Any -> Array
|
||||
set_at self index value = @Builtin_Method "Array.set_at"
|
||||
|
||||
## Gets the length of the array this.
|
||||
|
||||
> Example
|
||||
|
@ -5,6 +5,10 @@ from Standard.Base.Data.Index_Sub_Range import While, By_Index, Sample, Every
|
||||
import Standard.Base.Polyglot.Proxy_Polyglot_Array
|
||||
import Standard.Base.Random
|
||||
|
||||
polyglot java import java.util.ArrayList
|
||||
polyglot java import java.lang.IndexOutOfBoundsException
|
||||
polyglot java import org.enso.base.Array_Utils
|
||||
|
||||
## Creates a new vector of the given length, initializing elements using
|
||||
the provided constructor function.
|
||||
|
||||
@ -26,9 +30,9 @@ import Standard.Base.Random
|
||||
Vector.new my_vec.length (ix -> my_vec.at ix)
|
||||
new : Number -> (Number -> Any) -> Vector Any
|
||||
new length constructor =
|
||||
arr = Array.new length
|
||||
0.up_to length . each ix-> arr.set_at ix (constructor ix)
|
||||
Vector arr
|
||||
builder = (0.up_to length).fold (new_builder length) builder-> ix->
|
||||
builder.append (constructor ix)
|
||||
builder.to_vector
|
||||
|
||||
## Creates a new vector of the given length, filling the elements with
|
||||
the provided constant.
|
||||
@ -46,9 +50,9 @@ new length constructor =
|
||||
Vector.fill length=50 item=42
|
||||
fill : Number -> Any -> Vector Any
|
||||
fill length ~item =
|
||||
arr = Array.new length
|
||||
0.up_to length . each ix-> arr.set_at ix item
|
||||
Vector arr
|
||||
builder = (0.up_to length).fold (new_builder length) builder-> _->
|
||||
builder.append item
|
||||
builder.to_vector
|
||||
|
||||
## Creates a new vector builder instance.
|
||||
|
||||
@ -63,18 +67,18 @@ fill length ~item =
|
||||
- capacity: Initial capacity of the Vector.Builder
|
||||
|
||||
> Example
|
||||
Construct a vector using a builder that contains the items 1 to 10.
|
||||
Construct a vector using a builder that contains the items 1 to 5.
|
||||
|
||||
example_new_builder =
|
||||
builder = Vector.new_builder 10
|
||||
builder = Vector.new_builder 5
|
||||
do_build start stop =
|
||||
builder.append start
|
||||
if start >= stop then Nothing else
|
||||
@Tail_Call do_build start+1 stop
|
||||
do_build 1 10
|
||||
do_build 1 5
|
||||
builder.to_vector
|
||||
new_builder : Integer -> Builder
|
||||
new_builder (capacity=1) = Builder.new capacity
|
||||
new_builder (capacity=10) = Builder.new capacity
|
||||
|
||||
## ADVANCED
|
||||
|
||||
@ -113,12 +117,12 @@ type Vector
|
||||
Vector.fill length=50 item=42
|
||||
type Vector storage
|
||||
|
||||
## PRIVATE
|
||||
to_array self =
|
||||
arr = self.storage.to_array
|
||||
case arr of
|
||||
Array ->
|
||||
arr
|
||||
_ ->
|
||||
case Meta.meta arr of
|
||||
Meta.Primitive _ -> arr
|
||||
_ ->
|
||||
len = self.storage.length
|
||||
a = Array.new len
|
||||
Array.copy arr 0 a 0 len
|
||||
@ -986,8 +990,7 @@ type Builder
|
||||
A builder type for Enso vectors.
|
||||
|
||||
Arguments:
|
||||
- to_array: The accumulator for the new vector.
|
||||
- length: The current length of the vector being built.
|
||||
- java_builder: The accumulator for the new vector.
|
||||
|
||||
A vector builder is a mutable data structure, that allows to gather a
|
||||
number of elements and then convert them to a vector. This is
|
||||
@ -1007,7 +1010,14 @@ type Builder
|
||||
@Tail_Call do_build new_builder start+1 stop
|
||||
builder = do_build Vector.new_builder 1 10
|
||||
builder.to_vector
|
||||
type Builder to_array length
|
||||
|
||||
! TODO
|
||||
We may want to revisit the fold pattern - it is required for correct
|
||||
propagation of dataflow errors, but it is very easy to forget about it
|
||||
and get wrong error propagation. Instead we may want to have a `Ref`
|
||||
inside of the Builder. Any error detected during `append` could set
|
||||
that `Ref` and then `to_vector` could propagate that error.
|
||||
type Builder java_builder
|
||||
|
||||
## Creates a new builder.
|
||||
|
||||
@ -1019,21 +1029,11 @@ type Builder
|
||||
|
||||
Vector.new_builder
|
||||
new : Integer->Builder
|
||||
new (capacity=1) = Builder (Array.new capacity) 0
|
||||
|
||||
## Returns the current capacity (i.e. the size of the underlying storage)
|
||||
of this builder.
|
||||
|
||||
> Example
|
||||
Get the capacity of a new builder.
|
||||
|
||||
Vector.new_builder.capacity
|
||||
capacity : Integer
|
||||
capacity self = self.to_array.length
|
||||
new (capacity=10) = Builder (ArrayList.new capacity)
|
||||
|
||||
## Checks if this builder is empty.
|
||||
is_empty : Boolean
|
||||
is_empty self = self.length == 0
|
||||
is_empty self = self.java_builder.isEmpty
|
||||
|
||||
## Checks if this builder is not empty.
|
||||
not_empty : Boolean
|
||||
@ -1056,6 +1056,27 @@ type Builder
|
||||
self.unsafe_append item
|
||||
self
|
||||
|
||||
## Appends a part of a given vector to this builder
|
||||
|
||||
Arguments:
|
||||
- vector: The vector from which the elements are sourced.
|
||||
- start: The start index of the range to append.
|
||||
- end: The end index (the first index after the last element to be
|
||||
appended) of the range to be appended.
|
||||
|
||||
> Example
|
||||
Append a part of the vector.
|
||||
|
||||
builder = Vector.new_builder
|
||||
builder . append_vector_range [20, 30, 40, 50] 1 3 . to_vector == [30, 40]
|
||||
append_vector_range : Vector Any ! Error -> Builder ! Error
|
||||
append_vector_range self vector start end =
|
||||
subrange = vector.slice start end
|
||||
## This workaround is needed because
|
||||
`self.java_builder.addAll subrange.to_array` fails with
|
||||
`Unsupported argument types: [Array]`.
|
||||
Array_Utils.appendToArrayList self.java_builder subrange.to_array
|
||||
|
||||
## PRIVATE
|
||||
Appends a new element into this builder.
|
||||
|
||||
@ -1075,17 +1096,7 @@ type Builder
|
||||
|
||||
Vector.new_builder.unsafe_append 10
|
||||
unsafe_append : Any -> Nothing
|
||||
unsafe_append self item = case self.capacity > self.length of
|
||||
True ->
|
||||
self.to_array.set_at self.length item
|
||||
Unsafe.set_atom_field self 1 (self.length + 1)
|
||||
False ->
|
||||
old_array = self.to_array
|
||||
new_array = Array.new old_array.length*2
|
||||
Array.copy old_array 0 new_array 0 old_array.length
|
||||
Unsafe.set_atom_field self 0 new_array
|
||||
self.append item
|
||||
Nothing
|
||||
unsafe_append self item = self.java_builder.add item
|
||||
|
||||
## Gets an element from the vector at a specified index (0-based).
|
||||
|
||||
@ -1096,7 +1107,7 @@ type Builder
|
||||
at : Integer -> Any ! Index_Out_Of_Bounds_Error
|
||||
at self index =
|
||||
actual_index = if index < 0 then self.length + index else index
|
||||
Panic.catch Invalid_Array_Index_Error (self.to_array.at actual_index) _->
|
||||
Panic.catch IndexOutOfBoundsException (self.java_builder.get actual_index) _->
|
||||
Error.throw (Index_Out_Of_Bounds_Error index self.length)
|
||||
|
||||
## Checks whether a predicate holds for at least one element of this builder.
|
||||
@ -1107,7 +1118,7 @@ type Builder
|
||||
|
||||
exists : (Any -> Boolean) -> Boolean
|
||||
exists self predicate =
|
||||
0.up_to self.length . exists (idx -> (predicate (self.to_array.at idx)))
|
||||
0.up_to self.length . exists (idx -> (predicate (self.java_builder.get idx)))
|
||||
|
||||
## Converts this builder to a vector containing all the appended elements.
|
||||
|
||||
@ -1122,10 +1133,10 @@ type Builder
|
||||
bldr.to_vector
|
||||
to_vector : Vector Any
|
||||
to_vector self =
|
||||
old_array = self.to_array
|
||||
new_array = Array.new self.length
|
||||
Array.copy old_array 0 new_array 0 self.length
|
||||
Vector new_array
|
||||
## This creates a fresh copy of the builders storage, so any future
|
||||
changes to the builder will not affect the returned vector.
|
||||
new_array = self.java_builder.toArray
|
||||
from_polyglot_array new_array
|
||||
|
||||
## UNSTABLE
|
||||
|
||||
@ -1211,21 +1222,17 @@ slice_many_ranges vector ranges =
|
||||
new_length = ranges.fold 0 acc-> descriptor-> case descriptor of
|
||||
Integer -> acc+1
|
||||
Range _ _ _ -> acc+descriptor.length
|
||||
arr = Array.new new_length
|
||||
ranges.fold 0 start_ix-> descriptor-> case descriptor of
|
||||
builder = new_builder new_length
|
||||
ranges.each descriptor-> case descriptor of
|
||||
Integer ->
|
||||
arr.set_at start_ix (vector.unsafe_at descriptor)
|
||||
start_ix+1
|
||||
builder.append (vector.unsafe_at descriptor)
|
||||
Range start end step -> case step == 1 of
|
||||
True ->
|
||||
len = end-start
|
||||
Array.copy vector.to_array start arr start_ix len
|
||||
start_ix+len
|
||||
builder.append_vector_range vector start end
|
||||
False ->
|
||||
descriptor.each_with_index within_range_ix-> descriptor_ix->
|
||||
arr.set_at start_ix+within_range_ix (vector.unsafe_at descriptor_ix)
|
||||
start_ix+descriptor.length
|
||||
Vector arr
|
||||
descriptor.each ix->
|
||||
builder.append (vector.unsafe_at ix)
|
||||
builder.to_vector
|
||||
|
||||
## PRIVATE
|
||||
Takes a list of descriptors and returns a new one where ranges with
|
||||
|
@ -18,8 +18,8 @@ core_op : Mat -> Any -> (Mat -> Scalar -> Mat -> Nothing) -> Nothing
|
||||
core_op mat value function =
|
||||
result = Mat.new
|
||||
scalar = case value of
|
||||
Vector.Vector arr ->
|
||||
Scalar.new arr
|
||||
Vector.Vector _ ->
|
||||
Scalar.new value.to_array
|
||||
Matrix.Matrix m ->
|
||||
if ((m.rows == mat.rows) && (m.cols == mat.cols) && (m.channels == mat.channels)) then m else Panic.throw Matrix.Dimensions_Not_Equal
|
||||
_ ->
|
||||
|
@ -346,8 +346,8 @@ Error.should_equal self _ frames_to_skip=0 = fail_match_on_unexpected_error self
|
||||
|
||||
example_should_equal =
|
||||
1.00000001 . should_equal 1.00000002 epsilon=0.0001
|
||||
Decimal.should_equal : Decimal -> Decimal -> Integer -> Assertion
|
||||
Decimal.should_equal self that epsilon=0 frames_to_skip=0 =
|
||||
Number.should_equal : Decimal -> Decimal -> Integer -> Assertion
|
||||
Number.should_equal self that epsilon=0 frames_to_skip=0 =
|
||||
matches = case that of
|
||||
Number -> self.equals that epsilon
|
||||
_ -> False
|
||||
|
@ -13,11 +13,11 @@ import Standard.Visualization.Helpers
|
||||
json_from_table : Table.Table -> Object
|
||||
json_from_table table =
|
||||
names = ['label', 'latitude', 'longitude', 'radius', 'color']
|
||||
pairs = names.filter_map <| name->
|
||||
pairs = names.map <| name->
|
||||
column = table.lookup_ignore_case name
|
||||
column.when_valid ["df_" + name, column.to_vector]
|
||||
column.when_valid ["df_" + name, column.to_vector] . catch Nothing
|
||||
|
||||
Json.from_pairs pairs
|
||||
Json.from_pairs <| pairs.filter (x -> x.is_nothing.not)
|
||||
|
||||
## PRIVATE
|
||||
|
||||
|
@ -4,16 +4,6 @@ import Standard.Table.Data.Column
|
||||
import Standard.Table.Data.Storage
|
||||
import Standard.Table.Data.Table
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Maps the vector using the given function. Filters out all error values.
|
||||
|
||||
Arguments:
|
||||
- f: unary invokable that is applied to each vector element. Non-error
|
||||
values are returned in the resulting vector. Error values are dropped.
|
||||
Vector.Vector.filter_map : Any -> Vector
|
||||
Vector.Vector.filter_map self f = self.map f . filter .is_valid
|
||||
|
||||
## PRIVATE
|
||||
|
||||
Returns the given value if this is not an error. Propagates error otherwise.
|
||||
@ -116,9 +106,8 @@ Table.Table.all_columns self =
|
||||
- text: the case-insensitive name of the searched column.
|
||||
Table.Table.lookup_ignore_case : Text -> Column ! Nothing
|
||||
Table.Table.lookup_ignore_case self name =
|
||||
ret = self.all_columns.find <| col->
|
||||
self.all_columns.find <| col->
|
||||
col.name.equals_ignore_case name
|
||||
ret
|
||||
|
||||
## PRIVATE
|
||||
|
||||
|
@ -107,8 +107,8 @@ No_Fallback_Column.to_display_text self =
|
||||
Generates JSON that describes points data.
|
||||
Table.Table.point_data : Table -> Object
|
||||
Table.Table.point_data self =
|
||||
get_point_data field = field.lookup_in self . rename field.name
|
||||
columns = Point_Data.all_fields.filter_map get_point_data
|
||||
get_point_data field = field.lookup_in self . rename field.name . catch Any (_->Nothing)
|
||||
columns = Point_Data.all_fields.map get_point_data . filter (x -> x.is_nothing.not)
|
||||
(0.up_to self.row_count).to_vector.map <| row_n->
|
||||
pairs = columns.map column->
|
||||
value = column.at row_n . catch_ Nothing
|
||||
|
@ -8,7 +8,6 @@ import com.oracle.truffle.api.interop.InvalidArrayIndexException;
|
||||
import com.oracle.truffle.api.interop.TruffleObject;
|
||||
import com.oracle.truffle.api.library.ExportLibrary;
|
||||
import com.oracle.truffle.api.library.ExportMessage;
|
||||
import org.enso.interpreter.dsl.AcceptsError;
|
||||
import org.enso.interpreter.dsl.Builtin;
|
||||
import org.enso.interpreter.node.expression.builtin.error.InvalidArrayIndexError;
|
||||
import org.enso.interpreter.runtime.Context;
|
||||
@ -111,13 +110,6 @@ public class Array implements TruffleObject {
|
||||
return getItems()[(int) index];
|
||||
}
|
||||
|
||||
@Builtin.Method(name = "setAt", description = "Gets an array element at the given index.")
|
||||
@Builtin.WrapException(from = IndexOutOfBoundsException.class, to = InvalidArrayIndexError.class)
|
||||
public Object set(long index, @AcceptsError Object value) {
|
||||
getItems()[(int) index] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes an index validity check through the polyglot API.
|
||||
*
|
||||
@ -129,21 +121,6 @@ public class Array implements TruffleObject {
|
||||
return index < getArraySize() && index >= 0;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
void writeArrayElement(long index, Object value) {
|
||||
items[(int) index] = value;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean isArrayElementModifiable(long index) {
|
||||
return isArrayElementReadable(index);
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
boolean isArrayElementInsertable(long index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ExportMessage
|
||||
String toDisplayString(boolean b) {
|
||||
return toString();
|
||||
|
@ -1,5 +1,8 @@
|
||||
package org.enso.base;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Array_Utils {
|
||||
/**
|
||||
* This function forces the polyglot conversion of an Enso array into a `byte[]`. This allows for
|
||||
@ -11,4 +14,9 @@ public class Array_Utils {
|
||||
public static byte[] ensureByteArray(byte[] input) {
|
||||
return input;
|
||||
}
|
||||
|
||||
/** A temporary workaround to be able to efficiently append an array to `ArrayList`. */
|
||||
public static <T> void appendToArrayList(ArrayList<T> builder, List<T> list) {
|
||||
builder.addAll(list);
|
||||
}
|
||||
}
|
||||
|
@ -2,40 +2,64 @@ from Standard.Base import all
|
||||
|
||||
import Standard.Test
|
||||
|
||||
polyglot java import java.util.ArrayList
|
||||
|
||||
Array.method self = 0
|
||||
|
||||
spec = Test.group "Arrays" <|
|
||||
Test.specify "should be able to be converted to a visualization rep" <|
|
||||
arr = Vector.fill 1000 0 . to_array
|
||||
text = arr.to_default_visualization_data
|
||||
json = Json.parse text
|
||||
as_vec = json.into (Vector.Vector Number)
|
||||
as_vec.should_equal <| Vector.fill 100 0
|
||||
## Returns an array with the same contents as the given vector, surely backed by
|
||||
the Enso Array primitive.
|
||||
make_enso_array vector =
|
||||
enso_array = Array.new vector.length
|
||||
Array.copy vector.to_array 0 enso_array 0 vector.length
|
||||
enso_array
|
||||
|
||||
## Returns an array with the same contents as the given vector, surely backed by
|
||||
a Java array.
|
||||
make_java_array vector =
|
||||
builder = ArrayList.new
|
||||
vector.each x->
|
||||
builder.add x
|
||||
builder.toArray
|
||||
|
||||
test_arrays array_from_vector =
|
||||
Test.specify "should allow accessing elements" <|
|
||||
arr = [1, 2, 3] . to_array
|
||||
arr = array_from_vector [1, 2, 3]
|
||||
arr.at 0 . should_equal 1
|
||||
arr.at 2 . should_equal 3
|
||||
|
||||
Test.specify "should allow setting elements" <|
|
||||
arr = [1, 2, 3] . to_array
|
||||
arr.set_at 1 10
|
||||
arr.at 1 . should_equal 10
|
||||
Vector.from_polyglot_array arr . should_equal [1, 10, 3]
|
||||
|
||||
Test.specify "should panic on out of bounds access" <|
|
||||
arr = [1, 2, 3] . to_array
|
||||
arr = array_from_vector [1, 2, 3]
|
||||
Test.expect_panic_with (arr.at -1) Invalid_Array_Index_Error
|
||||
Test.expect_panic_with (arr.at 3) Invalid_Array_Index_Error
|
||||
Test.expect_panic_with (arr.set_at 3 100) Invalid_Array_Index_Error
|
||||
|
||||
Test.specify "should allow for functional dispatch on a method defined in this module"
|
||||
arr = [1, 2, 3] . to_array
|
||||
arr.method . should_equal 0
|
||||
spec =
|
||||
Test.group "Enso Arrays" <|
|
||||
test_arrays make_enso_array
|
||||
|
||||
Test.specify "should propagate dataflow errors" <|
|
||||
err = Error.throw (Illegal_State_Error "Foo")
|
||||
res = Array.new err
|
||||
res . should_fail_with Illegal_State_Error
|
||||
Test.specify "should allow for functional dispatch on a method defined in this module" <|
|
||||
arr = make_enso_array [1, 2, 3]
|
||||
arr.method . should_equal 0
|
||||
|
||||
Test.specify "should propagate dataflow errors" <|
|
||||
err = Error.throw (Illegal_State_Error "Foo")
|
||||
res = Array.new err
|
||||
res . should_fail_with Illegal_State_Error
|
||||
|
||||
Test.specify "should be able to be converted to a visualization rep" <|
|
||||
arr = make_enso_array (Vector.fill 1000 0)
|
||||
text = arr.to_default_visualization_data
|
||||
json = Json.parse text
|
||||
as_vec = json.into (Vector.Vector Number)
|
||||
as_vec.should_equal <| Vector.fill 100 0
|
||||
|
||||
Test.group "Polyglot Arrays" <|
|
||||
test_arrays make_java_array
|
||||
|
||||
Test.specify "should be able to be converted to a visualization rep" pending="`to_default_visualization_data` does not work for polyglot arrays" <|
|
||||
arr = make_java_array (Vector.fill 1000 0)
|
||||
text = arr.to_default_visualization_data
|
||||
json = Json.parse text
|
||||
as_vec = json.into (Vector.Vector Number)
|
||||
as_vec.should_equal <| Vector.fill 100 0
|
||||
|
||||
main = Test.Suite.run_main spec
|
||||
|
@ -412,10 +412,10 @@ spec = Test.group "Vectors" <|
|
||||
small_expected = [T 4 0, T 1 3, T 1 8, T -1 10, T -1 1, T -20 0]
|
||||
small_vec.sort order=Sort_Direction.Descending . should_equal small_expected
|
||||
|
||||
Test.specify "should be able to map over errors" <|
|
||||
fail a = Error.throw <| My_Error a
|
||||
[fail 1].map (x -> x.catch Any (x -> x.a)) . should_equal [1]
|
||||
[1].map fail . map .catch . should_equal [My_Error 1]
|
||||
Test.specify "should correctly propagate error through map" <|
|
||||
[1, 2, 3].map Error.throw . catch . should_equal 1
|
||||
fun a = if a == 3 then Error.throw (My_Error a) else a
|
||||
[1, 2, 3, 4].map fun . catch My_Error . should_equal (My_Error 3)
|
||||
|
||||
Test.specify "should be able to be efficiently converted to a visualisation" <|
|
||||
vec = Vector.fill 1000 0
|
||||
|
@ -8,9 +8,10 @@ import Standard.Test
|
||||
|
||||
import project.Helpers
|
||||
|
||||
spec =
|
||||
expect value expected_json_text =
|
||||
spec =
|
||||
expect value expected_json_text =
|
||||
result = Geo_Map.process_to_json_text value
|
||||
IO.println result
|
||||
Json.parse result . should_equal <| Json.parse expected_json_text
|
||||
|
||||
Test.group "Geo_Map" <|
|
||||
|
Loading…
Reference in New Issue
Block a user