trick_bag 0.30.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/Guardfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/RELEASE_NOTES.md +3 -0
- data/Rakefile +1 -0
- data/lib/trick_bag.rb +7 -0
- data/lib/trick_bag/collections/linked_list.rb +97 -0
- data/lib/trick_bag/enumerables/buffered_enumerable.rb +90 -0
- data/lib/trick_bag/enumerables/compound_enumerable.rb +114 -0
- data/lib/trick_bag/enumerables/filtered_enumerable.rb +32 -0
- data/lib/trick_bag/io/temp_files.rb +22 -0
- data/lib/trick_bag/io/text_mode_status_updater.rb +59 -0
- data/lib/trick_bag/meta/classes.rb +87 -0
- data/lib/trick_bag/numeric/multi_counter.rb +44 -0
- data/lib/trick_bag/numeric/totals.rb +49 -0
- data/lib/trick_bag/operators/operators.rb +13 -0
- data/lib/trick_bag/timing/timing.rb +47 -0
- data/lib/trick_bag/validations/hash_validations.rb +21 -0
- data/lib/trick_bag/validations/object_validations.rb +26 -0
- data/lib/trick_bag/version.rb +3 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/trick_bag/collections/linked_list_spec.rb +64 -0
- data/spec/trick_bag/enumerables/buffered_enumerable_spec.rb +117 -0
- data/spec/trick_bag/enumerables/compound_enumerable_spec.rb +141 -0
- data/spec/trick_bag/enumerables/filtered_enumerable_spec.rb +35 -0
- data/spec/trick_bag/io/temp_files_spec.rb +31 -0
- data/spec/trick_bag/io/text_mode_status_updater_spec.rb +24 -0
- data/spec/trick_bag/meta/classes_spec.rb +211 -0
- data/spec/trick_bag/numeric/multi_counter_spec.rb +28 -0
- data/spec/trick_bag/numeric/totals_spec.rb +38 -0
- data/spec/trick_bag/operators/operators_spec.rb +33 -0
- data/spec/trick_bag/timing/timing_spec.rb +17 -0
- data/spec/trick_bag/validations/hashes_validations_spec.rb +39 -0
- data/spec/trick_bag/validations/object_validations_spec.rb +23 -0
- data/trick_bag.gemspec +28 -0
- metadata +194 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'trick_bag/enumerables/buffered_enumerable'
|
3
|
+
|
4
|
+
module TrickBag
|
5
|
+
module Enumerables
|
6
|
+
|
7
|
+
describe BufferedEnumerable do
|
8
|
+
|
9
|
+
context 'when created with lambdas' do
|
10
|
+
# Returns an object that returns chunks of incrementing integers.
|
11
|
+
let(:fetcher) do
|
12
|
+
object = 0
|
13
|
+
->(array, chunk_size) do
|
14
|
+
chunk_size.times do
|
15
|
+
object += 1
|
16
|
+
array << object
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
specify 'the values and number of fetches are correct' do
|
22
|
+
chunk_fetch_calls = 0
|
23
|
+
object_count = 0
|
24
|
+
|
25
|
+
fetch_notifier = ->(fetched_objects) do
|
26
|
+
chunk_fetch_calls += 1
|
27
|
+
object_count += fetched_objects.size
|
28
|
+
end
|
29
|
+
|
30
|
+
e = BufferedEnumerable.create_with_lambdas(4, fetcher, fetch_notifier).to_enum
|
31
|
+
(1..10).each do |n|
|
32
|
+
expect(e.next).to eq(n)
|
33
|
+
end
|
34
|
+
expect(chunk_fetch_calls).to eq(3)
|
35
|
+
expect(object_count).to eq(12)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
context "when instantiating a subclass" do
|
41
|
+
specify 'the values and number of fetches are correct' do
|
42
|
+
create_test_class = ->() do
|
43
|
+
class BufferedEnumerableSubclass < BufferedEnumerable
|
44
|
+
|
45
|
+
attr_accessor :chunk_fetch_calls, :object_count
|
46
|
+
|
47
|
+
def initialize(chunk_size)
|
48
|
+
super
|
49
|
+
@chunk_fetch_calls = 0
|
50
|
+
@object_count = 0
|
51
|
+
end
|
52
|
+
|
53
|
+
def fetch_notify
|
54
|
+
@chunk_fetch_calls += 1
|
55
|
+
@object_count += data.size
|
56
|
+
end
|
57
|
+
|
58
|
+
def fetch
|
59
|
+
@object ||= 0
|
60
|
+
chunk_size.times do
|
61
|
+
@object += 1
|
62
|
+
self.data << @object
|
63
|
+
end
|
64
|
+
require 'pry'; binding.pry if self.data.is_a?(Fixnum)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
create_test_class.()
|
70
|
+
enumerable = BufferedEnumerableSubclass.new(4)
|
71
|
+
enumerator = enumerable.each
|
72
|
+
|
73
|
+
(1..10).each do |n|
|
74
|
+
expect(enumerator.next).to eq(n)
|
75
|
+
end
|
76
|
+
expect(enumerable.chunk_fetch_calls).to eq(3)
|
77
|
+
expect(enumerable.object_count).to eq(12)
|
78
|
+
::TrickBag::Meta::Classes.undef_class(:BufferedEnumerableSubclass, TrickBag)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
context "an Array implementation" do
|
84
|
+
|
85
|
+
create_array_subclass = -> do
|
86
|
+
class ArrayBufferedEnumerable < BufferedEnumerable
|
87
|
+
|
88
|
+
def initialize(chunk_size, array)
|
89
|
+
super(chunk_size)
|
90
|
+
@array = array
|
91
|
+
end
|
92
|
+
|
93
|
+
def fetch
|
94
|
+
num_times = [chunk_size, @array.size].min
|
95
|
+
num_times.times { @data << @array.shift }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'should fulfill its basic functions' do
|
101
|
+
create_array_subclass.()
|
102
|
+
enumerable = ArrayBufferedEnumerable.new(4, (0..5).to_a)
|
103
|
+
enumerator = enumerable.each
|
104
|
+
|
105
|
+
(0..5).to_a.each do |n|
|
106
|
+
expect(enumerator.next).to eq(n)
|
107
|
+
end
|
108
|
+
expect(->{ enumerator.next }).to raise_error(StopIteration)
|
109
|
+
expect(enumerable.chunk_count).to eq(2)
|
110
|
+
|
111
|
+
::TrickBag::Meta::Classes.undef_class(:ArrayBufferedEnumerable, TrickBag)
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'trick_bag/enumerables/compound_enumerable'
|
3
|
+
|
4
|
+
module TrickBag
|
5
|
+
module Enumerables
|
6
|
+
|
7
|
+
describe CompoundEnumerable do
|
8
|
+
|
9
|
+
context 'input validations' do
|
10
|
+
|
11
|
+
specify 'an initialization error will be raised if no enumerables are specified' do
|
12
|
+
expect(->{ CompoundEnumerable.array_enumerable() }).to raise_error
|
13
|
+
expect(->{ CompoundEnumerable.hash_enumerable([:key]) }).to raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
specify 'an initialization error will be raised if mode is not :yields_arrays or :yields_hashes' do
|
17
|
+
expect(->{ CompoundEnumerable.new(:bad_mode, [], [])}).to raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
specify 'an initialization error will be raised if key array size != enumerables size in :yields_hashes mode' do
|
21
|
+
expect(->{ CompoundEnumerable.new(:yields_hashes, [:key1, :key2], [])}).to raise_error
|
22
|
+
expect(->{ CompoundEnumerable.hash_enumerable([:key1, :key2], [])}).to raise_error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
context "as array" do
|
29
|
+
|
30
|
+
context 'with 1 enumerable' do
|
31
|
+
specify 'Gets its values then raises a StopIteration error' do
|
32
|
+
array = [1, 2]
|
33
|
+
e = CompoundEnumerable.array_enumerable(array).each
|
34
|
+
expect(e.next).to eq(1)
|
35
|
+
expect(e.next).to eq(2)
|
36
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
context 'with 2 enumerables' do
|
42
|
+
specify 'offers correct values in the correct order' do
|
43
|
+
outer = %w(A B)
|
44
|
+
inner = [1, 2]
|
45
|
+
e = CompoundEnumerable.array_enumerable(outer, inner).each
|
46
|
+
expect(e.next).to eq(['A', 1])
|
47
|
+
expect(e.next).to eq(['A', 2])
|
48
|
+
expect(e.next).to eq(['B', 1])
|
49
|
+
expect(e.next).to eq(['B', 2])
|
50
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
context 'with 3 enumerables' do
|
56
|
+
specify 'offers correct values in the correct order' do
|
57
|
+
domains = %w(aaa.com zzz.com)
|
58
|
+
qtypes = %w(A NS)
|
59
|
+
qclasses = %w(IN CH)
|
60
|
+
e = CompoundEnumerable.array_enumerable(domains, qtypes, qclasses).each
|
61
|
+
|
62
|
+
expect(e.next).to eq(['aaa.com', 'A', 'IN'])
|
63
|
+
expect(e.next).to eq(['aaa.com', 'A', 'CH'])
|
64
|
+
expect(e.next).to eq(['aaa.com', 'NS', 'IN'])
|
65
|
+
expect(e.next).to eq(['aaa.com', 'NS', 'CH'])
|
66
|
+
expect(e.next).to eq(['zzz.com', 'A', 'IN'])
|
67
|
+
expect(e.next).to eq(['zzz.com', 'A', 'CH'])
|
68
|
+
expect(e.next).to eq(['zzz.com', 'NS', 'IN'])
|
69
|
+
expect(e.next).to eq(['zzz.com', 'NS', 'CH'])
|
70
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'is an Enumerable' do
|
75
|
+
it "provides the 'take' method" do
|
76
|
+
expect(->{ CompoundEnumerable.array_enumerable([1, 2, 3]).take(2)}).not_to raise_error
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
context "as hash" do
|
83
|
+
|
84
|
+
context 'with 1 enumerable' do
|
85
|
+
specify 'Gets its values then raises a StopIteration error' do
|
86
|
+
array = [1, 2]
|
87
|
+
e = CompoundEnumerable.hash_enumerable([:number], array).each
|
88
|
+
expect(e.next).to eq({ number: 1 })
|
89
|
+
expect(e.next).to eq({ number: 2 })
|
90
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
context 'with 2 enumerables' do
|
96
|
+
specify 'offers correct values in the correct order' do
|
97
|
+
outer = %w(A B)
|
98
|
+
inner = [1, 2]
|
99
|
+
e = CompoundEnumerable.hash_enumerable([:outer, :inner], outer, inner).each
|
100
|
+
expect(e.next).to eq({ outer: 'A', inner: 1 })
|
101
|
+
expect(e.next).to eq({ outer: 'A', inner: 2 })
|
102
|
+
expect(e.next).to eq({ outer: 'B', inner: 1 })
|
103
|
+
expect(e.next).to eq({ outer: 'B', inner: 2 })
|
104
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
context 'with 3 enumerables' do
|
110
|
+
specify 'offers correct values in the correct order' do
|
111
|
+
domains = %w(aaa.com zzz.com)
|
112
|
+
qtypes = %w(A NS)
|
113
|
+
qclasses = %w(IN CH)
|
114
|
+
keys = [:domain, :qtype, :qclass]
|
115
|
+
e = CompoundEnumerable.hash_enumerable(keys, domains, qtypes, qclasses).each
|
116
|
+
|
117
|
+
expect(e.next).to eq({ domain: 'aaa.com', qtype: 'A', qclass: 'IN' })
|
118
|
+
expect(e.next).to eq({ domain: 'aaa.com', qtype: 'A', qclass: 'CH' })
|
119
|
+
expect(e.next).to eq({ domain: 'aaa.com', qtype: 'NS', qclass: 'IN' })
|
120
|
+
expect(e.next).to eq({ domain: 'aaa.com', qtype: 'NS', qclass: 'CH' })
|
121
|
+
|
122
|
+
expect(e.next).to eq({ domain: 'zzz.com', qtype: 'A', qclass: 'IN' })
|
123
|
+
expect(e.next).to eq({ domain: 'zzz.com', qtype: 'A', qclass: 'CH' })
|
124
|
+
expect(e.next).to eq({ domain: 'zzz.com', qtype: 'NS', qclass: 'IN' })
|
125
|
+
expect(e.next).to eq({ domain: 'zzz.com', qtype: 'NS', qclass: 'CH' })
|
126
|
+
expect(->{ e.next }).to raise_error(StopIteration)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'is an Enumerable' do
|
131
|
+
it "provides the 'take' method" do
|
132
|
+
expect(->{ CompoundEnumerable.hash_enumerable([:num], [1, 2, 3]).take(2)}).not_to raise_error
|
133
|
+
|
134
|
+
values = CompoundEnumerable.hash_enumerable([:num], [1, 2, 3]).take(2)
|
135
|
+
expect(values).to eq([{ num: 1 }, { num: 2 }])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'trick_bag/enumerables/filtered_enumerable'
|
3
|
+
|
4
|
+
module TrickBag
|
5
|
+
module Enumerables
|
6
|
+
|
7
|
+
describe FilteredEnumerable do
|
8
|
+
|
9
|
+
let (:even_filter) { ->(n) { n.even? } }
|
10
|
+
specify 'with no filter it behaves as a regular enumberable' do
|
11
|
+
e = FilteredEnumerable.new([1,2,3])
|
12
|
+
expect(e.to_a).to eq([1, 2, 3])
|
13
|
+
end
|
14
|
+
|
15
|
+
specify 'an even number filter works correctly when filter passed to constructor' do
|
16
|
+
e = FilteredEnumerable.new((1..10).to_a, even_filter)
|
17
|
+
expect(e.to_a).to eq([2, 4, 6, 8, 10])
|
18
|
+
end
|
19
|
+
|
20
|
+
specify 'an even number filter works correctly when filter passed after creation' do
|
21
|
+
e = FilteredEnumerable.new((1..10).to_a)
|
22
|
+
e.filter = even_filter
|
23
|
+
expect(e.to_a).to eq([2, 4, 6, 8, 10])
|
24
|
+
end
|
25
|
+
|
26
|
+
specify 'works as an enumerator' do
|
27
|
+
e = FilteredEnumerable.new((1..5).to_a, even_filter)
|
28
|
+
enumerator = e.each
|
29
|
+
expect(enumerator.next).to eq(2)
|
30
|
+
expect(enumerator.next).to eq(4)
|
31
|
+
expect(-> { enumerator.next }).to raise_error(StopIteration)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
require 'trick_bag/io/temp_files'
|
4
|
+
|
5
|
+
module TrickBag::Io
|
6
|
+
|
7
|
+
describe TempFiles do
|
8
|
+
|
9
|
+
it 'creates a readable file with the correct content' do
|
10
|
+
TempFiles.file_containing('foo') do |filespec|
|
11
|
+
expect(File.read(filespec)).to eq('foo')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'deletes the file when done' do
|
16
|
+
filespec = nil
|
17
|
+
TempFiles.file_containing('foo') do |fspec|
|
18
|
+
filespec = fspec
|
19
|
+
end
|
20
|
+
expect(File.exist?(filespec)).to be_false
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'uses the prefix in the filespec' do
|
24
|
+
prefix = 'jsiapewrqms'
|
25
|
+
TempFiles.file_containing('', prefix) do |filespec|
|
26
|
+
filename = File.split(filespec).last
|
27
|
+
expect(filename.start_with?(prefix)).to be_true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'trick_bag/io/text_mode_status_updater'
|
3
|
+
|
4
|
+
module TrickBag
|
5
|
+
module Io
|
6
|
+
describe TextModeStatusUpdater do
|
7
|
+
|
8
|
+
it 'instantiates without error' do
|
9
|
+
expect(->{ TextModeStatusUpdater.new(->{ '' }) }).not_to raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'creates a TextModeStatusUpdater' do
|
13
|
+
expect(TextModeStatusUpdater.new(->{ '' })).to be_a(TextModeStatusUpdater)
|
14
|
+
end
|
15
|
+
|
16
|
+
specify 'the output string contains the content provided by the passed lambda' do
|
17
|
+
string_io = StringIO.new
|
18
|
+
updater = TextModeStatusUpdater.new(->{ 'status' }, string_io, true)
|
19
|
+
updater.print
|
20
|
+
expect(string_io.string).to match(/status/)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
require 'trick_bag/meta/classes'
|
3
|
+
|
4
|
+
module TrickBag
|
5
|
+
module Meta
|
6
|
+
|
7
|
+
describe Classes do
|
8
|
+
|
9
|
+
after(:each) { Classes.undef_class('ClassPatchTestClass') }
|
10
|
+
|
11
|
+
|
12
|
+
####################################################### class?
|
13
|
+
|
14
|
+
context 'class?' do
|
15
|
+
|
16
|
+
it 'should recognize String as a class' do
|
17
|
+
expect(Classes.class?('String')).to be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should recognize that RUBY_PLATFORM is defined but is not a class' do
|
21
|
+
expect(Classes.class?('RUBY_PLATFORM')).to be_false
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should recognize a nonexistent constant as not being a class' do
|
25
|
+
expect(Classes.class?('Afjkdiurqpweruwiqopurqpweriuqewprzvxcvzxcvzxvzvzvzvcxzvzv')).to be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
####################################################### undef_class
|
31
|
+
|
32
|
+
context 'undef_class' do
|
33
|
+
it 'should remove the class' do
|
34
|
+
fn = -> do
|
35
|
+
class ClassPatchTestClass; end
|
36
|
+
ClassPatchTestClass.new # to illustrate that it's available
|
37
|
+
Classes.undef_class('ClassPatchTestClass', TrickBag::Meta)
|
38
|
+
end
|
39
|
+
fn.()
|
40
|
+
expect(->{ ClassPatchTestClass.new }).to raise_error
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
####################################################### private_attr_reader
|
46
|
+
|
47
|
+
context 'private_attr_reader' do
|
48
|
+
|
49
|
+
after(:each) { Classes.undef_class('ClassPatchTestClass') }
|
50
|
+
|
51
|
+
fn_create_class = ->do
|
52
|
+
class ClassPatchTestClass
|
53
|
+
|
54
|
+
extend Classes
|
55
|
+
|
56
|
+
private_attr_reader :foo
|
57
|
+
|
58
|
+
def initialize
|
59
|
+
@foo = 123
|
60
|
+
puts "foo = #{self.foo}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
it "should be visible inside the class" do
|
67
|
+
expect(fn_create_class).not_to raise_error
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be invisible outside the class" do
|
71
|
+
fn_create_class.()
|
72
|
+
expect(->{ ClassPatchTestClass.new.foo }).to raise_error
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
####################################################### private_attr_writer
|
78
|
+
|
79
|
+
context 'private_attr_writer' do
|
80
|
+
|
81
|
+
fn_create_class = ->do
|
82
|
+
class ClassPatchTestClass
|
83
|
+
|
84
|
+
extend Classes
|
85
|
+
|
86
|
+
private_attr_writer :foo
|
87
|
+
|
88
|
+
def initialize
|
89
|
+
self.foo = 123
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "should be visible inside the class" do
|
96
|
+
expect(fn_create_class).not_to raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should be invisible outside the class" do
|
100
|
+
fn_create_class.()
|
101
|
+
expect(->{ ClassPatchTestClass.new.foo = 456}).to raise_error
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
####################################################### private_attr_accessor
|
107
|
+
|
108
|
+
context 'private_attr_accessor' do
|
109
|
+
|
110
|
+
fn_create_class = ->do
|
111
|
+
class ClassPatchTestClass
|
112
|
+
|
113
|
+
extend Classes
|
114
|
+
|
115
|
+
private_attr_accessor :foo
|
116
|
+
|
117
|
+
def initialize
|
118
|
+
self.foo = 123
|
119
|
+
puts self.foo
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
it "should be visible inside the class" do
|
126
|
+
expect(fn_create_class).not_to raise_error
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should be invisible outside the class" do
|
130
|
+
fn_create_class.()
|
131
|
+
expect(->{ ClassPatchTestClass.new.foo = 456}).to raise_error
|
132
|
+
expect(->{ ClassPatchTestClass.new.foo }).to raise_error
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
####################################################### private_attr_writer_public_reader
|
139
|
+
|
140
|
+
context 'attr_access(:public, :private, :foo)' do
|
141
|
+
|
142
|
+
fn_create_class = ->do
|
143
|
+
class ClassPatchTestClass
|
144
|
+
|
145
|
+
extend Classes
|
146
|
+
|
147
|
+
attr_access :public, :private, :foo
|
148
|
+
|
149
|
+
def initialize
|
150
|
+
self.foo = 123
|
151
|
+
self.foo
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
it "should be readable and writable inside the class" do
|
158
|
+
expect(fn_create_class).not_to raise_error
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should be readable outside the class" do
|
162
|
+
fn_create_class.()
|
163
|
+
expect(->{ ClassPatchTestClass.new.foo }).not_to raise_error
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should not be writable outside the class" do
|
167
|
+
fn_create_class.()
|
168
|
+
expect(->{ ClassPatchTestClass.new.foo = 456}).to raise_error
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'attr_access(:private, :none, :foo)' do
|
173
|
+
|
174
|
+
fn_create_class = ->do
|
175
|
+
class ClassPatchTestClass
|
176
|
+
|
177
|
+
extend Classes
|
178
|
+
|
179
|
+
attr_access :private, :none, :foo
|
180
|
+
|
181
|
+
def initialize
|
182
|
+
@foo = 1
|
183
|
+
self.foo
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
it "should be readable inside the class" do
|
190
|
+
expect(fn_create_class).not_to raise_error
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
it "should not be readable outside the class" do
|
195
|
+
fn_create_class.()
|
196
|
+
expect(->{ ClassPatchTestClass.new.foo }).to raise_error
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should not be readable outside the class" do
|
200
|
+
fn_create_class.()
|
201
|
+
expect(->{ ClassPatchTestClass.new.foo }).to raise_error
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should not be writable outside the class" do
|
205
|
+
fn_create_class.()
|
206
|
+
expect(->{ ClassPatchTestClass.new.foo = 456}).to raise_error
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|