Seed - Development - Unit Testing

in #utopian-io6 years ago (edited)

SeedUnitTesting.png

Repository

https://github.com/Cajarty/Seed


Overview

The following development changes were based upon the design article Unit Testing.

Testing is the act of proving a product both works when it is intended to work, and fails under the proper fail conditions. Testing is an extremely important part of any software development cycle. Unit testing is one of the most popular forms of testing, thriving in testing subsystems and individual functions.

In this pull request we implemented 120 different unit tests, proving every important subsystem of the Seed project. The tested segments include cryptography tests, account tests, testing the pseudo-randomness system, testing block creation, transaction creation, the entanglement, the blockchains, the transaction & block squashing mechanism, the ledger, the Seed virtual machine, reading & writing to storage, as well as the messaging subsystem used by UI's. When any test failed, proving a subsystem was not behaving as expected, the subsystem was fixed in order to pass every test.

On top of writing the unit tests, we also created the unit testing environment. This environment allows for the easy addition of future unit tests, as well as allows for logging the test results in both a verbose and non-verbose manner.


Unit Testing Environment

The testing suite is a fairly simple subsystem found in the /seedSrc/tests/unitTesting.js file. This subsystem is composed of two portions, the exported functions and the Test class.


Exported Functions

The exported functions offered are to either run all unit tests, or request data to be used within the tests. Example data's that can be requested are requesting for some sample Transactions or sample Blocks. When users choose to run all unit tests, it will then access all testable subsystems and request from them a mapping of unit tests, and then execute each test.


Test Class

The Test class is a class passed into each unit test upon invocation. The Test class offers functions to tests related to asserting statements, with parameters for error messages if the test fails.

For example,

 test.assert(doesEqualFive(5), "Five should be equal to five")

is a simple usage of the simplest assert method. If the doesEqualFive method returns true, then the test passes. If it returns false, the test fails with the "Five should be equal to five" error message being added as the reason for test fails.

There are other assert overloads, such as assertAreEqual(a, b, errorMessage), created for convenience. However, testing isn't just about testing for success, but also testing for fail. For that reason, there also exists assertFail.

 test.assertFail(() => {
     tryCallFunctionThatThrowsError(invalidInput);
 }, "Should have thrown an error message for having invalid input")

Executes the code passed in as the first function in a try-catch. This assert will consider the test a pass if an error was thrown as expected, however a fail if no error was thrown.

These asserts in the Test class allow unit tests to make multiple checks per unit test.


Implementation

The entire implementation can be found in the /seedSrc/tests/unitTesting.js file. The exported functions allow for the developers to invoke the tests, and for tests to request extra data they may require.

Subsystems which desire to be tested must be added manually to the exported runAllUnitTests function. Each subsystem to be tested must offer a getUnitTests exported functions for the unitTesting system to gather all the unit tests from the testable subsystems.


Unit Tests

In total, fourteen different exports will be extensively unit tested in order to confirm Seed is in fully working order. Afterwards, these unit tests will act as a regression test, allowing us to confirm old functionality still works as intended while implementing future changes.

In each section, we will outline which unit tests are too be created, along with what the procedure for implementing the unit test is.


Cryptography Subsystem Tests

The cryptography tests can be found in the seedSrc/helpers/cryptoHelper.js file.

#DescriptionProcedureResult
1Correctly hash with SHA256.Access the cryptography subsystem and hash the string “Test #1”. Compare result with 3rd party proven SHA256 hasher.Passed
2Correctly hashes small data with SHA256.Repeat test #1, however pass in the string “1”Passed
3Correctly hashes large data with SHA256.Repeat test #1, however pass in the Seed literature review as input.Passed
4Throws a error message when attempting to hash undefined data.Repeat test #1, however pass in undefined, and try to catch the correct error message.Passed
5Throws a error message when attempting to hash empty data.Repeat test #4, however pass in an empty string.Passed
6Correctly generates a private keyAccess the crypto subsystem and generate a private key.Passed
7Correctly generates a private key with user defined entropy.Repeat test #6, however pass in as entropy the string“Test #7”.Passed
8Correctly generates a pair of valid private/public keys.Repeat step #6, however access the generateKeyPair functionality.Passed
9Correctly generates a pair of valid private/public keys with user defined entropy.Repeat step #8 however pass in entropy for private key creation.Passed
10Correctly fetches the public key that belongs to a proposed private key.Access the cryptography subsystem and request a public key, passing in a private key derived from the entropy “ABC”. Compared the result with the expected result.Passed
11Throws a error message when attempting to fetch the public key for a undefined private key.Repeat test #10, however pass in undefined as the private key. Catch the error and compare it for the expected error message.Passed
12Correctly takes a public key and correctly converts it to a public address.Access the cryptography subsystem and request a conversation from public key to public address. Compare the result with the expected result.Passed
13When converting to a public address, throws a error message when a empty parameter is passed in instead of a valid public key.Repeat test #12, however pass in undefined as the public key. Catch the error and compare it for the expected error message.Passed
14Correctly signs data on behalf of a private key.Access the cryptography subsystem and request a signature on behalf of the proposed private key. Compare the result with the expected result.Passed
15When signing data, throws a error message when a undefined parameter is passed in instead of a valid private key.Repeat test #14, however pass in undefined as the private key. Catch the error and compare it for the expected error message.Passed
16Correctly verifies the validity of a signature.Repeat test #14, however afterwards, request from the cryptography subsystem for the verification of the signature.Passed
17Catches invalid signatures when failing to validate them.Access the cryptography subsystem and request the verification of a signature, however pass in an invalid signature. Check for a return value of false.Passed
18When validating signatures, fails to validate signatures who belong to a different public key.Run test #16, however pass in another private key’s signature. Expect the validator to fail.Passed
19Correctly generates the proper checksum when given a valid hash.Access the cryptography subsystem and request the hash to checksum feature. Compare the result with the expected value.Passed
20Throws a error message when a undefined parameter is passed in instead of a valid hash.Access the cryptographic subsystem and request the hash of undefined. Catch the thrown error and compare it to the expected error message.Passed

Account Subsystem Tests

The account subsystem tests can be found in the seedSrc/account.js file.

#DescriptionProcedureResult
21Creating an account out of a private key generates proper data (e.g. public key and public address).Access the account subsystem and request the creation of an account, passing in a private key created from the entropy “ABC”. Compare the results with the expected data.Passed
22Throws a error message when a undefined parameter is passed in instead of a valid private key.Access the account subsystem and request the creation of an account, passing in undefined as the private key. Catch the thrown error and compare it to the expected error message.Passed
23Creating an account out of a public key generates a proper data (e.g. public address).Access the account subsystem and request the creation of an account, passing in a public key created from the private key who’s entropy was “ABC”. Compare the results with the expected data.Passed
24Throws a error message when a undefined parameter is passed in instead of a valid public key.Access the account subsystem and request the creation of an account, passing in undefined as the public key. Catch the thrown error and compare it to the expected error message.Passed
25Creating an account out of raw entropy generates a proper data (e.g. private key, public key and public address).Access the account subsystem and request the creation of an account, passing in the entropy “ABC”. Compare the results with the expected data.Passed
26Correctly identifies when a account has the capability to create signatures.Create an account through a given private key, and request from the account subsystem whether the account can sign messages. Expect the result to be true.Passed
27Correctly identifies when a account does not have the capability to create signatures.Create an account through a given public key, and request from the account subsystem whether the account can sign messages. Expect the result to be false.Passed
28Accounts with signing capability sign signatures correctly.Repeat test #26, however after confirming the account can sign, sign a message. Compare the results to an expected result.Passed
29Accounts without signing capability cannot sign signatures.Repeat test #27, however after confirming the account cannot sign messages, try and sign a message. Catch the thrown error message and compare it to the expected error.Passed
30Differing accounts signing the same message will produce differing signatures.Create two accounts from differing private keys, and have them sign the same message. Expect the signatures to not be the same.Passed
31Accounts signing separate messages will produce differing signatures.Create an account through a given private key, and sign two separate messages. Expect the two signatures to not be the same.Passed
32Accounts with signing capabilities can verify their signatures.Repeat test #28, however afterwards, request from the account itself it validate the signature. Expect it to return true.Passed
33Accounts without signing capabilities can verify their signatures.Repeat test #29, however after signing the message, create another account from the first accounts public key. With the new account, request from it that it validate the original signature. Expect it to return true.Passed
34Accounts cannot verify signatures which are invalid.Create an account from the account subsystem, and verify an invalid signature. Catch for an error message and compare it to the expected error message.Passed
35Accounts cannot verify signatures they did not sign.Repeat test #33, however create the second account out of a different public address. With the new account, request from it that it validate the original signature. Expect it to return false.Passed

Random Subsystem Tests

The random subsystem tests can be found in the seedSrc/helpers/random.js file.

#DescriptionProcedureResult
36Generates the proper Seed out of passed in hashes.Access the random subsystem and request a randomness seed value, passing in hashes. Compare the result with the expected result.Passed
37Throws an error message upon passing in undefined input into seeding generation.Repeat test #36, passing in undefined. Catch for errors and compare to the expected error message.Passed
38Throws an error message upon passing in a empty array as input into seeding generation.Repeat test #37, however passing in a empty array.Passed
39Generates expected pseudo random values based on passed in seed.Access the random subsystem and set the seed value to a set value. Request random ints and floats, comparing for expected values.Passed
40Randomness falls under a valid distribution.Access the random subsystem, set the seed value and request a random int from 1 to 10 one hundred thousand times. Compare the distribution, checking that there is no statistical significance between favouring numbers over each other.Passed

Block Subsystem Tests

The block subsystem tests can be found in the seedSrc/block.js file.

#DescriptionProcedureResult
41Block creation creates blocks with valid and accurate data, as well have as a correctly generated hash.Access the block subsystem and request to make a block, passing in the block data. Compare the block’s data and hash with expected values.Passed
42Validates that the block validation system is correct in positive cases.Access the block subsystem and request the creation of a valid block. Next, request block validation for the block. Expect the result to be positive.Passed
43Validates that the block validation system is correct in failing blocks which don’t meet block validation rule #1.Access the block subsystem and request the creation of a valid block in accordance to rule #1.Passed
44Validates that the block validation system is correct in failing blocks which don’t meet block validation rule #2.Run test #3, however the check is in accordance of rule #2.Passed
45An exception is thrown when an invalid block is checked for validation.Access the block subsystem and request the validation of a block, however pass in undefined. Check for a thrown error and compare to expected error.Passed

Transaction Subsystem Tests

The transaction subsystem tests can be found in the seedSrc/transaction.js file.

#DescriptionProcedureResult
46Transaction creation creates transactions with valid and accurate data, as well have as a correctly generated hash.Access the transaction subsystem and request to make a transaction, passing in the transaction data. Compare the transaction’s data and hash with expected values.Passed
47Validates that the transaction validation system is correct in positive cases.Access the transaction subsystem and request the creation of a valid transaction. Next, request transaction validation for the transaction. Expect the result to be positive.Passed
48Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #1.Access the transaction subsystem and request the creation of a valid transaction in accordance to rule #1.Passed
49Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #2.Run test #48 however the check is in accordance of rule #2.Passed
50Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #3.Run test #48 however the check is in accordance of rule #3.Passed
51Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #4.Run test #48 however the check is in accordance of rule #4.Passed
52Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #5.Run test #48 however the check is in accordance of rule #5.Passed
53Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #6.Run test #48 however the check is in accordance of rule #6.Passed
54Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #7.Run test #48 however the check is in accordance of rule #7.Passed
55Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #8.Run test #48 however the check is in accordance of rule #8.Passed
56Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #9.Run test #48 however the check is in accordance of rule #9.Passed
57Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #10.Run test #48 however the check is in accordance of rule #10.Passed
58Validates that the transaction validation system is correct in failing transactions which don’t meet transaction validation rule #11.Run test #48 however the check is in accordance of rule #11.Passed
59An exception is thrown when an invalid transaction is checked for validation.Access the transaction subsystem and request the validation of a transaction, however pass in undefined. Check for a thrown error and compare to expected error.Passed

Squasher Subsystem Tests

The squasher subsystem tests can be found in the seedSrc/squasher.js file.

#DescriptionProcedureResult
60Confirms squasher would trigger on proper hashes for valid cases.Access the squashing subsystem and invoke the trigger check, passing into it a positive case hash. Expect the result to return true.Passed
61Confirms squasher would not trigger on a invalid hash.Access the squashing subsystem and invoke the trigger check, passing into it a negative case hash. Expect the result to return false.Passed
62Confirms squashing two objects works properly while following the “relative data” squashing rules.Access the squashing subsystem and invoke the squashing mechanism, passing in two objects where all the variables are numbers. The squashed result should be one object with the relative values added, as if two vectors were added.Passed
63Confirms squashing two objects works properly while following the “absolute data” squashing rules.Run test #62, however have the variables in the objects be strings, and overwrite the strings assuming the later parameters were the recent changes.Passed
64Confirms order matters with “absolute data” rules, with rearranging order changing the squashed result.Run test #63, however run a second instance where the parameters were in a differing order, and then confirm that the squashed objects do not match.Passed
65Confirm squashing transactions into a block produced a valid block.Access the squashing subsystem and squash multiple transactions into a block. Confirm the block subsystem validates the newly created block.Passed
66Confirm squashing blocks into a block produced a valid block.Access the squashing subsystem and squash multiple blocks into a block. Confirm the block subsystem validates the newly created block.Passed

Entanglement Subsystem Tests

The entanglement subsystem tests can be found in the seedSrc/entanglement.js file.

#DescriptionProcedureResult
67Confirms transactions can be added to the entanglement.Access the entanglement subsystem and add a transaction to the entanglement. Confirm the transaction was added.Passed
68Confirms adding transactions fails if the transaction is invalid.Run test #67, however passing in a invalid transaction. Catch the thrown error, confirming that the caught error matches the expected error.Passed
69Confirms adding transactions fails if the transaction would cause a cycle in the directed acyclic graph.Run test #68, however passing in a transaction which is valid, however causes a cycle if added to the DAG.Passed
70Confirms adding transactions validates older ones.Access the entanglement subsystem and add multiple transactions to the entanglement, until the first is validated.Passed

Blockchain Subsystem Tests

The blockchain subsystem tests can be found in the seedSrc/blockchain.js file.

#DescriptionProcedureResult
71Confirms blocks can be added to the blockchains.Access the blockchains subsystem and add a block to the blockchain. Confirm the block was added.Passed
72Confirms adding blocks fails if the block is invalid.Run test #71, however passing in a invalid block. Catch the thrown error, confirming that the caught error matches the expected error.Passed
73Confirm blocks can invoke the block squashing mechanism if they have the right hash.Access the blockchains subsystem and add a block who’s hash would trigger squashing. Afterwards, confirm the added block does not exist in the blockchain, and that its transactions belong to a new block.Passed

Ledger Subsystem Tests

The ledger subsystem tests can be found in the seedSrc/ledger.js file.

#DescriptionProcedureResult
74Confirm that the ledger can be read from.Access the ledger subsystem and request a read, passing invalid parameters. Compare the results with the expected results.Passed
75Confirm the ledger can have changes applied to it which change the state of the ledger.Access the ledger subsystem and request to apply a “ChangeContext” object to it, modifying the ledgers state. Run test #71, reading for our newly saved information, confirming it was applied.Passed
76Confirm the ledger can create a deep copy of module data.Access the ledger subsystem and request a deep copy of module data. Confirm this data is proper. Afterwards, modify the data, and then read from the eldger. Confirm the ledger did not have its data change when the deep copy was changed.Passed
77Confirm numerous transactions can have their changes applied and get the correct result.Access the ledger subsystem and apply multiple transactions to the ledger. Confirm the state of the ledger matches expected results.Passed
78Confirm a block can have its changes applied to the ledger and get the correct result.Access the ledger subsystem and apply the block to the ledger. Confirm the state of the ledger matches expected results.Passed

Virtual Machine Subsystem Tests

The virtual machine subsystem tests can be found in the seedSrc/virtualMachine/virtualMachine.js file.

#DescriptionProcedureResult
79Confirm the virtual machine can have modules added to it and be stored in the ledger.Access the virtual machine subsystem and add a valid module to it. Access the ledger subsystem and validate that it has the modules data properly loaded.Passed
80Confirm the virtual machine can read a modules data from the ledger.Access the virtual machine subsystem and read module data. Confirm that the returned results matches expected results.Passed
81Confirm “getter” functions can be invoked to fetch Module data.Access the virtual machine subsystem and invoke a “getter” call to read a Module’s data. Compare the results with the expected results.Passed
82Confirm “setters” can be simulated.Access the virtual machine subsystem and invoke a “setter” call to modify a Modules state. Compare the results with the expected results.Passed
83Confirm “setters” can be invoked and the ledger updates accordingly.Access the virtual machine subsystem and invoke a “setter” call. Compare the results with the expected results, and confirm that the ledger change appropriately as well.Passed
84Confirm transactions can be added to the virtual machine, executing them and storing their changes to the ledger.Access the virtual machine subsystem and add a transaction too it. Confirm that the transaction was executed and it was added to the entanglement.Passed

File Storage Tests

The file storage tests can be found in the seedSrc/storage/fileSystemInjector.js file.

#DescriptionProcedureResult
85Confirm that transactions can be written to storage asynchronously.Create a FileStorageInjector object and invoke the its save transaction asynchronously passing in a valid transaction. Confirm that the transaction was saved.Passed
86Confirm that transactions can be written to storage synchronously.Create a FileStorageInjector object and invoke the its save transaction synchronously passing in a valid transaction. Confirm that the transaction was saved.Passed
87Confirm that blocks can be written to storage asynchronously.Create a FileStorageInjector object and invoke the its save block asynchronously passing in a valid transaction. Confirm that the block was saved.Passed
88Confirm that blocks can be written to storage synchronously.Create a FileStorageInjector object and invoke the its save block synchronously passing in a valid transaction. Confirm that the block was saved.Passed
89Confirm that FileStorage can read transactions synchronously.Create a FileStorageInjector object and through it invoke reading transactions synchronously. Load a transaction and compare its loaded data against expected results.Passed
90Confirm that FileStorage can read transactions asynchronously.Create a FileStorageInjector object and through it invoke reading transactions asynchronously. Load a transaction and compare its loaded data against expected results.Passed
91Confirm that FileStorage can read blocks synchronously.Create a FileStorageInjector object and through it invoke reading blocks synchronously. Load a block and compare its loaded data against expected results.Passed
92Confirm that FileStorage can read blocks asynchronously.Create a FileStorageInjector object and through it invoke reading transactions asynchronously. Load a transaction and compare its loaded data against expected results.Passed
93Confirm that transactions can be removed from storage.Create a FileStorageInjector object and remove a transaction from storage. Confirm the transaction no longer exists.Passed
94Confirm that blocks can be removed from storage.Create a FileStorageInjector object and remove a block from storage. Confirm the block no longer exists.Passed
95Confirm that FileStorage can read all transactions in the entanglement synchronously.Create a FileStorageInjector object and read all transactions in storage, building an entanglement. Compare this with the expected state of the entanglement.Passed
96Confirm that FileStorage can read all blocks for a generation from the blockchain synchronously.Create a FileStorageInjector object and read all blocks in storage for a given generation, building a blockchain. Compare this with the expected state of the blockchain.Passed
97Confirm that FileStorage can read all blocks for all generations of blockchains synchronously.Create a FileStorageInjector object and read all blocks in storage, building the blockchains. Compare this with the expected state of the blockchains.Passed

Local Storage Tests

The local storage tests can be found in the seedSrc/storage/localStorageInjector.js file.

#DescriptionProcedureResult
98Confirm that transactions can be written to storage asynchronously.Create a LocalStorageInjector object and invoke the its save transaction asynchronously passing in a valid transaction. Confirm that the transaction was saved.Passed
99Confirm that transactions can be written to storage synchronously.Create a LocalStorageInjector object and invoke the its save transaction synchronously passing in a valid transaction. Confirm that the transaction was saved.Passed
100Confirm that blocks can be written to storage asynchronously.Create a LocalStorageInjector object and invoke the its save block asynchronously passing in a valid transaction. Confirm that the block was saved.Passed
101Confirm that blocks can be written to storage synchronously.Create a LocalStorageInjector object and invoke the its save block synchronously passing in a valid transaction. Confirm that the block was saved.Passed
102Confirm that FileStorage can read transactions synchronously.Create a LocalStorageInjector object and through it invoke reading transactions synchronously. Load a transaction and compare its loaded data against expected results.Passed
103Confirm that FileStorage can read transactions asynchronously.Create a LocalStorageInjector object and through it invoke reading transactions asynchronously. Load a transaction and compare its loaded data against expected results.Passed
104Confirm that FileStorage can read blocks synchronously.Create a LocalStorageInjector object and through it invoke reading blocks synchronously. Load a block and compare its loaded data against expected results.Passed
105Confirm that FileStorage can read blocks asynchronously.Create a LocalStorageInjector object and through it invoke reading transactions asynchronously. Load a transaction and compare its loaded data against expected results.Passed
106Confirm that transactions can be removed from storage.Create a LocalStorageInjector object and remove a transaction from storage. Confirm the transaction no longer exists.Passed
107Confirm that blocks can be removed from storage.Create a LocalStorageInjector object and remove a block from storage. Confirm the block no longer exists.Passed
108Confirm that FileStorage can read all transactions in the entanglement synchronously.Create a LocalStorageInjector object and read all transactions in storage, building an entanglement. Compare this with the expected state of the entanglement.Passed
109Confirm that FileStorage can read all blocks for a generation from the blockchain synchronously.Create a LocalStorageInjector object and read all blocks in storage for a given generation, building a blockchain. Compare this with the expected state of the blockchain.Passed
110Confirm that FileStorage can read all blocks for all generations of blockchains synchronously.Create a LocalStorageInjector object and read all blocks in storage, building the blockchains. Compare this with the expected state of the blockchains.Passed

Storage Subsystem Tests

The storage subsystem tests can be found in the seedSrc/storage/storage.js file.

#DescriptionProcedureResult
111Confirm that Storage can save a transaction to the file system using FileStorageInjector.Access the storage subsystem and create a Storage object with a FIleStorageInjector, then save a transaction to file. Confirm the transaction was saved.Passed
112Confirm that Storage can save a block to the file system using FileStorageInjector.Access the storage subsystem and create a Storage object with a FIleStorageInjector, then save a block to file. Confirm the block was saved.Passed
113Confirm that Storage, using FileStorageInjector, can load all the initial ledger state, reading all blockchains/entanglement and applying all blocks/transactions to the virtual machine.Access the storage subsystem and create a Storage object with a FIleStorageInjector, then invoke the load from initial state function on the storage subsystem, then confirm the ledger, blockchain and entanglement states match the expected states.Passed
114Confirm that Storage can save a transaction to local storage using LocalStorageInjector.Access the storage subsystem and create a Storage object with a LocalStorageInjector, then save a transaction to local storage. Confirm the transaction was saved.Passed
115Confirm that Storage can save a block to local storage using LocalStorageInjector.Access the storage subsystem and create a Storage object with a LocalStorageInjector, then save a block to local storage. Confirm the block was saved.Passed
116Confirm that Storage, using LocalStorageInjector, can load all the initial ledger state, reading all blockchains/entanglement and applying all blocks/transactions to the virtual machine.Access the storage subsystem and create a Storage object with a LocalStorageInjector, then invoke the load from initial state function on the storage subsystem, then confirm the ledger, blockchain and entanglement states match the expected states.Passed

Messaging System Tests

The messaging subsystem tests can be found in the seedSrc/messaging.js file.

#DescriptionProcedureResult
117Confirm the ability to subscribe for messages relating to module function callbacks being executed in the ledger machine.Access the messaging subsystem and subscribe for a function callback. Afterwards, invoke a transaction which matches the subscribed message. Confirm that the callback was invoked.Passed
118Confirm the ability to subscribe for messages relating to module data changes callbacks being executed in the ledger machine.Access the messaging subsystem and subscribe for a module data change callback. Afterwards, invoke a transaction which changes the piece of data the above is listening on. Confirm that the callback was invoked.Passed
119Confirm the ability to unsubscribe from messaging.Run tests #117 and #118, and then unsubscribe the two callbacks. Confirm that the callbacks were unsubscribed.Passed
120Confirm, once unsubscribed, previously invokable callbacks stop being invoked.Run test #119, however after unsubscribing, invoke a transaction which would trigger both callbacks. Confirm neither are invoked.Passed

References

  1. Seed - Design - Unit Testing

GitHub

https://github.com/CarsonRoscoe

Pull Request

https://github.com/Cajarty/Seed/pull/8

Sort:  
  • Very beautiful formatting both on STEEM and github all at once.
  • Great job on the test and explaining why it's important.
  • Ironically, I would suggest that you run your tests on more platforms like linux to make sure it does run and that no globally installed program works for you and not others.
  • There are some funny business with case sensitiveness of file names on Macs, beware!
  • Now with the errors:
    • Error: Cannot find module './localStorageInjector.js'
      fixed with : git mv seedSrc/storage/LocalStorageInjector.js seedSrc/storage/localStorageInjector.js
    • Error: Cannot find module 'elliptic'
      that's because you first need to npm iboth folders clientSrc and seedSrc.
    • sh: 1: Electron: not found was fixed by including the path of the locally installed electron from npm and using this one to start.
    • You should .gitignore the .DS_Store files from your repo.
  • I've created a pull request with the fixes: https://github.com/Cajarty/Seed/pull/9/

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @helo!

So far this week you've reviewed 2 contributions. Keep up the good work!

Wow, thank you very much for not only catching the errors and testing it on Linux, but also fixing the errors. Your changes were reviewed and approved.

I have Windows 10 and Fedora Linux on my Mac, however I've gotten lazy and am not in the habit of testing this project on the other platforms yet (mainly because no one else has claimed to have ran it other than my partner, who also uses Mac). I will make begin testing on all platforms from now on!

Thank you for your kind review

Hi @carsonroscoe!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @carsonroscoe!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

You have a minor misspelling in the following sentence:

| Create an account through a given private key, and sign two seperate messages.
It should be separate instead of seperate.