copland 0.8.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.
- data/doc/README +88 -0
- data/doc/manual-html/chapter-1.html +454 -0
- data/doc/manual-html/chapter-10.html +399 -0
- data/doc/manual-html/chapter-11.html +600 -0
- data/doc/manual-html/chapter-12.html +406 -0
- data/doc/manual-html/chapter-2.html +382 -0
- data/doc/manual-html/chapter-3.html +424 -0
- data/doc/manual-html/chapter-4.html +432 -0
- data/doc/manual-html/chapter-5.html +381 -0
- data/doc/manual-html/chapter-6.html +364 -0
- data/doc/manual-html/chapter-7.html +434 -0
- data/doc/manual-html/chapter-8.html +373 -0
- data/doc/manual-html/chapter-9.html +324 -0
- data/doc/manual-html/copland.png +0 -0
- data/doc/manual-html/index.html +331 -0
- data/doc/manual-html/manual.css +179 -0
- data/doc/manual-html/tutorial-1.html +407 -0
- data/doc/manual-html/tutorial-2.html +451 -0
- data/doc/manual-html/tutorial-3.html +484 -0
- data/doc/manual-html/tutorial-4.html +446 -0
- data/doc/manual-html/tutorial-5.html +520 -0
- data/doc/manual/chapter.erb +18 -0
- data/doc/manual/example.erb +18 -0
- data/doc/manual/img/copland.png +0 -0
- data/doc/manual/index.erb +30 -0
- data/doc/manual/manual.css +179 -0
- data/doc/manual/manual.rb +239 -0
- data/doc/manual/manual.yml +2643 -0
- data/doc/manual/page.erb +102 -0
- data/doc/manual/tutorial.erb +30 -0
- data/doc/packages/copland.html +764 -0
- data/doc/packages/copland.lib.html +439 -0
- data/doc/packages/copland.remote.html +2096 -0
- data/doc/packages/copland.webrick.html +925 -0
- data/doc/packages/index.html +49 -0
- data/doc/packages/packrat.css +125 -0
- data/examples/calc/calc.rb +47 -0
- data/examples/calc/package.yml +35 -0
- data/examples/calc/services.rb +74 -0
- data/examples/solitaire-cipher/README +11 -0
- data/examples/solitaire-cipher/Rakefile +57 -0
- data/examples/solitaire-cipher/bin/main.rb +14 -0
- data/examples/solitaire-cipher/lib/cipher.rb +230 -0
- data/examples/solitaire-cipher/lib/cli.rb +24 -0
- data/examples/solitaire-cipher/lib/package.yml +106 -0
- data/examples/solitaire-cipher/test/tc_deck.rb +30 -0
- data/examples/solitaire-cipher/test/tc_key-stream.rb +19 -0
- data/examples/solitaire-cipher/test/tc_keying-algorithms.rb +31 -0
- data/examples/solitaire-cipher/test/tc_solitaire-cipher.rb +66 -0
- data/examples/solitaire-cipher/test/tc_unkeyed-algorithm.rb +17 -0
- data/examples/solitaire-cipher/test/tests.rb +2 -0
- data/lib/copland.rb +56 -0
- data/lib/copland/class-factory.rb +95 -0
- data/lib/copland/configuration-point.rb +38 -0
- data/lib/copland/configuration-point/common.rb +203 -0
- data/lib/copland/configuration-point/errors.rb +44 -0
- data/lib/copland/configuration-point/list.rb +59 -0
- data/lib/copland/configuration-point/map.rb +59 -0
- data/lib/copland/configuration/errors.rb +43 -0
- data/lib/copland/configuration/loader.rb +113 -0
- data/lib/copland/configuration/yaml/configuration-point.rb +87 -0
- data/lib/copland/configuration/yaml/implementor.rb +134 -0
- data/lib/copland/configuration/yaml/interceptor.rb +63 -0
- data/lib/copland/configuration/yaml/listener.rb +56 -0
- data/lib/copland/configuration/yaml/loader.rb +122 -0
- data/lib/copland/configuration/yaml/package.rb +125 -0
- data/lib/copland/configuration/yaml/parser.rb +71 -0
- data/lib/copland/configuration/yaml/schema.rb +165 -0
- data/lib/copland/configuration/yaml/service-point.rb +116 -0
- data/lib/copland/configuration/yaml/utils.rb +82 -0
- data/lib/copland/default-schema-processor.rb +144 -0
- data/lib/copland/errors.rb +82 -0
- data/lib/copland/event-producer.rb +95 -0
- data/lib/copland/impl/builder-factory.rb +112 -0
- data/lib/copland/impl/copland-config.yml +1 -0
- data/lib/copland/impl/include-exclude.rb +140 -0
- data/lib/copland/impl/logging-interceptor.rb +106 -0
- data/lib/copland/impl/package.yml +217 -0
- data/lib/copland/impl/startup.rb +116 -0
- data/lib/copland/impl/symbol-source-manager.rb +131 -0
- data/lib/copland/impl/symbol-source.rb +63 -0
- data/lib/copland/instantiator.rb +38 -0
- data/lib/copland/instantiator/abstract.rb +91 -0
- data/lib/copland/instantiator/complex.rb +96 -0
- data/lib/copland/instantiator/identity.rb +58 -0
- data/lib/copland/instantiator/simple.rb +68 -0
- data/lib/copland/interceptor-chain.rb +166 -0
- data/lib/copland/interceptor.rb +139 -0
- data/lib/copland/log-factory.rb +206 -0
- data/lib/copland/models.rb +39 -0
- data/lib/copland/models/abstract.rb +78 -0
- data/lib/copland/models/prototype-deferred.rb +58 -0
- data/lib/copland/models/prototype.rb +58 -0
- data/lib/copland/models/proxy.rb +100 -0
- data/lib/copland/models/singleton-deferred.rb +59 -0
- data/lib/copland/models/singleton.rb +77 -0
- data/lib/copland/models/threaded.rb +65 -0
- data/lib/copland/ordering.rb +123 -0
- data/lib/copland/package.rb +246 -0
- data/lib/copland/registry.rb +368 -0
- data/lib/copland/schema.rb +206 -0
- data/lib/copland/service-point.rb +282 -0
- data/lib/copland/utils.rb +221 -0
- data/lib/copland/version.rb +47 -0
- data/test/conf-test/list-bad-key.yml +30 -0
- data/test/conf-test/list-bad-missing.yml +28 -0
- data/test/conf-test/list-bad-type.yml +28 -0
- data/test/conf-test/list-good.yml +29 -0
- data/test/conf-test/map-bad-key.yml +25 -0
- data/test/conf-test/map-bad-missing.yml +24 -0
- data/test/conf-test/map-bad-type.yml +23 -0
- data/test/conf-test/map-good.yml +25 -0
- data/test/configuration-point/package.yml +52 -0
- data/test/configuration/yaml/config/copland-config.yml +2 -0
- data/test/configuration/yaml/config/module.yml +2 -0
- data/test/configuration/yaml/config/subdir/copland-config.yml +2 -0
- data/test/configuration/yaml/config/subdir/package.yml +4 -0
- data/test/configuration/yaml/defaults/package.yml +5 -0
- data/test/configuration/yaml/defaults/subdir/package.yml +4 -0
- data/test/configuration/yaml/tc_config-loader.rb +86 -0
- data/test/configuration/yaml/tc_configuration-point-processor.rb +134 -0
- data/test/configuration/yaml/tc_implementor-processor.rb +104 -0
- data/test/configuration/yaml/tc_interceptor-processor.rb +85 -0
- data/test/configuration/yaml/tc_listener-processor.rb +69 -0
- data/test/configuration/yaml/tc_loader.rb +74 -0
- data/test/configuration/yaml/tc_package-processor.rb +120 -0
- data/test/configuration/yaml/tc_parser.rb +94 -0
- data/test/configuration/yaml/tc_schema-parser.rb +160 -0
- data/test/configuration/yaml/tc_service-point-processor.rb +104 -0
- data/test/configuration/yaml/tc_type-validator.rb +90 -0
- data/test/custom-logger.yml +3 -0
- data/test/impl/logging/package.yml +44 -0
- data/test/impl/logging/services.rb +84 -0
- data/test/impl/startup/package.yml +46 -0
- data/test/impl/startup/services.rb +47 -0
- data/test/impl/symbols/package.yml +24 -0
- data/test/impl/symbols/services.rb +38 -0
- data/test/impl/tc_builder-factory.rb +173 -0
- data/test/impl/tc_logging-interceptor.rb +148 -0
- data/test/impl/tc_startup.rb +59 -0
- data/test/impl/tc_symbol-sources.rb +61 -0
- data/test/logger.yml +6 -0
- data/test/mock.rb +201 -0
- data/test/schema/bad-package.yml +65 -0
- data/test/schema/package.yml +102 -0
- data/test/schema/services.rb +5 -0
- data/test/services/package.yml +79 -0
- data/test/services/simple.rb +87 -0
- data/test/tc_class-factory.rb +93 -0
- data/test/tc_complex-instantiator.rb +107 -0
- data/test/tc_configuration-point-contrib.rb +74 -0
- data/test/tc_configuration-point-schema.rb +122 -0
- data/test/tc_configuration-point.rb +91 -0
- data/test/tc_default-schema-processor.rb +297 -0
- data/test/tc_identity-instantiator.rb +61 -0
- data/test/tc_interceptors.rb +84 -0
- data/test/tc_logger.rb +131 -0
- data/test/tc_models.rb +176 -0
- data/test/tc_package.rb +165 -0
- data/test/tc_proxy.rb +65 -0
- data/test/tc_registry.rb +141 -0
- data/test/tc_schema.rb +78 -0
- data/test/tc_service-point.rb +178 -0
- data/test/tc_service.rb +70 -0
- data/test/tc_simple-instantiator.rb +61 -0
- data/test/tests.rb +93 -0
- data/tutorial/01/main.rb +7 -0
- data/tutorial/01/package.yml +8 -0
- data/tutorial/01/tutorial.rb +7 -0
- data/tutorial/02/main.rb +10 -0
- data/tutorial/02/package.yml +27 -0
- data/tutorial/02/tutorial.rb +46 -0
- data/tutorial/03/main.rb +24 -0
- data/tutorial/03/package.yml +29 -0
- data/tutorial/03/tutorial.rb +48 -0
- data/tutorial/04/main.rb +24 -0
- data/tutorial/04/package.yml +35 -0
- data/tutorial/04/tutorial.rb +48 -0
- data/tutorial/05/functions/package.yml +16 -0
- data/tutorial/05/functions/services.rb +15 -0
- data/tutorial/05/main.rb +10 -0
- data/tutorial/05/package.yml +35 -0
- data/tutorial/05/tutorial.rb +53 -0
- metadata +260 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class CLI
|
|
2
|
+
|
|
3
|
+
ENCRYPTED = /^([A-Z]{5} )*[A-Z]{5}$/
|
|
4
|
+
|
|
5
|
+
attr_writer :cipher
|
|
6
|
+
attr_writer :options
|
|
7
|
+
|
|
8
|
+
def run
|
|
9
|
+
return unless @options.run_app?
|
|
10
|
+
|
|
11
|
+
@cipher.use_algorithm @options.keying_algorithm
|
|
12
|
+
|
|
13
|
+
@options.strings.each do |arg|
|
|
14
|
+
if arg =~ ENCRYPTED
|
|
15
|
+
puts arg.inspect
|
|
16
|
+
puts " (decrypt)--> #{@cipher.decrypt(arg).inspect}"
|
|
17
|
+
else
|
|
18
|
+
puts arg.inspect
|
|
19
|
+
puts " (encrypt)--> #{@cipher.encrypt(arg).inspect}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: solitaire.cipher
|
|
3
|
+
description: >-
|
|
4
|
+
The services needed to implement a command-line version of the solitaire
|
|
5
|
+
cipher. This is in fulfillment of Ruby Quiz 1: "The Solitaire Cipher".
|
|
6
|
+
|
|
7
|
+
service-points:
|
|
8
|
+
|
|
9
|
+
CLI:
|
|
10
|
+
description: >-
|
|
11
|
+
The command-line interface required by the quiz. Ideally, this would
|
|
12
|
+
be put in a package of its own, leaving the more general-purpose
|
|
13
|
+
services in this package, but for the quiz...let's not go TOO overboard
|
|
14
|
+
on this...
|
|
15
|
+
model: singleton
|
|
16
|
+
implementor:
|
|
17
|
+
factory: copland.BuilderFactory
|
|
18
|
+
class: cli/CLI
|
|
19
|
+
properties:
|
|
20
|
+
cipher: !!service SolitaireCipher
|
|
21
|
+
options: !!service Options
|
|
22
|
+
|
|
23
|
+
KeyingAlgorithms:
|
|
24
|
+
description: >-
|
|
25
|
+
This service helps provide keying algorithms. It is backed by the
|
|
26
|
+
configuration point of the same name, but provides a little more "extra"
|
|
27
|
+
functionality than an unadorned configuration point.
|
|
28
|
+
implementor:
|
|
29
|
+
factory: copland.BuilderFactory
|
|
30
|
+
class: cipher/KeyingAlgorithms
|
|
31
|
+
properties:
|
|
32
|
+
algorithms: !!configuration KeyingAlgorithms
|
|
33
|
+
registry: !!service copland.Registry
|
|
34
|
+
|
|
35
|
+
KeyStream:
|
|
36
|
+
description: >-
|
|
37
|
+
Represents a keystream. It may be used as an iterator to obtain
|
|
38
|
+
subsequent letters from the keystream.
|
|
39
|
+
model: prototype
|
|
40
|
+
implementor:
|
|
41
|
+
factory: copland.BuilderFactory
|
|
42
|
+
class: cipher/KeyStream
|
|
43
|
+
properties:
|
|
44
|
+
deck: !!service Deck
|
|
45
|
+
|
|
46
|
+
SolitaireCipher:
|
|
47
|
+
description: >-
|
|
48
|
+
The implementation of the solitaire cipher. This handles both encryption
|
|
49
|
+
and decryption.
|
|
50
|
+
model: prototype
|
|
51
|
+
implementor:
|
|
52
|
+
factory: copland.BuilderFactory
|
|
53
|
+
class: cipher/SolitaireCipher
|
|
54
|
+
parameters:
|
|
55
|
+
- !!service UnkeyedAlgorithm
|
|
56
|
+
properties:
|
|
57
|
+
algorithms: !!service KeyingAlgorithms
|
|
58
|
+
stream: !!service KeyStream
|
|
59
|
+
|
|
60
|
+
UnkeyedAlgorithm:
|
|
61
|
+
description: >-
|
|
62
|
+
The default keying algorithm, which is really no algorithm at all. It
|
|
63
|
+
does nothing to the deck, leaving it in its unkeyed form.
|
|
64
|
+
implementor: cipher/UnkeyedAlgorithm
|
|
65
|
+
|
|
66
|
+
BackwardsAlgorithm:
|
|
67
|
+
description: >-
|
|
68
|
+
Keys the deck by ordering the cards in reverse unkeyed order.
|
|
69
|
+
implementor: cipher/BackwardsAlgorithm
|
|
70
|
+
|
|
71
|
+
ShuffleAlgorithm:
|
|
72
|
+
description: >-
|
|
73
|
+
Just for demonstration, and certainly not required by the quiz. This
|
|
74
|
+
keying algorithm just shuffles the deck, using a specific number to
|
|
75
|
+
seed the random number generator, for repeatability.
|
|
76
|
+
implementor:
|
|
77
|
+
factory: copland.BuilderFactory
|
|
78
|
+
class: cipher/ShuffleAlgorithm
|
|
79
|
+
properties:
|
|
80
|
+
options: !!service Options
|
|
81
|
+
|
|
82
|
+
Options:
|
|
83
|
+
description: >-
|
|
84
|
+
Represents the options given to the application, either via the command
|
|
85
|
+
line or some other way.
|
|
86
|
+
implementor: cipher/Options
|
|
87
|
+
|
|
88
|
+
Deck:
|
|
89
|
+
model: prototype-deferred
|
|
90
|
+
description: Implements a deck of cards for the solitaire cipher.
|
|
91
|
+
implementor: cipher/Deck
|
|
92
|
+
|
|
93
|
+
configuration-points:
|
|
94
|
+
|
|
95
|
+
KeyingAlgorithms:
|
|
96
|
+
type: map
|
|
97
|
+
description: >-
|
|
98
|
+
The map of available algorithms to use when keying a deck. Each algorithm
|
|
99
|
+
that is added must be the (fully-qualified) name of a service.
|
|
100
|
+
|
|
101
|
+
contributions:
|
|
102
|
+
|
|
103
|
+
KeyingAlgorithms:
|
|
104
|
+
unkeyed: solitaire.cipher.UnkeyedAlgorithm
|
|
105
|
+
shuffle: solitaire.cipher.ShuffleAlgorithm
|
|
106
|
+
reverse: solitaire.cipher.BackwardsAlgorithm
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), "..", "lib" )
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'cipher'
|
|
4
|
+
|
|
5
|
+
class TC_Deck < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@deck = Deck.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_content
|
|
12
|
+
expected = (1..52).to_a + [ "A", "B" ]
|
|
13
|
+
assert_equal expected, @deck.to_a
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_shuffle
|
|
17
|
+
@deck.cipher_shuffle!
|
|
18
|
+
expected = (2..52).to_a + [ "A", "B", 1 ]
|
|
19
|
+
assert_equal expected, @deck.to_a
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_letter
|
|
23
|
+
expected = %w{ D W J nil X H Y R F D G }
|
|
24
|
+
expected.each do |expected_letter|
|
|
25
|
+
@deck.cipher_shuffle!
|
|
26
|
+
assert_equal expected_letter, @deck.cipher_letter || "nil"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), "..", "lib" )
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'cipher'
|
|
4
|
+
|
|
5
|
+
class TC_KeyStream < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@stream = KeyStream.new
|
|
9
|
+
@stream.deck = Deck.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_next
|
|
13
|
+
expected = %w{ D W J X H Y R F D G }
|
|
14
|
+
expected.each do |expected_letter|
|
|
15
|
+
assert_equal expected_letter, @stream.next
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), "..", "lib" )
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'cipher'
|
|
4
|
+
|
|
5
|
+
class TC_KeyingAlgorithms < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
class MockRegistry
|
|
8
|
+
def service( name )
|
|
9
|
+
return "found" if name == "something.mock"
|
|
10
|
+
return nil
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def setup
|
|
15
|
+
@algorithms = KeyingAlgorithms.new
|
|
16
|
+
@algorithms.algorithms = { "mock" => "something.mock" }
|
|
17
|
+
@algorithms.registry = MockRegistry.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_get_not_found
|
|
21
|
+
assert_raise( RuntimeError ) do
|
|
22
|
+
@algorithms.get( "bogus" )
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_get_found
|
|
27
|
+
svc = @algorithms.get( "mock" )
|
|
28
|
+
assert_equal svc, "found"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), "..", "lib" )
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'cipher'
|
|
4
|
+
|
|
5
|
+
class TC_SolitaireCipher < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
class MockAlgorithms
|
|
8
|
+
def get( name )
|
|
9
|
+
MockAlgorithm.new
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class MockDeck
|
|
14
|
+
def cipher_shuffle!
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def cipher_letter
|
|
18
|
+
"X"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class MockAlgorithm
|
|
23
|
+
def new_deck
|
|
24
|
+
MockDeck.new
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def setup
|
|
29
|
+
@cipher = SolitaireCipher.new( UnkeyedAlgorithm.new )
|
|
30
|
+
@cipher.algorithms = MockAlgorithms.new
|
|
31
|
+
@cipher.stream = KeyStream.new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_use_algorithm
|
|
35
|
+
@cipher.use_algorithm "mock"
|
|
36
|
+
assert_equal "FCJJM", @cipher.encrypt( "HELLO" )
|
|
37
|
+
assert_equal "JGNNQ", @cipher.decrypt( "HELLO" )
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_encrypt
|
|
41
|
+
msg = "Code in Ruby! Live longer."
|
|
42
|
+
expected = "GLNCQ MJAFF FVOMB JIYCB"
|
|
43
|
+
assert_equal expected, @cipher.encrypt( msg )
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_decrypt_bad
|
|
47
|
+
assert_raise( RuntimeError ) do
|
|
48
|
+
@cipher.decrypt( "not good" )
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
assert_raise( RuntimeError ) do
|
|
52
|
+
@cipher.decrypt( "BOGUS 12345" )
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_decrypt_good
|
|
57
|
+
msg = "CLEPK HHNIY CFPWH FDFEH"
|
|
58
|
+
expected = "YOURCIPHERISWORKINGX"
|
|
59
|
+
assert_equal expected, @cipher.decrypt( msg )
|
|
60
|
+
|
|
61
|
+
msg = "ABVAW LWZSY OORYK DUPVH"
|
|
62
|
+
expected = "WELCOMETORUBYQUIZXXX"
|
|
63
|
+
assert_equal expected, @cipher.decrypt( msg )
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
$: << File.join( File.dirname( __FILE__ ), "..", "lib" )
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'cipher'
|
|
4
|
+
|
|
5
|
+
class TC_UnkeyedAlgorithm < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@algo = UnkeyedAlgorithm.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_new_deck
|
|
12
|
+
expected = (1..52).to_a + [ "A", "B" ]
|
|
13
|
+
deck = @algo.new_deck
|
|
14
|
+
assert_equal expected, deck.to_a
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
data/lib/copland.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
# this list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# * The names of its contributors may not be used to endorse or promote
|
|
17
|
+
# products derived from this software without specific prior written
|
|
18
|
+
# permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
# =============================================================================
|
|
32
|
+
#++
|
|
33
|
+
|
|
34
|
+
require 'copland/configuration/errors'
|
|
35
|
+
require 'copland/errors'
|
|
36
|
+
require 'copland/registry'
|
|
37
|
+
require 'copland/version'
|
|
38
|
+
|
|
39
|
+
module Copland
|
|
40
|
+
|
|
41
|
+
# The map of library 'require' names to the package descriptor search paths
|
|
42
|
+
# that they define.
|
|
43
|
+
LIBRARIES = Hash.new { |h,k| h[k] = Array.new }
|
|
44
|
+
|
|
45
|
+
# The name of the "core" Copland library. This will always be loaded by
|
|
46
|
+
# default, but we define a library name to keep things consistent. Also to
|
|
47
|
+
# allow packages to explicitly require it, if they desire.
|
|
48
|
+
LIBRARY_NAME = "copland"
|
|
49
|
+
|
|
50
|
+
# The search paths of the core Copland library.
|
|
51
|
+
SEARCH_PATHS = [ File.join( File.dirname( __FILE__ ), "copland", "impl" ) ]
|
|
52
|
+
|
|
53
|
+
# Tell Copland how to find it's core services.
|
|
54
|
+
LIBRARIES[ LIBRARY_NAME ] = SEARCH_PATHS
|
|
55
|
+
|
|
56
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
|
8
|
+
#
|
|
9
|
+
# * Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
# this list of conditions and the following disclaimer.
|
|
11
|
+
#
|
|
12
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
|
15
|
+
#
|
|
16
|
+
# * The names of its contributors may not be used to endorse or promote
|
|
17
|
+
# products derived from this software without specific prior written
|
|
18
|
+
# permission.
|
|
19
|
+
#
|
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
+
# =============================================================================
|
|
32
|
+
#++
|
|
33
|
+
|
|
34
|
+
require 'singleton'
|
|
35
|
+
|
|
36
|
+
module Copland
|
|
37
|
+
|
|
38
|
+
# This factory class provides an interface for instantiating a variety
|
|
39
|
+
# of different kinds of classes. It uses the concept of a "pool" to allow
|
|
40
|
+
# different functional groupings of classes to be separated within the
|
|
41
|
+
# factory. Thus, this is _the_ factory class for all classes in Copland,
|
|
42
|
+
# including configuration points, instantiators, and service models.
|
|
43
|
+
class ClassFactory
|
|
44
|
+
include Singleton
|
|
45
|
+
|
|
46
|
+
# Create a new ClassFactory. By default, it defines no pools.
|
|
47
|
+
def initialize
|
|
48
|
+
@pools = Hash.new
|
|
49
|
+
@constructors = Hash.new
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Define a new pool with the given name. If a block is given, it should
|
|
53
|
+
# accept at least one parameter (the klass to instantiate) and should
|
|
54
|
+
# return an instance of that class. Additional parameters may be
|
|
55
|
+
# passed to the block, with the intent that they may be used to initialize
|
|
56
|
+
# the new object somehow.
|
|
57
|
+
def create_pool( name, &block )
|
|
58
|
+
block ||= proc { |k,*args| k.new( *args ) }
|
|
59
|
+
@pools[ name ] = Hash.new
|
|
60
|
+
@constructors[ name ] = block
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Retreive a reference to the pool with the given name. If no such pool
|
|
64
|
+
# exists, a NoSuchPoolException will be raised.
|
|
65
|
+
def get_pool( name )
|
|
66
|
+
pool = @pools[ name ]
|
|
67
|
+
raise NoSuchPoolException, name unless pool
|
|
68
|
+
return pool
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Register the given klass with the class factory, in the given pool, with
|
|
72
|
+
# the given name. If the given pool does not exist, a NoSuchPoolException
|
|
73
|
+
# will be raised.
|
|
74
|
+
def register( pool_name, name, klass )
|
|
75
|
+
pool = get_pool( pool_name )
|
|
76
|
+
pool[ name ] = klass
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Return a new instance of the class registered under the given name in the
|
|
80
|
+
# given pool. If any additional arguments are given to the method, they
|
|
81
|
+
# will be passed to the constructor used to instantiate the class.
|
|
82
|
+
def get( pool_name, name, *args )
|
|
83
|
+
pool = get_pool( pool_name )
|
|
84
|
+
|
|
85
|
+
klass = pool[ name ]
|
|
86
|
+
raise NoSuchRegisteredClassException, "#{pool_name}:#{name}" unless klass
|
|
87
|
+
|
|
88
|
+
constructor = @constructors[ pool_name ]
|
|
89
|
+
|
|
90
|
+
return constructor.call( klass, *args )
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|