bitcoin 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metadata +17 -288
- data/.rspec +0 -1
- data/.rvmrc +0 -1
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -98
- data/Guardfile +0 -38
- data/README.markdown +0 -24
- data/Rakefile +0 -1
- data/bin/rbcoin +0 -8
- data/bitcoin.gemspec +0 -40
- data/config/cucumber.yml +0 -5
- data/config/darcs.boring +0 -121
- data/doc/DEFINITION_OF_DONE.markdown +0 -12
- data/doc/HISTORY.markdown +0 -19
- data/doc/LICENCE.markdown +0 -25
- data/doc/TODO.markdown +0 -31
- data/doc/UBIQUITOUS_LANGUAGE.markdown +0 -15
- data/features/descriptions/command_help.feature +0 -31
- data/features/descriptions/satoshi_wallet/add_address.feature +0 -49
- data/features/descriptions/satoshi_wallet/show_addresses.feature +0 -18
- data/features/descriptions/satoshi_wallet/show_version.feature +0 -17
- data/features/descriptions/satoshi_wallet/subcommand_help.feature +0 -20
- data/features/fixtures/ABOUT_FIXTURES.markdown +0 -6
- data/features/fixtures/addressbook_wallet.dat +0 -0
- data/features/fixtures/new_wallet.dat +0 -0
- data/features/step_definitions/command_steps.rb +0 -3
- data/features/step_definitions/wallet_steps.rb +0 -11
- data/features/support/env.rb +0 -9
- data/lib/bitcoin.rb +0 -5
- data/lib/bitcoin/cli.rb +0 -35
- data/lib/bitcoin/commands.rb +0 -3
- data/lib/bitcoin/commands/help_command.rb +0 -32
- data/lib/bitcoin/commands/satoshi_wallet.rb +0 -11
- data/lib/bitcoin/commands/satoshi_wallet/add_address_command.rb +0 -61
- data/lib/bitcoin/commands/satoshi_wallet/show_addresses_command.rb +0 -16
- data/lib/bitcoin/commands/satoshi_wallet/show_version_command.rb +0 -15
- data/lib/bitcoin/commands/satoshi_wallet_command.rb +0 -37
- data/lib/bitcoin/commands/satoshi_wallet_command_environment.rb +0 -28
- data/lib/bitcoin/console/capturing_stream_bundle.rb +0 -42
- data/lib/bitcoin/console/stream_bundle.rb +0 -21
- data/lib/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository.rb +0 -155
- data/lib/bitcoin/data_access/satoshi/satoshi_version.rb +0 -58
- data/lib/bitcoin/data_access/satoshi/satoshi_wallet.rb +0 -39
- data/lib/bitcoin/domain/address_book.rb +0 -19
- data/lib/bitcoin/domain/bitcoin_address.rb +0 -33
- data/lib/bitcoin/filesystem/empty_temp_dir.rb +0 -74
- data/lib/bitcoin/rspec/argument_matchers.rb +0 -1
- data/lib/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher.rb +0 -23
- data/lib/bitcoin/rspec/directory_helpers.rb +0 -22
- data/lib/bitcoin/version.rb +0 -3
- data/spec/bitcoin/cli_spec.rb +0 -128
- data/spec/bitcoin/commands/help_command_spec.rb +0 -53
- data/spec/bitcoin/commands/satoshi_wallet/add_address_command_spec.rb +0 -149
- data/spec/bitcoin/commands/satoshi_wallet/show_addresses_command_spec.rb +0 -26
- data/spec/bitcoin/commands/satoshi_wallet/show_version_command_spec.rb +0 -26
- data/spec/bitcoin/commands/satoshi_wallet_command_environment_spec.rb +0 -76
- data/spec/bitcoin/commands/satoshi_wallet_command_spec.rb +0 -73
- data/spec/bitcoin/console/_contracts/stream_bundle_contract.rb +0 -29
- data/spec/bitcoin/console/capturing_stream_bundle_spec.rb +0 -74
- data/spec/bitcoin/console/stream_bundle_spec.rb +0 -13
- data/spec/bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository_spec.rb +0 -78
- data/spec/bitcoin/data_access/satoshi/satoshi_version_spec.rb +0 -112
- data/spec/bitcoin/data_access/satoshi/satoshi_wallet_spec.rb +0 -102
- data/spec/bitcoin/domain/address_book_spec.rb +0 -63
- data/spec/bitcoin/domain/bitcoin_address_spec.rb +0 -52
- data/spec/bitcoin/filesystem/empty_temp_dir_spec.rb +0 -170
- data/spec/bitcoin/rspec/argument_matchers/block_evaluating_to_matcher_spec.rb +0 -36
- data/spec/spec_helper.rb +0 -29
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/data_access/satoshi/bdb_satoshi_wallet_repository'
|
4
|
-
require 'bitcoin/rspec/directory_helpers'
|
5
|
-
|
6
|
-
module Bitcoin
|
7
|
-
module DataAccess
|
8
|
-
module Satoshi
|
9
|
-
describe BDBSatoshiWalletRepository, adapter: :slow do
|
10
|
-
include Bitcoin::RSpec::DirectoryHelpers
|
11
|
-
|
12
|
-
TEMP_DB_DIR = File.join(PROJECT_ROOT, "tmp", "db").freeze
|
13
|
-
ensure_empty_test_dir(TEMP_DB_DIR)
|
14
|
-
|
15
|
-
# Temporary means to get a copy of the fixture file
|
16
|
-
before(:each) do
|
17
|
-
FileUtils.cp(File.join(PROJECT_ROOT, "features", "fixtures", wallet_fixture_filename), TEMP_DB_DIR)
|
18
|
-
end
|
19
|
-
|
20
|
-
def wallet_filename
|
21
|
-
File.join(PROJECT_ROOT, "tmp", "db", wallet_fixture_filename)
|
22
|
-
end
|
23
|
-
|
24
|
-
let(:wallet_fixture_filename) { "addressbook_wallet.dat" }
|
25
|
-
|
26
|
-
subject { BDBSatoshiWalletRepository.new(wallet_filename, db_dirname: TEMP_DB_DIR) }
|
27
|
-
|
28
|
-
it "has a less naive write_compact_size"
|
29
|
-
|
30
|
-
describe "4-byte unsigned little endian integers stored immediately (no compact length in the value)" do
|
31
|
-
specify {
|
32
|
-
subject.get_value_immediate_uint32le("version").should eq 32400
|
33
|
-
}
|
34
|
-
|
35
|
-
specify {
|
36
|
-
expect {
|
37
|
-
subject.set_value_immediate_uint32le("version", 32500)
|
38
|
-
}.to change {
|
39
|
-
subject.get_value_immediate_uint32le("version")
|
40
|
-
}.from(32400).to(32500)
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "string key data, string value data" do
|
45
|
-
it "lets you read all values" do
|
46
|
-
subject.get_key_and_value_data_string_utf8("name").should eq [
|
47
|
-
[ "13f2t2WKnCZh1rZbDhdUKB6fY1rZNWZVzd", "Receiving address 2" ],
|
48
|
-
[ "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", "Bitcoin Monitor" ],
|
49
|
-
[ "16kzGRdP8LToECecna3EynghiApUM9duLw", "Receiving address 1" ],
|
50
|
-
[ "1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw", "Bitcoincharts" ]
|
51
|
-
]
|
52
|
-
end
|
53
|
-
|
54
|
-
it "lets you read individual values" do
|
55
|
-
subject.get_value_with_key_data_string_utf8("name", "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz").should eq "Bitcoin Monitor"
|
56
|
-
end
|
57
|
-
|
58
|
-
it "lets you create" do
|
59
|
-
expect {
|
60
|
-
subject.set_value_with_key_data_string_utf8("name", "1ThisIsAMadeUpKeyKudFr63EwHqQT2njz", "New Value")
|
61
|
-
}.to change {
|
62
|
-
subject.get_value_with_key_data_string_utf8("name", "1ThisIsAMadeUpKeyKudFr63EwHqQT2njz")
|
63
|
-
}.from(nil).to("New Value")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "lets you update" do
|
67
|
-
expect {
|
68
|
-
subject.set_value_with_key_data_string_utf8("name", "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", "Really is Bitcoin Monitor")
|
69
|
-
}.to change {
|
70
|
-
subject.get_value_with_key_data_string_utf8("name", "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz")
|
71
|
-
}.from("Bitcoin Monitor").to("Really is Bitcoin Monitor")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
@@ -1,112 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/data_access/satoshi/satoshi_version'
|
4
|
-
|
5
|
-
module Bitcoin
|
6
|
-
module DataAccess
|
7
|
-
module Satoshi
|
8
|
-
describe SatoshiVersion do
|
9
|
-
describe ".from_wallet_bytes" do
|
10
|
-
it "supports the data format as extracted from the BDB database" do
|
11
|
-
SatoshiVersion.from_wallet_bytes([144, 126, 0, 0]).should eq SatoshiVersion.new(0, 3, 24)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe ".from_wallet_int" do
|
16
|
-
it "supports the data format as extracted from the BDB database" do
|
17
|
-
SatoshiVersion.from_wallet_int(32400).should eq SatoshiVersion.new(0, 3, 24)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "three-part form" do
|
22
|
-
it "compares equality" do
|
23
|
-
SatoshiVersion.new(0, 3, 24).should eq SatoshiVersion.new(0, 3, 24)
|
24
|
-
|
25
|
-
SatoshiVersion.new(0, 3, 24).should_not eq SatoshiVersion.new(0, 3, 25)
|
26
|
-
SatoshiVersion.new(0, 3, 24).should_not eq SatoshiVersion.new(0, 4, 24)
|
27
|
-
SatoshiVersion.new(0, 3, 24).should_not eq SatoshiVersion.new(1, 3, 24)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "has a total ordering" do
|
31
|
-
SatoshiVersion.new(0, 3, 24).should be < SatoshiVersion.new(0, 3, 25)
|
32
|
-
SatoshiVersion.new(0, 3, 24).should be > SatoshiVersion.new(0, 3, 23)
|
33
|
-
|
34
|
-
SatoshiVersion.new(0, 3, 24).should be < SatoshiVersion.new(0, 4, 23)
|
35
|
-
SatoshiVersion.new(0, 3, 24).should be > SatoshiVersion.new(0, 2, 25)
|
36
|
-
|
37
|
-
SatoshiVersion.new(1, 3, 24).should be < SatoshiVersion.new(2, 2, 23)
|
38
|
-
SatoshiVersion.new(1, 3, 24).should be > SatoshiVersion.new(0, 4, 25)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "four-part form" do
|
43
|
-
# We cheat slightly here and make assumptions about the implementation
|
44
|
-
# (by not re-specifying every conceivable possibility)
|
45
|
-
|
46
|
-
it "compares equality" do
|
47
|
-
SatoshiVersion.new(0, 3, 24, 0).should eq SatoshiVersion.new(0, 3, 24, 0)
|
48
|
-
SatoshiVersion.new(0, 3, 24, 0).should_not eq SatoshiVersion.new(0, 3, 24, 1)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "has a total ordering" do
|
52
|
-
SatoshiVersion.new(0, 3, 24, 1).should be < SatoshiVersion.new(0, 3, 25, 2)
|
53
|
-
SatoshiVersion.new(0, 3, 24, 1).should be > SatoshiVersion.new(0, 3, 23, 0)
|
54
|
-
|
55
|
-
SatoshiVersion.new(0, 3, 24, 1).should be < SatoshiVersion.new(0, 3, 25, 0)
|
56
|
-
SatoshiVersion.new(0, 3, 24, 1).should be > SatoshiVersion.new(0, 3, 23, 2)
|
57
|
-
|
58
|
-
# etc, for the rest of the components...
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "-beta version suffixes" do
|
63
|
-
it "are not supported", because: "this is hardcoded into the Satoshi client" do
|
64
|
-
# As of 0.3.24, the "beta" status is determined in the C++ code with this value:
|
65
|
-
# static const bool VERSION_IS_BETA = true;
|
66
|
-
false.should be_false
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "comparing three- and four-part forms" do
|
71
|
-
# This is not explicit in the Satoshi code, but seems a reasonable assumption for now,
|
72
|
-
# until it breaks...
|
73
|
-
it "assumes an implicit 0 at the end of the three-part form" do
|
74
|
-
SatoshiVersion.new(0, 3, 24).should eq SatoshiVersion.new(0, 3, 24, 0)
|
75
|
-
SatoshiVersion.new(0, 3, 24, 0).should eq SatoshiVersion.new(0, 3, 24)
|
76
|
-
# it seems safe to assume the rest of the comparisons work by induction
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe "conversion" do
|
81
|
-
describe "to strings" do
|
82
|
-
it "supports #to_s", because: "we need to be usable with IO#<<" do
|
83
|
-
SatoshiVersion.new(0, 3, 24).to_s.should eq "0.3.24"
|
84
|
-
SatoshiVersion.new(0, 3, 24, 1).to_s.should eq "0.3.24.1"
|
85
|
-
end
|
86
|
-
|
87
|
-
it "truncates a fourth zero", because: "the standard client does this (semantic versioning?)" do
|
88
|
-
SatoshiVersion.new(0, 3, 24, 0).to_s.should eq "0.3.24"
|
89
|
-
end
|
90
|
-
|
91
|
-
it "does not truncate a third version", because: "the standard client does this (semantic versioning?)" do
|
92
|
-
SatoshiVersion.new(0, 4, 0).to_s.should eq "0.4.0"
|
93
|
-
end
|
94
|
-
|
95
|
-
it "supports #to_str as an alias of :to_s" do
|
96
|
-
version = SatoshiVersion.new(0, 3, 24)
|
97
|
-
to_s_method = version.method(:to_s)
|
98
|
-
to_str_method = version.method(:to_str)
|
99
|
-
to_str_method.should eq to_s_method
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe "to Satoshi-format wallet bytes" do
|
104
|
-
it "creates the same bytes as came from the BDB database" do
|
105
|
-
SatoshiVersion.new(0, 3, 24).to_wallet_bytes.should eq [144, 126, 0, 0]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/data_access/satoshi/satoshi_wallet'
|
4
|
-
|
5
|
-
module Bitcoin
|
6
|
-
module DataAccess
|
7
|
-
module Satoshi
|
8
|
-
describe SatoshiWallet do
|
9
|
-
describe ".open" do
|
10
|
-
let(:satoshi_wallet_repository) { mock(BDBSatoshiWalletRepository) }
|
11
|
-
let(:satoshi_wallet) { mock(SatoshiWallet) }
|
12
|
-
|
13
|
-
before(:each) do
|
14
|
-
BDBSatoshiWalletRepository.stub(new: satoshi_wallet_repository)
|
15
|
-
SatoshiWallet.stub(new: satoshi_wallet)
|
16
|
-
end
|
17
|
-
|
18
|
-
it "makes a BDBSatoshiWalletRepository" do
|
19
|
-
BDBSatoshiWalletRepository.should_receive(:new).with("wallet.dat", db_dirname: "/db/dir")
|
20
|
-
SatoshiWallet.open(wallet_filename: "wallet.dat", db_dirname: "/db/dir", & ->(wallet) { :noop })
|
21
|
-
end
|
22
|
-
|
23
|
-
it "makes a SatoshiWallet with the BDBSatoshiWalletRepository" do
|
24
|
-
SatoshiWallet.should_receive(:new).with(satoshi_wallet_repository)
|
25
|
-
SatoshiWallet.open(wallet_filename: "wallet.dat", db_dirname: "/db/dir", & ->(wallet) { :noop })
|
26
|
-
end
|
27
|
-
|
28
|
-
it "yields the wallet" do
|
29
|
-
SatoshiWallet.open(wallet_filename: "wallet.dat", db_dirname: "/db/dir") do |wallet|
|
30
|
-
wallet.should eq satoshi_wallet
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
it "returns the value of the block" do
|
35
|
-
SatoshiWallet.open(wallet_filename: "wallet.dat", db_dirname: "/db/dir") { |wallet|
|
36
|
-
:block_value
|
37
|
-
}.should eq :block_value
|
38
|
-
end
|
39
|
-
|
40
|
-
it "raises an error if no block is given", because: "we use blocks to manage the opening and closing of the BDB database" do
|
41
|
-
expect {
|
42
|
-
SatoshiWallet.open(wallet_filename: "wallet.dat", db_dirname: "/db/dir")
|
43
|
-
}.to raise_error(ArgumentError) { |error|
|
44
|
-
error.message.should =~ /you must provide a block to SatoshiWallet\.new/i
|
45
|
-
}
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe "instance methods" do
|
50
|
-
let(:satoshi_wallet_repository) { mock(BDBSatoshiWalletRepository) }
|
51
|
-
|
52
|
-
before(:each) do
|
53
|
-
BDBSatoshiWalletRepository.stub(new: satoshi_wallet_repository)
|
54
|
-
end
|
55
|
-
|
56
|
-
subject { SatoshiWallet.new(satoshi_wallet_repository) }
|
57
|
-
|
58
|
-
describe "#version" do
|
59
|
-
it "returns the version from the wallet" do
|
60
|
-
satoshi_wallet_repository.should_receive(:get_value_immediate_uint32le).with("version").and_return(32400)
|
61
|
-
subject.version.should eq SatoshiVersion.new(0, 3, 24)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "#addresses" do
|
66
|
-
before(:each) do
|
67
|
-
satoshi_wallet_repository.stub(
|
68
|
-
get_key_and_value_data_string_utf8: [
|
69
|
-
[ "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", "Bitcoin Monitor" ],
|
70
|
-
[ "1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw", "Bitcoincharts" ]
|
71
|
-
]
|
72
|
-
)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "fetches the data" do
|
76
|
-
satoshi_wallet_repository.should_receive(:get_key_and_value_data_string_utf8).with("name")
|
77
|
-
subject.addresses
|
78
|
-
end
|
79
|
-
|
80
|
-
it "returns an AddressBook with the wallet addresses" do
|
81
|
-
subject.addresses.should be_a Domain::AddressBook
|
82
|
-
expected_addresses = Domain::AddressBook.new([
|
83
|
-
{ address: Domain::BitcoinAddress.new("14Z1mazY4HfysZyMaKudFr63EwHqQT2njz"), name: "Bitcoin Monitor" },
|
84
|
-
{ address: Domain::BitcoinAddress.new("1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw"), name: "Bitcoincharts" }
|
85
|
-
]).to_a
|
86
|
-
subject.addresses.to_a.should =~ expected_addresses
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#add_address" do
|
91
|
-
it "adds the BitcoinAddress to the Wallet" do
|
92
|
-
satoshi_wallet_repository.should_receive(:set_value_with_key_data_string_utf8).with(
|
93
|
-
"name", "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", "Bitcoin Monitor"
|
94
|
-
)
|
95
|
-
subject.add_address(Domain::BitcoinAddress.new("14Z1mazY4HfysZyMaKudFr63EwHqQT2njz"), name: "Bitcoin Monitor")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/domain/address_book'
|
4
|
-
|
5
|
-
module Bitcoin
|
6
|
-
module Domain
|
7
|
-
describe AddressBook do
|
8
|
-
context "made with no addresses" do
|
9
|
-
subject { AddressBook.new }
|
10
|
-
its(:to_a) { should eq [ ] }
|
11
|
-
end
|
12
|
-
|
13
|
-
context "made with addresses" do
|
14
|
-
let(:address_hashes) {
|
15
|
-
[
|
16
|
-
{ address: "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", name: "Bitcoin Monitor" },
|
17
|
-
{ address: "1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw", name: "Bitcoincharts" }
|
18
|
-
]
|
19
|
-
}
|
20
|
-
|
21
|
-
subject {
|
22
|
-
AddressBook.new(address_hashes)
|
23
|
-
}
|
24
|
-
|
25
|
-
its(:to_a) {
|
26
|
-
should =~ [
|
27
|
-
{ address: "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz", name: "Bitcoin Monitor" },
|
28
|
-
{ address: "1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw", name: "Bitcoincharts" }
|
29
|
-
]
|
30
|
-
}
|
31
|
-
|
32
|
-
# We're assuming the output comes out in the input order, so this example is
|
33
|
-
# overly precise until we know how we'll handle presentation
|
34
|
-
its(:to_s) {
|
35
|
-
should eq(
|
36
|
-
-%{
|
37
|
-
14Z1mazY4HfysZyMaKudFr63EwHqQT2njz Bitcoin Monitor
|
38
|
-
1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw Bitcoincharts
|
39
|
-
}
|
40
|
-
)
|
41
|
-
}
|
42
|
-
|
43
|
-
describe "argument cloning" do
|
44
|
-
# Ensure this is created before we try changing the input arguments
|
45
|
-
before(:each) { subject }
|
46
|
-
|
47
|
-
it "does not mutate the args" do
|
48
|
-
expect {
|
49
|
-
address_hashes.delete_if { true }
|
50
|
-
}.to_not change {
|
51
|
-
subject.to_a.length
|
52
|
-
}.from(2).to(0)
|
53
|
-
end
|
54
|
-
|
55
|
-
it "makes a deep copy" do
|
56
|
-
address_hashes.first[:name] = "changed"
|
57
|
-
subject.to_a.map { |hash| hash[:name] }.should_not include("changed")
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/domain/bitcoin_address'
|
4
|
-
|
5
|
-
module Bitcoin
|
6
|
-
module Domain
|
7
|
-
describe BitcoinAddress do
|
8
|
-
context "created with a valid real network address" do
|
9
|
-
subject { BitcoinAddress.new("14Z1mazY4HfysZyMaKudFr63EwHqQT2njz") }
|
10
|
-
|
11
|
-
its(:to_s) { should eq "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz" }
|
12
|
-
|
13
|
-
describe "#==" do
|
14
|
-
it "is equal to another BitcoinAddress with the same address" do
|
15
|
-
subject.should eq BitcoinAddress.new("14Z1mazY4HfysZyMaKudFr63EwHqQT2njz")
|
16
|
-
end
|
17
|
-
|
18
|
-
it "is not equal to a BitcoinAddress with a different address" do
|
19
|
-
subject.should_not eq BitcoinAddress.new("1Nqr3MqVyUp6k3o3QPePAdn4Yg4tzgB9kw")
|
20
|
-
end
|
21
|
-
|
22
|
-
it "is not equal to a String" do
|
23
|
-
subject.should_not eq "14Z1mazY4HfysZyMaKudFr63EwHqQT2njz"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "creating with an invalid address" do
|
29
|
-
invalid_addresses = [
|
30
|
-
# Not actually sure the reasons here are valid in general but it's just enough to
|
31
|
-
# get us going (the point of the exercise is to put an error protocol in place)
|
32
|
-
{ address: "14Z1mazY4HfysZyMaKudFr63EwHqQT2nj", because: "this is too short" },
|
33
|
-
{ address: "14Z1mazY4HfysZyMaKudFr63EwHqQT2njzX", because: "this is too long" }
|
34
|
-
# Hash doesn't match
|
35
|
-
# Wrong version
|
36
|
-
# ... etc ...
|
37
|
-
# (When we know more about Bitcoin crypto we can come back and finish this off)
|
38
|
-
]
|
39
|
-
|
40
|
-
invalid_addresses.each do |invalid_address|
|
41
|
-
it "raises an error for address #{invalid_address[:address]} because #{invalid_address[:because]}" do
|
42
|
-
expect {
|
43
|
-
BitcoinAddress.new(invalid_address[:address])
|
44
|
-
}.to raise_error(BitcoinAddress::InvalidBitcoinAddressError) { |error|
|
45
|
-
error.message.should eq %'The address "#{invalid_address[:address]}" is not a valid Bitcoin address'
|
46
|
-
}
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,170 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'bitcoin/filesystem/empty_temp_dir'
|
4
|
-
require 'bitcoin/rspec/directory_helpers'
|
5
|
-
|
6
|
-
module Bitcoin
|
7
|
-
module FileSystem
|
8
|
-
describe EmptyTempDir do
|
9
|
-
include Bitcoin::RSpec::DirectoryHelpers
|
10
|
-
|
11
|
-
TEMP_TEST_DIR = File.join(PROJECT_ROOT, "tmp", "test").freeze
|
12
|
-
|
13
|
-
ensure_empty_test_dir(TEMP_TEST_DIR)
|
14
|
-
|
15
|
-
describe ".open" do
|
16
|
-
describe "integration" do # refactoring invariant
|
17
|
-
it "lets you create a temporary file inside the temporary directory" do
|
18
|
-
expected_temp_dir_name = File.join(TEMP_TEST_DIR, "temp_dir")
|
19
|
-
|
20
|
-
EmptyTempDir.open(with_name: "temp_dir", parallel_to: File.join(TEMP_TEST_DIR, "wallet.dat")) do |temp_dir|
|
21
|
-
File.open(File.join(temp_dir.absolute_path, "test_file"), "w") do |file|
|
22
|
-
file << "some unimportant contents"
|
23
|
-
end
|
24
|
-
Dir.entries(temp_dir.absolute_path).should eq %w[ . .. test_file ]
|
25
|
-
end
|
26
|
-
|
27
|
-
File.exist?(expected_temp_dir_name).should be_false
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "interactions" do
|
32
|
-
let(:block_runner) { mock(EmptyTempDir::BlockRunner, run: :block_runner_run_value) }
|
33
|
-
|
34
|
-
before(:each) do
|
35
|
-
EmptyTempDir::BlockRunner.stub(new: block_runner)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "raises an error if no block is provided", because: "this would be a pointless thing to do" do
|
39
|
-
expect {
|
40
|
-
EmptyTempDir.open(with_name: "temp_dir", parallel_to: File.join(TEMP_TEST_DIR, "wallet.dat"))
|
41
|
-
}.to raise_error(ArgumentError) { |error|
|
42
|
-
error.message.should =~ /you must provide a block to EmptyTempDir\.open/i
|
43
|
-
}
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "creating the BlockRunner" do
|
47
|
-
it "calculates a directory name parallel to the file" do
|
48
|
-
EmptyTempDir::BlockRunner.should_receive(:new).with("/foo/bar/temp_dir")
|
49
|
-
EmptyTempDir.open(with_name: "temp_dir", parallel_to: "/foo/bar/baz", & -> { :noop })
|
50
|
-
end
|
51
|
-
|
52
|
-
it "always passed absolute directories" do
|
53
|
-
EmptyTempDir::BlockRunner.should_receive(:new).with(File.join(PROJECT_ROOT, "/foo/bar/anything"))
|
54
|
-
EmptyTempDir.open(with_name: "anything", parallel_to: "foo/bar/baz", & -> { :noop })
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
it "runs the block" do
|
59
|
-
block = -> { :block_value }
|
60
|
-
block_runner.should_receive(:run).with(block_evaluating_to(:block_value))
|
61
|
-
EmptyTempDir.open(with_name: "anything", parallel_to: "/foo/bar/baz", &block)
|
62
|
-
end
|
63
|
-
|
64
|
-
it "returns the value of the block" do
|
65
|
-
EmptyTempDir.open(with_name: "temp_dir", parallel_to: "/foo/bar/baz", & -> { :noop }).should eq :block_runner_run_value
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe EmptyTempDir::BlockRunner do
|
71
|
-
describe ".new" do
|
72
|
-
# Yes, I actually did this to myself.
|
73
|
-
describe "raising an error on unsafe paths", because: "otherwise it could format your hard drive!" do
|
74
|
-
[ "", "/", "//" ].each do |unacceptable_path|
|
75
|
-
it "blocks #{unacceptable_path.inspect}" do
|
76
|
-
expect {
|
77
|
-
EmptyTempDir::BlockRunner.new(unacceptable_path)
|
78
|
-
}.to raise_error(ArgumentError) { |error|
|
79
|
-
error.message.should eq "Unacceptable directory name for EmptyTempDir"
|
80
|
-
}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
describe "#run" do
|
87
|
-
shared_examples "EmptyTempDir::BlockRunner#run" do
|
88
|
-
let(:expected_temp_dir_name) { File.join(TEMP_TEST_DIR, "temp_dir") }
|
89
|
-
subject { EmptyTempDir::BlockRunner.new(expected_temp_dir_name) }
|
90
|
-
|
91
|
-
it "ensures the directory exists" do
|
92
|
-
subject.run(
|
93
|
-
->(temp_dir) { File.directory?(expected_temp_dir_name) }
|
94
|
-
).should be_true
|
95
|
-
end
|
96
|
-
|
97
|
-
it "ensures the directory is empty" do
|
98
|
-
subject.run(
|
99
|
-
->(temp_dir) { Dir.entries(expected_temp_dir_name) }
|
100
|
-
).should =~ %w[ . .. ]
|
101
|
-
end
|
102
|
-
|
103
|
-
it "removes the directory at the end (even if a file was created inside it)" do
|
104
|
-
subject.run(
|
105
|
-
->(temp_dir) {
|
106
|
-
File.open(File.join(temp_dir.absolute_path, "test_file"), "w") do |file|
|
107
|
-
file << "unimportant contents"
|
108
|
-
end
|
109
|
-
Dir.entries(temp_dir.absolute_path).should eq %w[ . .. test_file ]
|
110
|
-
}
|
111
|
-
)
|
112
|
-
|
113
|
-
File.exist?(expected_temp_dir_name).should be_false
|
114
|
-
end
|
115
|
-
|
116
|
-
it "removes the directory even if the block raises an error" do
|
117
|
-
expect {
|
118
|
-
subject.run(->(temp_dir) { raise RuntimeError.new("I'm trying to make the temp dir persist!") })
|
119
|
-
}.to raise_error
|
120
|
-
|
121
|
-
File.exist?(expected_temp_dir_name).should be_false
|
122
|
-
end
|
123
|
-
|
124
|
-
it "re-raises any error thrown in the block" do
|
125
|
-
expected_error = RuntimeError.new("I'm trying to make the temp dir persist!")
|
126
|
-
|
127
|
-
expect {
|
128
|
-
subject.run(->(temp_dir) { raise expected_error })
|
129
|
-
}.to raise_error { |actual_error|
|
130
|
-
actual_error.should equal expected_error
|
131
|
-
}
|
132
|
-
end
|
133
|
-
|
134
|
-
it "has the expected path name" do
|
135
|
-
subject.run(->(temp_dir) { temp_dir.absolute_path.should eq expected_temp_dir_name })
|
136
|
-
end
|
137
|
-
|
138
|
-
it "returns the value of the block", because: "all the examples rely on this" do
|
139
|
-
subject.run(->(temp_dir) {
|
140
|
-
:block_value
|
141
|
-
}).should eq :block_value
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context "where the target directory does not exist" do
|
146
|
-
before(:each) do
|
147
|
-
FileUtils.rm_rf(expected_temp_dir_name)
|
148
|
-
end
|
149
|
-
|
150
|
-
it_behaves_like "EmptyTempDir::BlockRunner#run"
|
151
|
-
end
|
152
|
-
|
153
|
-
context "where the target directory exists" do
|
154
|
-
before(:each) do
|
155
|
-
existing_file_name = File.join(expected_temp_dir_name, "intermediate_dir", "test_file")
|
156
|
-
|
157
|
-
# Make the target directory and a file inside a nested folder inside it
|
158
|
-
FileUtils.mkdir_p(File.dirname(existing_file_name))
|
159
|
-
File.open(existing_file_name, "w") do |file|
|
160
|
-
file << "some unimportant contents"
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
it_behaves_like "EmptyTempDir::BlockRunner#run"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|