Skip to content

Commit

Permalink
Add ArrayResize BIF and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeers committed Jan 5, 2024
1 parent b073d2b commit a6779d0
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

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

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 ArrayResize extends BIF {

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

/**
* Resets an array to a specified minimum number of elements.
* This can improve performance, if used to size an array to its
* expected maximum. For more than 500 elements, use arrayResize
* immediately after using the ArrayNew tag.
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.array The array to resize
*
* @argument.size The new minimum size of the array
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Array actualObj = arguments.getAsArray( Key.array );
Integer size = arguments.getAsInteger( Key.size );

if ( actualObj.size() < size ) {
for ( int i = actualObj.size(); i < size; i++ ) {
actualObj.add( null );
}
}

return true;
}

}
2 changes: 2 additions & 0 deletions src/main/java/ortus/boxlang/runtime/scopes/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ public class Key {
public static final Key mask = Key.of( "mask" );
public static final Key dateFormat = Key.of( "dateFormat" );
public static final Key timeFormat = Key.of( "timeFormat" );
public static final Key size = Key.of( "size" );

/**
* --------------------------------------------------------------------------
* Private Properties
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@

/**
* [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 ArrayResizeTest {

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 grow an array using nulls" )
@Test
public void testGrow() {
instance.executeSource(
"""
nums = [];
result = ArrayResize( nums, 3 );
""",
context );
Array arr = variables.getAsArray( Key.of( "nums" ) );
assertThat( variables.get( result ) ).isEqualTo( true );
assertThat( arr.size() ).isEqualTo( 3 );
assertThat( arr.get( 0 ) ).isNull();
assertThat( arr.get( 1 ) ).isNull();
assertThat( arr.get( 2 ) ).isNull();
}

@DisplayName( "It should not grow an array that is already bigger than the provided size" )
@Test
public void testBigger() {
instance.executeSource(
"""
nums = [ 1, 2, 3, 4, 5 ];
result = ArrayResize( nums, 3 );
""",
context );
Array arr = variables.getAsArray( Key.of( "nums" ) );
assertThat( variables.get( result ) ).isEqualTo( true );
assertThat( arr.size() ).isEqualTo( 5 );
assertThat( arr.get( 0 ) ).isEqualTo( 1 );
assertThat( arr.get( 1 ) ).isEqualTo( 2 );
assertThat( arr.get( 2 ) ).isEqualTo( 3 );
assertThat( arr.get( 3 ) ).isEqualTo( 4 );
assertThat( arr.get( 4 ) ).isEqualTo( 5 );
}

@DisplayName( "It should allow member invocation" )
@Test
public void testMemberInvocation() {
instance.executeSource(
"""
nums = [];
result = nums.resize( 3 );
""",
context );
Array arr = variables.getAsArray( Key.of( "nums" ) );
assertThat( variables.get( result ) ).isEqualTo( true );
assertThat( arr.size() ).isEqualTo( 3 );
assertThat( arr.get( 0 ) ).isNull();
assertThat( arr.get( 1 ) ).isNull();
assertThat( arr.get( 2 ) ).isNull();
}

}

0 comments on commit a6779d0

Please sign in to comment.