Skip to content

Commit

Permalink
[MoveLib] Rename all take_/return_ function names (MystenLabs#1660)
Browse files Browse the repository at this point in the history
  • Loading branch information
lxfind authored Apr 28, 2022
1 parent 1bd3ecd commit c3b8dbb
Show file tree
Hide file tree
Showing 28 changed files with 272 additions and 272 deletions.
14 changes: 7 additions & 7 deletions doc/src/build/move.md
Original file line number Diff line number Diff line change
Expand Up @@ -680,19 +680,19 @@ function:
TestScenario::next_tx(scenario, &initial_owner);
{
// extract the sword owned by the initial owner
let sword = TestScenario::take_object<Sword>(scenario);
let sword = TestScenario::take_owned<Sword>(scenario);
// transfer the sword to the final owner
sword_transfer(sword, final_owner, TestScenario::ctx(scenario));
};
// third transaction executed by the final sword owner
TestScenario::next_tx(scenario, &final_owner);
{
// extract the sword owned by the final owner
let sword = TestScenario::take_object<Sword>(scenario);
let sword = TestScenario::take_owned<Sword>(scenario);
// verify that the sword has expected properties
assert!(magic(&sword) == 42 && strength(&sword) == 7, 1);
// return the sword to the object pool (it cannot be simply "dropped")
TestScenario::return_object(scenario, sword)
TestScenario::return_owned(scenario, sword)
}
}
```
Expand All @@ -711,7 +711,7 @@ the sword it now owns to its final owner. Please note that in *pure
Move* we do not have the notion of Sui storage and, consequently, no
easy way for the emulated Sui transaction to retrieve it from
storage. This is where the `TestScenario` module comes to help - its
`take_object` function makes an object of a given type (in this case
`take_owned` function makes an object of a given type (in this case
of type `Sword`) owned by an address executing the current transaction
available for manipulation by the Move code. (For now, we assume that
there is only one such object.) In this case, the object retrieved
Expand All @@ -730,7 +730,7 @@ by transferring the sword object to the fake address. But the
`TestScenario` package gives us a more elegant solution, which is
closer to what happens when Move code is actually executed in the
context of Sui - we can simply return the sword to the object pool
using the `TestScenario::return_object` function.
using the `TestScenario::return_owned` function.
We can now run the test command again and see that we now have two
successful tests for our module:
Expand Down Expand Up @@ -870,11 +870,11 @@ We can now create a function to test the module initialization:
TestScenario::next_tx(scenario, &admin);
{
// extract the Forge object
let forge = TestScenario::take_object<Forge>(scenario);
let forge = TestScenario::take_owned<Forge>(scenario);
// verify number of created swords
assert!(swords_created(&forge) == 0, 1);
// return the Forge object to the object pool
TestScenario::return_object(scenario, forge)
TestScenario::return_owned(scenario, forge)
}
}
Expand Down
12 changes: 6 additions & 6 deletions doc/src/build/programming-with-objects/ch1-object-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,27 @@ let not_owner = @0x2;
// Check that @not_owner does not own the just-created ColorObject.
TestScenario::next_tx(scenario, &not_owner);
{
assert!(!TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(!TestScenario::can_take_owned<ColorObject>(scenario), 0);
};
```

`TestScenario::next_tx` switches the transaction sender to `@0x2`, which is a new address than the previous one.
`TestScenario::can_take_object` checks whether an object with the given type actually exists in the global storage owned by the current sender of the transaction. In this code, we assert that we should not be able to remove such an object, because `@0x2` does not own any object.
`TestScenario::can_take_owned` checks whether an object with the given type actually exists in the global storage owned by the current sender of the transaction. In this code, we assert that we should not be able to remove such an object, because `@0x2` does not own any object.
> :bulb: The second parameter of `assert!` is the error code. In non-test code, we usually define a list of dedicated error code constants for each type of error that could happen in production. For unit tests though, it's usually unnecessary because there will be way too many assetions and the stacktrace upon error is sufficient to tell where the error happened. Hence we recommend just putting `0` there in unit tests for assertions.
Finally we check that `@0x1` owns the object and the object value is consistent:
```rust
TestScenario::next_tx(scenario, &owner);
{
let object = TestScenario::take_object<ColorObject>(scenario);
let object = TestScenario::take_owned<ColorObject>(scenario);
let (red, green, blue) = ColorObject::get_color(&object);
assert!(red == 255 && green == 0 && blue == 255, 0);
TestScenario::return_object(scenario, object);
TestScenario::return_owned(scenario, object);
};
```

`TestScenario::take_object` removes the object of given type from global storage that's owned by the current transaction sender (it also implicitly checks `can_take_object`). If this line of code succeeds, it means that `owner` indeed owns an object of type `ColorObject`.
We also check that the field values of the object match with what we set in creation. At the end, we must return the object back to the global storage by calling `TestScenario::return_object` so that it's back to the global storage. This also ensures that if any mutations happened to the object during the test, the global storage is aware of the changes.
`TestScenario::take_owned` removes the object of given type from global storage that's owned by the current transaction sender (it also implicitly checks `can_take_owned`). If this line of code succeeds, it means that `owner` indeed owns an object of type `ColorObject`.
We also check that the field values of the object match with what we set in creation. At the end, we must return the object back to the global storage by calling `TestScenario::return_owned` so that it's back to the global storage. This also ensures that if any mutations happened to the object during the test, the global storage is aware of the changes.

Again, you can find the full code in [ColorObject.move](../../../../sui_programmability/examples/objects_tutorial/sources/ColorObject.move).

Expand Down
26 changes: 13 additions & 13 deletions doc/src/build/programming-with-objects/ch2-using-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ In the above function signature, `from_object` can be a read-only reference beca
> :bulb: Although `from_object` is a read-only reference in this transaction, it is still a mutable object in Sui storage--another transaction could be sent to mutate the object at the same time! To prevent this, Sui must lock any mutable object used as a transaction input, even when it's passed as a read-only reference. In addition, only an object's owner can send a transaction that locks the object.
Let's write a unit test to see how we could interact with multiple objects of the same type in tests.
In the previous chapter, we introduced the `take_object<T>` API, which takes an object of type `T` from the global storage created by previous transactions. However, what if there are multiple objects of the same type? `take_object<T>` will no longer be able to tell which one to return. To solve this problem, we need to use two new APIs. The first is `TxContext::last_created_object_id(ctx)`, which returns the ID of the most recent created object. The second is `TestScenario::take_object_by_id<T>`, which returns an object of type `T` with a specific object ID.
In the previous chapter, we introduced the `take_owned<T>` API, which takes an object of type `T` from the global storage created by previous transactions. However, what if there are multiple objects of the same type? `take_owned<T>` will no longer be able to tell which one to return. To solve this problem, we need to use two new APIs. The first is `TxContext::last_created_object_id(ctx)`, which returns the ID of the most recent created object. The second is `TestScenario::take_owned_by_id<T>`, which returns an object of type `T` with a specific object ID.
Now let's take a look at the test (`test_copy_into`):
```rust
let owner = @0x1;
Expand All @@ -51,25 +51,25 @@ The above code created two objects. Note that right after each call, we make a c
```rust
TestScenario::next_tx(scenario, &owner);
{
let obj1 = TestScenario::take_object_by_id<ColorObject>(scenario, id1);
let obj2 = TestScenario::take_object_by_id<ColorObject>(scenario, id2);
let obj1 = TestScenario::take_owned_by_id<ColorObject>(scenario, id1);
let obj2 = TestScenario::take_owned_by_id<ColorObject>(scenario, id2);
let (red, green, blue) = ColorObject::get_color(&obj1);
assert!(red == 255 && green == 255 && blue == 255, 0);

let ctx = TestScenario::ctx(scenario);
ColorObject::copy_into(&obj2, &mut obj1, ctx);
TestScenario::return_object(scenario, obj1);
TestScenario::return_object(scenario, obj2);
TestScenario::return_owned(scenario, obj1);
TestScenario::return_owned(scenario, obj2);
};
```
We used `take_object_by_id` to take both objects using different IDs. We then used `copy_into` to update `obj1`'s value using `obj2`'s. We can verify that the mutation works:
We used `take_owned_by_id` to take both objects using different IDs. We then used `copy_into` to update `obj1`'s value using `obj2`'s. We can verify that the mutation works:
```rust
TestScenario::next_tx(scenario, &owner);
{
let obj1 = TestScenario::take_object_by_id<ColorObject>(scenario, id1);
let obj1 = TestScenario::take_owned_by_id<ColorObject>(scenario, id1);
let (red, green, blue) = ColorObject::get_color(&obj1);
assert!(red == 0 && green == 0 && blue == 0, 0);
TestScenario::return_object(scenario, obj1);
TestScenario::return_owned(scenario, obj1);
}
```

Expand Down Expand Up @@ -108,14 +108,14 @@ let scenario = &mut TestScenario::begin(&owner);
// Delete the ColorObject we just created.
TestScenario::next_tx(scenario, &owner);
{
let object = TestScenario::take_object<ColorObject>(scenario);
let object = TestScenario::take_owned<ColorObject>(scenario);
let ctx = TestScenario::ctx(scenario);
ColorObject::delete(object, ctx);
};
// Verify that the object was indeed deleted.
TestScenario::next_tx(scenario, &owner);
{
assert!(!TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(!TestScenario::can_take_owned<ColorObject>(scenario), 0);
}
```
The first part is the same as what we have seen in [Chapter 1](./ch1-object-basics.md#writing-unit-tests), which creates a new `ColorObject` and puts it in the owner's account. The second transaction is what we are testing: retrieve the object from the storage and then delete it. Since the object is deleted, there is no need (in fact, it is impossible) to return it to the storage. The last part of the test checks that the object is indeed no longer in the global storage and hence cannot be retrieved from there.
Expand All @@ -142,7 +142,7 @@ let scenario = &mut TestScenario::begin(&owner);
let recipient = @0x2;
TestScenario::next_tx(scenario, &owner);
{
let object = TestScenario::take_object<ColorObject>(scenario);
let object = TestScenario::take_owned<ColorObject>(scenario);
let ctx = TestScenario::ctx(scenario);
ColorObject::transfer(object, recipient, ctx);
};
Expand All @@ -152,12 +152,12 @@ Note that in the second transaction, the sender of the transaction should still
// Check that owner no longer owns the object.
TestScenario::next_tx(scenario, &owner);
{
assert!(!TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(!TestScenario::can_take_owned<ColorObject>(scenario), 0);
};
// Check that recipient now owns the object.
TestScenario::next_tx(scenario, &recipient);
{
assert!(TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(TestScenario::can_take_owned<ColorObject>(scenario), 0);
};
```

Expand Down
10 changes: 5 additions & 5 deletions doc/src/build/programming-with-objects/ch3-immutable-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Since immutable objects can never be mutated, there will never be a data race ev
### Test immutable object
Let's take a look at how we interact with immutable objects in unit tests.

Previously, we used the `TestScenario::take_object` API to take an object from the global storage that's owned by the sender of the transaction in a unit test. Since immutable objects are not owned by anyone, `TestScenario::take_object` works for immutable objects as well! That is, if there exists an immutable object of type `T` in the global storage, `take_object<T>` will return that object.
Previously, we used the `TestScenario::take_owned` API to take an object from the global storage that's owned by the sender of the transaction in a unit test. Since immutable objects are not owned by anyone, `TestScenario::take_owned` works for immutable objects as well! That is, if there exists an immutable object of type `T` in the global storage, `take_owned<T>` will return that object.

Let's see it work in action:
```rust
Expand All @@ -59,12 +59,12 @@ public(script) fun test_immutable() {
};
TestScenario::next_tx(scenario, &sender1);
{
assert!(TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(TestScenario::can_take_owned<ColorObject>(scenario), 0);
};
let sender2 = @0x2;
TestScenario::next_tx(scenario, &sender2);
{
assert!(TestScenario::can_take_object<ColorObject>(scenario), 0);
assert!(TestScenario::can_take_owned<ColorObject>(scenario), 0);
};
}
```
Expand Down Expand Up @@ -95,10 +95,10 @@ public(script) fun test_mutate_immutable() {
};
TestScenario::next_tx(scenario, &sender1);
{
let object = TestScenario::take_object<ColorObject>(scenario);
let object = TestScenario::take_owned<ColorObject>(scenario);
let ctx = TestScenario::ctx(scenario);
ColorObject::update(&mut object, 0, 0, 0, ctx);
TestScenario::return_object(scenario, object);
TestScenario::return_owned(scenario, object);
};
}
```
Expand Down
16 changes: 8 additions & 8 deletions sui_core/src/unit_tests/data/hero/sources/Hero.move
Original file line number Diff line number Diff line change
Expand Up @@ -313,32 +313,32 @@ module Examples::Hero {
// Admin mints 500 coins and sends them to the Player so they can buy game items
TestScenario::next_tx(scenario, &admin);
{
let treasury_cap = TestScenario::take_object<TreasuryCap<EXAMPLE>>(scenario);
let treasury_cap = TestScenario::take_owned<TreasuryCap<EXAMPLE>>(scenario);
let ctx = TestScenario::ctx(scenario);
let coins = Coin::mint(500, &mut treasury_cap, ctx);
Coin::transfer(coins, copy player);
TestScenario::return_object(scenario, treasury_cap);
TestScenario::return_owned(scenario, treasury_cap);
};
// Player purchases a hero with the coins
TestScenario::next_tx(scenario, &player);
{
let coin = TestScenario::take_object<Coin<EXAMPLE>>(scenario);
let coin = TestScenario::take_owned<Coin<EXAMPLE>>(scenario);
acquire_hero(coin, TestScenario::ctx(scenario));
};
// Admin sends a boar to the Player
TestScenario::next_tx(scenario, &admin);
{
let admin_cap = TestScenario::take_object<GameAdmin>(scenario);
let admin_cap = TestScenario::take_owned<GameAdmin>(scenario);
send_boar(&mut admin_cap, 10, 10, player, TestScenario::ctx(scenario));
TestScenario::return_object(scenario, admin_cap)
TestScenario::return_owned(scenario, admin_cap)
};
// Player slays the boar!
TestScenario::next_tx(scenario, &player);
{
let hero = TestScenario::take_object<Hero>(scenario);
let boar = TestScenario::take_object<Boar>(scenario);
let hero = TestScenario::take_owned<Hero>(scenario);
let boar = TestScenario::take_owned<Boar>(scenario);
slay(&mut hero, boar, TestScenario::ctx(scenario));
TestScenario::return_object(scenario, hero)
TestScenario::return_owned(scenario, hero)
};
}
}
12 changes: 6 additions & 6 deletions sui_programmability/examples/basics/sources/Counter.move
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module Basics::CounterTest {

TestScenario::next_tx(scenario, &user1);
{
let counter_wrapper = TestScenario::take_shared_object<Counter::Counter>(scenario);
let counter_wrapper = TestScenario::take_shared<Counter::Counter>(scenario);
let counter = TestScenario::borrow_mut(&mut counter_wrapper);

assert!(Counter::owner(counter) == owner, 0);
Expand All @@ -80,25 +80,25 @@ module Basics::CounterTest {
Counter::increment(counter, TestScenario::ctx(scenario));
Counter::increment(counter, TestScenario::ctx(scenario));
Counter::increment(counter, TestScenario::ctx(scenario));
TestScenario::return_shared_object(scenario, counter_wrapper);
TestScenario::return_shared(scenario, counter_wrapper);
};

TestScenario::next_tx(scenario, &owner);
{
let counter_wrapper = TestScenario::take_shared_object<Counter::Counter>(scenario);
let counter_wrapper = TestScenario::take_shared<Counter::Counter>(scenario);
let counter = TestScenario::borrow_mut(&mut counter_wrapper);

assert!(Counter::owner(counter) == owner, 0);
assert!(Counter::value(counter) == 3, 1);

Counter::set_value(counter, 100, TestScenario::ctx(scenario));

TestScenario::return_shared_object(scenario, counter_wrapper);
TestScenario::return_shared(scenario, counter_wrapper);
};

TestScenario::next_tx(scenario, &user1);
{
let counter_wrapper = TestScenario::take_shared_object<Counter::Counter>(scenario);
let counter_wrapper = TestScenario::take_shared<Counter::Counter>(scenario);
let counter = TestScenario::borrow_mut(&mut counter_wrapper);

assert!(Counter::owner(counter) == owner, 0);
Expand All @@ -108,7 +108,7 @@ module Basics::CounterTest {

assert!(Counter::value(counter) == 101, 2);

TestScenario::return_shared_object(scenario, counter_wrapper);
TestScenario::return_shared(scenario, counter_wrapper);
};
}
}
10 changes: 5 additions & 5 deletions sui_programmability/examples/basics/sources/Lock.move
Original file line number Diff line number Diff line change
Expand Up @@ -127,23 +127,23 @@ module Basics::LockTest {
// key to User2, so that he can have access to the stored treasure.
TestScenario::next_tx(scenario, &user1);
{
let key = TestScenario::take_object<Key<Treasure>>(scenario);
let key = TestScenario::take_owned<Key<Treasure>>(scenario);

Transfer::transfer(key, user2);
};

// User2 is impatient and he decides to take the treasure.
TestScenario::next_tx(scenario, &user2);
{
let lock_wrapper = TestScenario::take_shared_object<Lock<Treasure>>(scenario);
let lock_wrapper = TestScenario::take_shared<Lock<Treasure>>(scenario);
let lock = TestScenario::borrow_mut(&mut lock_wrapper);
let key = TestScenario::take_object<Key<Treasure>>(scenario);
let key = TestScenario::take_owned<Key<Treasure>>(scenario);
let ctx = TestScenario::ctx(scenario);

Lock::take<Treasure>(lock, &key, ctx);

TestScenario::return_shared_object(scenario, lock_wrapper);
TestScenario::return_object(scenario, key);
TestScenario::return_shared(scenario, lock_wrapper);
TestScenario::return_owned(scenario, key);
};
}
}
Loading

0 comments on commit c3b8dbb

Please sign in to comment.