Skip to content

Commit

Permalink
Add ArraySet BIF and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeers committed Jan 4, 2024
1 parent eed423c commit 3717741
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

package ortus.boxlang.runtime.bifs.global.array;

import java.util.stream.IntStream;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.bifs.BoxMember;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.Array;
import ortus.boxlang.runtime.types.BoxLangType;

@BoxBIF
@BoxMember( type = BoxLangType.ARRAY )

public class ArraySet extends BIF {

/**
* Constructor
*/
public ArraySet() {
super();
declaredArguments = new Argument[] {
new Argument( true, "modifiablearray", Key.array ),
new Argument( true, "any", Key.start ),
new Argument( true, "any", Key.end ),
new Argument( true, "any", Key.value )
};
}

/**
* In a one-dimensional array, sets the elements in a specified
* index range to a value. Useful for initializing an array after
* a call to arrayNew.
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.foo Describe any expected arguments
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualObj = arguments.getAsArray( Key.array );
Integer start = arguments.getAsInteger( Key.start );
Integer end = arguments.getAsInteger( Key.end );
Object value = arguments.get( Key.value );

// expand the array using null values
if ( end > actualObj.size() ) {
IntStream.range( actualObj.size() - 1, end - 1 ).forEach( i -> actualObj.add( null ) );
}

IntStream.range( start, end + 1 ).forEach( i -> {
if ( i - 1 >= actualObj.size() ) {
actualObj.add( value );
} else {
actualObj.set( i - 1, value );
}
} );

return true;
}

}
15 changes: 8 additions & 7 deletions src/main/java/ortus/boxlang/runtime/scopes/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,14 @@ public class Key {
public static final Key datatype = Key.of( "datatype" );
public static final Key dimensions = Key.of( "dimensions" );
public static final Key type = Key.of( "type" );
public static Key arrayFind = Key.of( "arrayFind" );
public static Key findAll = Key.of( "findAll" );
public static Key arrayFindAll = Key.of( "arrayFindAll" );
public static Key array1 = Key.of( "array1" );
public static Key array2 = Key.of( "array2" );
public static Key leaveIndex = Key.of( "leaveIndex" );
public static Key defaultValue = Key.of( "defaultValue" );
public static final Key arrayFind = Key.of( "arrayFind" );
public static final Key findAll = Key.of( "findAll" );
public static final Key arrayFindAll = Key.of( "arrayFindAll" );
public static final Key array1 = Key.of( "array1" );
public static final Key array2 = Key.of( "array2" );
public static final Key leaveIndex = Key.of( "leaveIndex" );
public static final Key defaultValue = Key.of( "defaultValue" );
public static final Key end = Key.of( "end" );

public static final Key file = Key.of( "file" );
public static final Key filepath = Key.of( "filepath" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@
import ortus.boxlang.runtime.BoxRuntime;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.context.ScriptingBoxContext;
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.scopes.VariablesScope;
import ortus.boxlang.runtime.types.Array;
import ortus.boxlang.runtime.types.Struct;

public class ArrayReverseTest {

static BoxRuntime instance;
static IBoxContext context;
static IScope variables;
static Struct variables;
static Key result = new Key( "result" );

@BeforeAll
public static void setUp() {
instance = BoxRuntime.getInstance( true );
context = new ScriptingBoxContext( instance.getRuntimeContext() );
variables = context.getScopeNearby( VariablesScope.name );
variables = ( Struct ) context.getScopeNearby( VariablesScope.name );
}

@AfterAll
Expand All @@ -68,7 +68,7 @@ public void testBif() {
result = ArrayReverse( arr );
""",
context );
Array reversed = ( Array ) variables.dereference( result, false );
Array reversed = ( Array ) variables.getAsArray( result );
assertThat( reversed.size() ).isEqualTo( 3 );
assertThat( reversed.get( 0 ) ).isEqualTo( "blue" );
assertThat( reversed.get( 1 ) ).isEqualTo( "green" );
Expand All @@ -84,7 +84,7 @@ public void testDoesntMutate() {
result = ArrayReverse( arr );
""",
context );
Array arr = ( Array ) variables.dereference( Key.of( "arr" ), false );
Array arr = ( Array ) variables.getAsArray( Key.of( "arr" ) );
assertThat( arr.size() ).isEqualTo( 3 );
assertThat( arr.get( 0 ) ).isEqualTo( "red" );
assertThat( arr.get( 1 ) ).isEqualTo( "green" );
Expand All @@ -100,7 +100,7 @@ public void testItReturnsFloorMember() {
result = ArrayReverse( arr );
""",
context );
Array reversed = ( Array ) variables.dereference( result, false );
Array reversed = ( Array ) variables.getAsArray( result );
assertThat( reversed.size() ).isEqualTo( 3 );
assertThat( reversed.get( 0 ) ).isEqualTo( "blue" );
assertThat( reversed.get( 1 ) ).isEqualTo( "green" );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

/**
* [BoxLang]
*
* Copyright [2023] [Ortus Solutions, Corp]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package ortus.boxlang.runtime.bifs.global.array;

import static com.google.common.truth.Truth.assertThat;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import ortus.boxlang.runtime.BoxRuntime;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.context.ScriptingBoxContext;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.scopes.VariablesScope;
import ortus.boxlang.runtime.types.Array;
import ortus.boxlang.runtime.types.Struct;

public class ArraySetTest {

static BoxRuntime instance;
static IBoxContext context;
static Struct variables;
static Key result = new Key( "result" );

@BeforeAll
public static void setUp() {
instance = BoxRuntime.getInstance( true );
context = new ScriptingBoxContext( instance.getRuntimeContext() );
variables = ( Struct ) context.getScopeNearby( VariablesScope.name );
}

@AfterAll
public static void teardown() {
instance.shutdown();
}

@BeforeEach
public void setupEach() {
variables.clear();
}

@DisplayName( "It should set the values in the array" )
@Test
public void testBif() {
instance.executeSource(
"""
arr = [ "red", "green", "blue" ];
result = ArraySet( arr, 3, 5, 10 );
""",
context );
Array arr = variables.getAsArray( Key.of( "arr" ) );
assertThat( arr.size() ).isEqualTo( 5 );
assertThat( arr.get( 0 ) ).isEqualTo( "red" );
assertThat( arr.get( 1 ) ).isEqualTo( "green" );
assertThat( arr.get( 2 ) ).isEqualTo( 10 );
assertThat( arr.get( 3 ) ).isEqualTo( 10 );
assertThat( arr.get( 4 ) ).isEqualTo( 10 );
}

@DisplayName( "It should allow you to invoke it as a member function" )
@Test
public void testMemberInvocation() {
instance.executeSource(
"""
arr = [ "red", "green", "blue" ];
result = arr.set( 3, 5, 10 );
""",
context );
Array arr = variables.getAsArray( Key.of( "arr" ) );
assertThat( arr.size() ).isEqualTo( 5 );
assertThat( arr.get( 0 ) ).isEqualTo( "red" );
assertThat( arr.get( 1 ) ).isEqualTo( "green" );
assertThat( arr.get( 2 ) ).isEqualTo( 10 );
assertThat( arr.get( 3 ) ).isEqualTo( 10 );
assertThat( arr.get( 4 ) ).isEqualTo( 10 );
}

@DisplayName( "It should work on an empty array" )
@Test
public void testEmptyArray() {
instance.executeSource(
"""
arr = [];
result = ArraySet( arr, 3, 5, 10 );
""",
context );
Array arr = variables.getAsArray( Key.of( "arr" ) );
assertThat( arr.size() ).isEqualTo( 5 );
assertThat( arr.get( 0 ) ).isNull();
assertThat( arr.get( 1 ) ).isNull();
assertThat( arr.get( 2 ) ).isEqualTo( 10 );
assertThat( arr.get( 3 ) ).isEqualTo( 10 );
assertThat( arr.get( 4 ) ).isEqualTo( 10 );
}

}

0 comments on commit 3717741

Please sign in to comment.