fancy 0.3.3 → 0.4.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/README.md +14 -14
- data/Rakefile +16 -4
- data/bin/fancy +3 -0
- data/bin/fspec +20 -0
- data/bin/fyi +27 -11
- data/bin/ifancy +1 -1
- data/boot/fancy_ext.rb +1 -0
- data/boot/fancy_ext/block_env.rb +1 -9
- data/boot/fancy_ext/delegator.rb +64 -0
- data/boot/fancy_ext/object.rb +4 -0
- data/boot/fancy_ext/thread.rb +4 -0
- data/boot/load.rb +5 -1
- data/boot/rbx-compiler/compiler/ast.rb +0 -1
- data/boot/rbx-compiler/compiler/ast/class_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +2 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +10 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +12 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +2 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/lexer.lex +5 -11
- data/boot/rbx-compiler/parser/parser.rb +16 -5
- data/boot/rbx-compiler/parser/parser.y +39 -24
- data/doc/api/fancy.css +1 -1
- data/doc/api/fancy.jsonp +1 -1
- data/doc/api/fdoc.js +22 -4
- data/doc/api/index.html +5 -6
- data/doc/api/jquery-ui.min.js +401 -0
- data/doc/api/jquery.tools.min.js +192 -0
- data/doc/api/themeswitchertool.js +250 -0
- data/doc/features.md +17 -0
- data/examples/actor_bunnies.fy +32 -0
- data/examples/actors.fy +26 -0
- data/examples/actors_primitive.fy +27 -0
- data/examples/actors_ring.fy +37 -0
- data/examples/armstrong_numbers.fy +1 -1
- data/examples/array.fy +7 -9
- data/examples/async_send.fy +1 -2
- data/examples/blocks.fy +4 -4
- data/examples/call_with_receiver.fy +1 -1
- data/examples/class.fy +1 -1
- data/examples/default_args.fy +4 -1
- data/examples/define_methods.fy +2 -2
- data/examples/echo.fy +1 -1
- data/examples/factorial.fy +1 -1
- data/examples/future_composition.fy +2 -2
- data/examples/futures.fy +0 -5
- data/examples/game_of_life.fy +1 -1
- data/examples/person.fy +1 -1
- data/lib/argv.fy +7 -2
- data/lib/array.fy +109 -42
- data/lib/block.fy +39 -14
- data/lib/boot.fy +2 -0
- data/lib/class.fy +2 -0
- data/lib/compiler/ast.fy +2 -1
- data/lib/compiler/ast/assign.fy +2 -3
- data/lib/compiler/ast/async_send.fy +1 -15
- data/lib/compiler/ast/class_def.fy +2 -1
- data/lib/compiler/ast/expression_list.fy +4 -5
- data/lib/compiler/ast/future_send.fy +1 -10
- data/lib/compiler/ast/goto.fy +46 -0
- data/lib/compiler/ast/identifier.fy +9 -7
- data/lib/compiler/ast/literals.fy +8 -1
- data/lib/compiler/ast/match.fy +14 -4
- data/lib/compiler/ast/message_send.fy +34 -6
- data/lib/compiler/ast/method_def.fy +6 -6
- data/lib/compiler/ast/node.fy +3 -3
- data/lib/compiler/ast/range.fy +1 -0
- data/lib/compiler/ast/script.fy +0 -2
- data/lib/compiler/ast/singleton_method_def.fy +2 -4
- data/lib/compiler/ast/string_interpolation.fy +17 -0
- data/lib/compiler/ast/super.fy +5 -4
- data/lib/compiler/ast/try_catch.fy +8 -6
- data/lib/compiler/ast/tuple_literal.fy +3 -2
- data/lib/compiler/command.fy +0 -1
- data/lib/compiler/compiler.fy +1 -5
- data/lib/compiler/stages.fy +6 -14
- data/lib/documentation.fy +57 -46
- data/lib/enumerable.fy +257 -23
- data/lib/enumerator.fy +122 -15
- data/lib/false_class.fy +10 -1
- data/lib/fancy_spec.fy +263 -61
- data/lib/fdoc.fy +11 -25
- data/lib/fiber.fy +11 -0
- data/lib/file.fy +8 -11
- data/lib/future.fy +84 -5
- data/lib/hash.fy +65 -14
- data/lib/integer.fy +35 -0
- data/lib/iteration.fy +54 -29
- data/lib/message.fy +6 -0
- data/lib/method.fy +0 -16
- data/lib/nil_class.fy +58 -8
- data/lib/number.fy +49 -22
- data/lib/object.fy +371 -65
- data/lib/package.fy +24 -1
- data/lib/package/installer.fy +5 -9
- data/lib/package/specification.fy +2 -2
- data/lib/parser/ext/lexer.lex +15 -11
- data/lib/parser/ext/parser.y +70 -23
- data/lib/parser/methods.fy +33 -14
- data/lib/proxy.fy +33 -3
- data/lib/range.fy +28 -0
- data/lib/rbx.fy +3 -1
- data/lib/rbx/actor.fy +53 -0
- data/lib/rbx/alpha.fy +31 -0
- data/lib/rbx/array.fy +21 -12
- data/lib/rbx/bignum.fy +6 -2
- data/lib/rbx/block.fy +23 -26
- data/lib/rbx/class.fy +54 -2
- data/lib/rbx/code_loader.fy +8 -4
- data/lib/rbx/date.fy +9 -0
- data/lib/rbx/directory.fy +18 -0
- data/lib/rbx/environment_variables.fy +1 -0
- data/lib/rbx/exception.fy +9 -2
- data/lib/rbx/fiber.fy +22 -4
- data/lib/rbx/file.fy +5 -5
- data/lib/rbx/fixnum.fy +5 -0
- data/lib/rbx/float.fy +11 -3
- data/lib/rbx/hash.fy +31 -16
- data/lib/rbx/integer.fy +1 -0
- data/lib/rbx/io.fy +17 -7
- data/lib/rbx/match_data.fy +15 -4
- data/lib/rbx/method.fy +40 -7
- data/lib/rbx/name_error.fy +4 -0
- data/lib/rbx/object.fy +92 -24
- data/lib/rbx/range.fy +20 -6
- data/lib/rbx/regexp.fy +11 -3
- data/lib/rbx/string.fy +51 -1
- data/lib/rbx/stringio.fy +17 -0
- data/lib/rbx/symbol.fy +15 -1
- data/lib/rbx/system.fy +20 -2
- data/lib/rbx/tcp_server.fy +4 -1
- data/lib/rbx/tcp_socket.fy +11 -0
- data/lib/rbx/time.fy +6 -0
- data/lib/rbx/tuple.fy +14 -5
- data/lib/set.fy +144 -29
- data/lib/stack.fy +42 -11
- data/lib/string.fy +118 -8
- data/lib/struct.fy +13 -3
- data/lib/symbol.fy +21 -2
- data/lib/thread_pool.fy +2 -1
- data/lib/true_class.fy +45 -7
- data/lib/tuple.fy +27 -9
- data/lib/version.fy +2 -2
- data/ruby_lib/fancy +43 -0
- data/ruby_lib/fdoc +23 -0
- data/ruby_lib/fspec +3 -0
- data/ruby_lib/fyi +3 -0
- data/ruby_lib/ifancy +3 -0
- data/tests/argv.fy +5 -9
- data/tests/array.fy +323 -196
- data/tests/assignment.fy +29 -29
- data/tests/block.fy +72 -59
- data/tests/class.fy +227 -138
- data/tests/control_flow.fy +83 -51
- data/tests/documentation.fy +8 -8
- data/tests/enumerable.fy +8 -0
- data/tests/enumerator.fy +47 -29
- data/tests/exception.fy +49 -32
- data/tests/file.fy +28 -28
- data/tests/fixnum.fy +170 -0
- data/tests/future.fy +24 -7
- data/tests/hash.fy +55 -38
- data/tests/method.fy +50 -43
- data/tests/nil_class.fy +37 -37
- data/tests/object.fy +152 -70
- data/tests/pattern_matching.fy +67 -31
- data/tests/range.fy +6 -6
- data/tests/set.fy +101 -4
- data/tests/stack.fy +14 -5
- data/tests/string.fy +115 -61
- data/tests/stringio.fy +18 -0
- data/tests/struct.fy +27 -0
- data/tests/symbol.fy +19 -6
- data/tests/true_class.fy +34 -34
- data/tests/tuple.fy +30 -12
- metadata +103 -81
- data/boot/rbx-compiler/compiler/ast/require.rb +0 -20
- data/examples/actor.fy +0 -37
- data/examples/curl_async.fy +0 -37
- data/lib/compiler/ast/require.fy +0 -15
- data/tests/number.fy +0 -135
- data/tests/parsing/sexp.fy +0 -50
data/tests/pattern_matching.fy
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
FancySpec describe: "Pattern Matching" with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "matches a value correctly by its class" when: {
|
|
3
3
|
def do_match: obj {
|
|
4
4
|
match obj {
|
|
5
5
|
case String -> 'string
|
|
@@ -8,50 +8,50 @@ FancySpec describe: "Pattern Matching" with: {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
do_match: "foo" .
|
|
12
|
-
do_match: 42 .
|
|
13
|
-
do_match: 'symbol .
|
|
14
|
-
do_match: Object .
|
|
15
|
-
do_match: 32.32 .
|
|
11
|
+
do_match: "foo" . is: 'string
|
|
12
|
+
do_match: 42 . is: 'fixnum
|
|
13
|
+
do_match: 'symbol . is: 'anything
|
|
14
|
+
do_match: Object . is: 'anything
|
|
15
|
+
do_match: 32.32 . is: 'anything
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
it: "
|
|
18
|
+
it: "binds a given match arg, if present, to the result of the match operation" when: {
|
|
19
19
|
match "foobarbaz" {
|
|
20
20
|
case /foo([a-z]+)baz/ -> |matcher|
|
|
21
21
|
local1, local2, local3 = 'ignore, 'this_too, 'this_also
|
|
22
|
-
matcher[1]
|
|
22
|
+
matcher[1] is: "bar"
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
it: "
|
|
26
|
+
it: "only binds a given match arg to the scope of the match case" when: {
|
|
27
27
|
match "foobarbaz" {
|
|
28
28
|
case /foo([a-z]+)baz/ -> |local_of_case|
|
|
29
|
-
local_of_case == nil .
|
|
29
|
+
local_of_case == nil . is: false
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
local_of_case
|
|
32
|
+
local_of_case is: nil
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
it: "
|
|
35
|
+
it: "only binds locals of the match clause to the scope of the match case" when: {
|
|
36
36
|
match "foobarbaz" {
|
|
37
37
|
case /foo([a-z]+)baz/ -> |local_of_case|
|
|
38
|
-
local1 = "Hi, I am some local, that
|
|
38
|
+
local1 = "Hi, I am some local, that is be gone after this block."
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
local1
|
|
41
|
+
local1 is: nil
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
it: "
|
|
44
|
+
it: "binds any additional match args to the matched values" when: {
|
|
45
45
|
str = "foo bar baz"
|
|
46
46
|
match str {
|
|
47
47
|
case /^foo (.*) (.*)$/ -> |all, match1, match2|
|
|
48
|
-
all class
|
|
49
|
-
match1
|
|
50
|
-
match2
|
|
48
|
+
all class is: MatchData
|
|
49
|
+
match1 is: "bar"
|
|
50
|
+
match2 is: "baz"
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
it: "
|
|
54
|
+
it: "returns an instance of the apropriate MatchData class" when: {
|
|
55
55
|
def create_tuple: num {
|
|
56
56
|
(num, num * num) # create a Tuple
|
|
57
57
|
}
|
|
@@ -59,35 +59,71 @@ FancySpec describe: "Pattern Matching" with: {
|
|
|
59
59
|
match create_tuple: 10 {
|
|
60
60
|
case Tuple -> |md, x, y, z|
|
|
61
61
|
# convention: md[0] always holds the entire object that was matched.
|
|
62
|
-
md[0]
|
|
63
|
-
x
|
|
64
|
-
y
|
|
65
|
-
z
|
|
62
|
+
md[0] is: (create_tuple: 10)
|
|
63
|
+
x is: 10
|
|
64
|
+
y is: 100
|
|
65
|
+
z is: nil # tuple only has 2 entries
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
it: "
|
|
69
|
+
it: "matches an array correctly" when: {
|
|
70
70
|
def create_array: num {
|
|
71
71
|
[num, num ** 2, num ** 3, num ** 4]
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
match create_array: 2 {
|
|
75
75
|
case Array -> |_, a,b,c,d|
|
|
76
|
-
a
|
|
77
|
-
b
|
|
78
|
-
c
|
|
79
|
-
d
|
|
76
|
+
a is: 2
|
|
77
|
+
b is: (2 ** 2)
|
|
78
|
+
c is: (2 ** 3)
|
|
79
|
+
d is: (2 ** 4)
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
it: "
|
|
83
|
+
it: "does not try to bind the match args if the match failed" when: {
|
|
84
84
|
["hello world!", "hello you!", "no hello here!"] each: |str| {
|
|
85
85
|
match str {
|
|
86
86
|
case /^hello (.*)$/ -> |_, name|
|
|
87
|
-
name
|
|
87
|
+
name is_not: nil
|
|
88
88
|
|
|
89
|
-
case _ -> name
|
|
89
|
+
case _ -> name is: nil
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
|
|
94
|
+
it: "matches a Block as a pattern correctly" when: {
|
|
95
|
+
def match_it: x {
|
|
96
|
+
match x {
|
|
97
|
+
case @{is_a?: String} -> 'string
|
|
98
|
+
case @{is_a?: Symbol} -> 'symbol
|
|
99
|
+
case @{responds_to?: 'each:} ->
|
|
100
|
+
match x {
|
|
101
|
+
case @{empty?} -> 'empty
|
|
102
|
+
case _ -> 'not_empty
|
|
103
|
+
}
|
|
104
|
+
case Fixnum ->
|
|
105
|
+
match x {
|
|
106
|
+
case @{<= 3} -> '<=
|
|
107
|
+
case _ -> x * 2
|
|
108
|
+
}
|
|
109
|
+
case _ -> x to_s * 2
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
match_it: "hello, world!" . is: 'string
|
|
114
|
+
match_it: [] . is: 'empty
|
|
115
|
+
match_it: <[]> . is: 'empty
|
|
116
|
+
match_it: (Set new) . is: 'empty
|
|
117
|
+
match_it: (Stack new) . is: 'empty
|
|
118
|
+
match_it: [1,2,3] . is: 'not_empty
|
|
119
|
+
match_it: (1,"foo") . is: 'not_empty
|
|
120
|
+
match_it: <['foo => 'bar]> . is: 'not_empty
|
|
121
|
+
match_it: 'yo . is: 'symbol
|
|
122
|
+
match_it: 32 . is: 64
|
|
123
|
+
match_it: 4 . is: 8
|
|
124
|
+
match_it: 3 . is: '<=
|
|
125
|
+
match_it: 2 . is: '<=
|
|
126
|
+
match_it: 0 . is: '<=
|
|
127
|
+
match_it: -1 . is: '<=
|
|
128
|
+
}
|
|
93
129
|
}
|
data/tests/range.fy
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
FancySpec describe: Range with: {
|
|
2
|
-
it: "
|
|
3
|
-
Range new: 1 to: 10 . to_a size
|
|
4
|
-
(1..10) to_a size
|
|
5
|
-
("a".."z") to_a size
|
|
2
|
+
it: "has the correct amount of elements" with: 'size when: {
|
|
3
|
+
Range new: 1 to: 10 . to_a size is: 10
|
|
4
|
+
(1..10) to_a size is: 10
|
|
5
|
+
("a".."z") to_a size is: 26
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
it: "
|
|
9
|
-
(1..10)
|
|
8
|
+
it: "has a working literal syntax" when: {
|
|
9
|
+
(1..10) is: (Range new: 1 to: 10)
|
|
10
10
|
}
|
|
11
11
|
}
|
data/tests/set.fy
CHANGED
|
@@ -1,10 +1,107 @@
|
|
|
1
1
|
FancySpec describe: Set with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "only keeps unique values" with: '[] when: {
|
|
3
3
|
s = Set new
|
|
4
4
|
s << 'foo
|
|
5
5
|
s << 'foo
|
|
6
|
-
s size
|
|
7
|
-
s
|
|
8
|
-
s
|
|
6
|
+
s size is: 1
|
|
7
|
+
s is: (Set[['foo]])
|
|
8
|
+
s is_not: ['foo] # Sets and Arrays differ
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
it: "is empty" with: 'empty? when: {
|
|
12
|
+
s = Set new
|
|
13
|
+
s empty? is: true
|
|
14
|
+
s = Set[[]]
|
|
15
|
+
s empty? is: true
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
it: "is not empty" with: 'empty? when: {
|
|
19
|
+
s = Set new
|
|
20
|
+
s << 1
|
|
21
|
+
s empty? is: false
|
|
22
|
+
s = Set[[1,2,3]]
|
|
23
|
+
s empty? is: false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
it: "has the correct size" with: 'size when: {
|
|
27
|
+
s = Set new
|
|
28
|
+
s size is: 0
|
|
29
|
+
s << 'foo
|
|
30
|
+
s size is: 1
|
|
31
|
+
10 times: {
|
|
32
|
+
s << 'bar # only inserted once
|
|
33
|
+
}
|
|
34
|
+
s size is: 2
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
it: "is equal to another set" with: '== when: {
|
|
38
|
+
s1 = Set new
|
|
39
|
+
s2 = Set new
|
|
40
|
+
s1 == s2 is: true
|
|
41
|
+
|
|
42
|
+
s1 = Set[[1,2,3]]
|
|
43
|
+
s2 = Set[[3,2,1]]
|
|
44
|
+
s3 = Set[[3,1,2]]
|
|
45
|
+
s1 == s2 is: true
|
|
46
|
+
s1 == s3 is: true
|
|
47
|
+
s2 == s1 is: true
|
|
48
|
+
s2 == s3 is: true
|
|
49
|
+
s3 == s1 is: true
|
|
50
|
+
s3 == s2 is: true
|
|
51
|
+
|
|
52
|
+
s1 << 1 # should have no effect
|
|
53
|
+
s2 << 3
|
|
54
|
+
s2 == s1 is: true
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
it: "includes a value" with: 'includes?: when: {
|
|
58
|
+
s = Set[[1,2,3,"foo", 'bar, 10.0, 10.1]]
|
|
59
|
+
s includes?: 1 . is: true
|
|
60
|
+
s includes?: 2 . is: true
|
|
61
|
+
s includes?: 3 . is: true
|
|
62
|
+
s includes?: "foo" . is: true
|
|
63
|
+
s includes?: 'bar . is: true
|
|
64
|
+
s includes?: 10.0 . is: true
|
|
65
|
+
s includes?: 10.1 . is: true
|
|
66
|
+
s includes?: 'hello . is: false
|
|
67
|
+
s includes?: nil . is: false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
it: "calls a Block with each value" with: 'each: when: {
|
|
71
|
+
s = Set[[1,2,3,4]]
|
|
72
|
+
sum = 0
|
|
73
|
+
s each: |val| {
|
|
74
|
+
sum = sum + val
|
|
75
|
+
s includes?: val . is: true
|
|
76
|
+
}
|
|
77
|
+
sum is: (s sum)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
it: "removes a value in the Set" with: 'remove: when: {
|
|
81
|
+
s = Set[(1,2,3)]
|
|
82
|
+
s remove: 2
|
|
83
|
+
s is: (Set[(1,3)])
|
|
84
|
+
s remove: 1
|
|
85
|
+
s is: (Set[[3]])
|
|
86
|
+
s remove: 3
|
|
87
|
+
s empty? . is: true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
it: "returns the union of two sets" with: '+ when: {
|
|
91
|
+
s1 = Set[(1,2,3)]
|
|
92
|
+
s2 = Set[(3,4,5)]
|
|
93
|
+
s1 + s2 is: (Set[(1,2,3,4,5)])
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
it: "returns the difference of two sets" with: '- when: {
|
|
97
|
+
s1 = Set[(1,2,3)]
|
|
98
|
+
s2 = Set[(3,4,5)]
|
|
99
|
+
s1 - s2 is: (Set[(1,2)])
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
it: "returns the intersection of two sets" with: '& when: {
|
|
103
|
+
s1 = Set[(1,2,3)]
|
|
104
|
+
s2 = Set[(2,3,4,5)]
|
|
105
|
+
s1 & s2 is: (Set[(2,3)])
|
|
9
106
|
}
|
|
10
107
|
}
|
data/tests/stack.fy
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
FancySpec describe: Stack with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "is empty when created" with: '<< when: {
|
|
3
3
|
s = Stack new
|
|
4
|
-
s empty?
|
|
4
|
+
s empty? is: true
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
it: "
|
|
7
|
+
it: "returns the last inserted element" with: 'pop when: {
|
|
8
8
|
s = Stack new
|
|
9
9
|
s push: 1
|
|
10
|
-
s pop
|
|
10
|
+
s pop is: 1
|
|
11
11
|
|
|
12
12
|
objs = [1,2,3]
|
|
13
13
|
objs each: |x| {
|
|
@@ -15,8 +15,17 @@ FancySpec describe: Stack with: {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
objs reverse each: |x| {
|
|
18
|
-
s pop
|
|
18
|
+
s pop is: x
|
|
19
19
|
}
|
|
20
|
+
}
|
|
20
21
|
|
|
22
|
+
it: "calls a Block with each element, starting with the top of stack" with: 'each: when: {
|
|
23
|
+
s = Stack new
|
|
24
|
+
10 times: |i| { s << i }
|
|
25
|
+
val = 9
|
|
26
|
+
s each: |x| {
|
|
27
|
+
x is: val
|
|
28
|
+
val = val - 1
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
}
|
data/tests/string.fy
CHANGED
|
@@ -1,109 +1,163 @@
|
|
|
1
1
|
FancySpec describe: String with: {
|
|
2
|
-
it: "
|
|
2
|
+
it: "is the empty string on initialization" when: {
|
|
3
3
|
str = String new
|
|
4
|
-
str
|
|
4
|
+
str is: ""
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
it: "
|
|
7
|
+
it: "is the concatination of the strings" with: '+ when: {
|
|
8
8
|
str1 = "hello "
|
|
9
9
|
str2 = "world"
|
|
10
10
|
str3 = "!"
|
|
11
|
-
str1 + str2 + str3
|
|
11
|
+
str1 + str2 + str3 is: "hello world!"
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
it: "
|
|
15
|
-
"I'm " ++ 21 ++ " years old!"
|
|
14
|
+
it: "concatenates the argument's string value with a string" with: '++ when: {
|
|
15
|
+
"I'm " ++ 21 ++ " years old!" is: "I'm 21 years old!"
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
it: "
|
|
19
|
-
"hello, world" from: 2 to: 5 .
|
|
20
|
-
"hello, world"[[2,5]] .
|
|
18
|
+
it: "returns the correct substring" with: 'from:to: when: {
|
|
19
|
+
"hello, world" from: 2 to: 5 . is: "llo,"
|
|
20
|
+
"hello, world"[[2,5]] . is: "llo,"
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
it: "
|
|
24
|
-
"hello, world" upcase
|
|
23
|
+
it: "returns the upcased string" with: 'upcase when: {
|
|
24
|
+
"hello, world" upcase is: "HELLO, WORLD"
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
it: "
|
|
28
|
-
"HELLO, WORLD" downcase
|
|
27
|
+
it: "returns the downcased string" with: 'downcase when: {
|
|
28
|
+
"HELLO, WORLD" downcase is: "hello, world"
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
it: "
|
|
32
|
-
"HELLO, WORLD" downcase upcase
|
|
31
|
+
it: "returns the same string by down- and upcasing in a row" when: {
|
|
32
|
+
"HELLO, WORLD" downcase upcase is: "HELLO, WORLD"
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
it: "
|
|
35
|
+
it: "iterates over each character in a string" with: 'each: when: {
|
|
36
36
|
str = "Hello, World!"
|
|
37
37
|
i = 0
|
|
38
38
|
str each: |char| {
|
|
39
|
-
char
|
|
39
|
+
char is: (str at: i)
|
|
40
40
|
i = i + 1
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
it: "
|
|
44
|
+
it: "behaves like a collection/sequence via each:" with: 'uniq when: {
|
|
45
45
|
str = "Hello, World!"
|
|
46
|
-
str uniq join: "" .
|
|
46
|
+
str uniq join: "" . is: "Helo, Wrd!"
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
it: "
|
|
49
|
+
it: "has all its characters as instances of String class" with: 'all?: when: {
|
|
50
50
|
str = "foo bar baz"
|
|
51
|
-
str all?: |c| { c is_a?: String } .
|
|
51
|
+
str all?: |c| { c is_a?: String } . is: true
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
it: "drops all characters upto a whitespace" with: 'drop_while: when: {
|
|
55
|
+
"hello world" drop_while: |c| { c != " " } . join: "" . is: " world"
|
|
56
|
+
}
|
|
57
57
|
|
|
58
|
-
it: "
|
|
59
|
-
"" empty?
|
|
60
|
-
" " empty?
|
|
61
|
-
String new empty?
|
|
58
|
+
it: "is empty" with: 'empty? when: {
|
|
59
|
+
"" empty? is: true
|
|
60
|
+
" " empty? is: false
|
|
61
|
+
String new empty? is: true
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
it: "is blank" with: 'blank? when: {
|
|
65
|
+
"" blank? is: true
|
|
66
|
+
" " blank? is: true
|
|
67
|
+
"-" blank? is: false
|
|
68
|
+
" " blank? is: true
|
|
69
|
+
"hello world" blank? is: false
|
|
70
|
+
"hello world" at: 5 . blank? is: true
|
|
71
|
+
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
it: "is evaluated as fancy code and returns the correct value" when: {
|
|
74
|
+
x = "'foo" eval
|
|
75
|
+
x is: 'foo
|
|
76
|
+
"3 + 4" eval is: 7
|
|
77
|
+
"'foo to_s upcase" eval is: "FOO"
|
|
78
|
+
"33.33" eval is: 33.33
|
|
79
|
+
}
|
|
80
80
|
|
|
81
|
-
it: "
|
|
82
|
-
"foo" * 2
|
|
83
|
-
"f" ++ ("o" * 2) ++ "bar"
|
|
81
|
+
it: "returns itself times n" with: '* when: {
|
|
82
|
+
"foo" * 2 is: "foofoo"
|
|
83
|
+
"f" ++ ("o" * 2) ++ "bar" is: "foobar"
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
it: "
|
|
86
|
+
it: "splits a string at a given seperator string" with: 'split: when: {
|
|
87
87
|
str = "hello, world, how are you?"
|
|
88
|
-
str split: ", " .
|
|
89
|
-
"1,2,3,,4,5" split: "," .
|
|
90
|
-
",1,2,3,4," split: "," .
|
|
91
|
-
"foo bar\n baz yo" split
|
|
92
|
-
"foo bar\n baz yo" words
|
|
88
|
+
str split: ", " . is: ["hello", "world", "how are you?"]
|
|
89
|
+
"1,2,3,,4,5" split: "," . is: ["1", "2", "3", "", "4", "5"]
|
|
90
|
+
",1,2,3,4," split: "," . is: ["", "1", "2", "3", "4"]
|
|
91
|
+
"foo bar\n baz yo" split is: ["foo", "bar", "baz", "yo"]
|
|
92
|
+
"foo bar\n baz yo" words is: ["foo", "bar", "baz", "yo"]
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
it: "
|
|
96
|
-
"hello, #{10 * 10} world!"
|
|
95
|
+
it: "supports basic string interpolation" when: {
|
|
96
|
+
"hello, #{10 * 10} world!" is: "hello, 100 world!"
|
|
97
97
|
x = "world"
|
|
98
|
-
"hello, #{x}!!"
|
|
98
|
+
"hello, #{x}!!" is: "hello, world!!"
|
|
99
|
+
|
|
100
|
+
"hello, #{x}, Fancy #{'rocks to_s upcase}!!" is: "hello, world, Fancy ROCKS!!"
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
it: "returns the String as a Symbol" with: 'to_sym when: {
|
|
104
|
+
"foo" to_sym is: 'foo
|
|
105
|
+
"foo:bar:" to_sym is: 'foo:bar:
|
|
106
|
+
"FooBar?!" to_sym is: 'FooBar?!
|
|
107
|
+
"+-&/^\?a!" to_sym is '+-&/^\?a!
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
it: "allows replacing characters in the string" with: '[]: when: {
|
|
111
|
+
s = "hello"
|
|
112
|
+
s[0]: "H"
|
|
113
|
+
s is: "Hello"
|
|
114
|
+
s[0]: "Good day. H"
|
|
115
|
+
s is: "Good day. Hello"
|
|
116
|
+
s[-1]: "o."
|
|
117
|
+
s is: "Good day. Hello."
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
it: "contains a substring" with: 'includes?: when: {
|
|
121
|
+
"foo bar baz" includes?: "foo" . is: true
|
|
122
|
+
"foo bar baz" includes?: "bar" . is: true
|
|
123
|
+
"foo bar baz" includes?: "baz" . is: true
|
|
124
|
+
"foo bar baz" includes?: " " . is: true
|
|
125
|
+
"foo bar baz" includes?: "" . is: true
|
|
126
|
+
"foo bar baz" includes?: "foobarbaz" . is: false
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
it: "should remove any leading indentation" with: 'skip_leading_indentation when: {
|
|
130
|
+
"""
|
|
131
|
+
hello, world!
|
|
132
|
+
how are you?
|
|
133
|
+
""" skip_leading_indentation is: "hello, world!\nhow are you?"
|
|
134
|
+
|
|
135
|
+
str = """
|
|
136
|
+
foo, bar
|
|
137
|
+
"""
|
|
138
|
+
str skip_leading_indentation is_not: str
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
it: "returns an array of all its characters" with: 'characters when: {
|
|
142
|
+
"foo" characters is: ["f","o","o"]
|
|
143
|
+
"" characters is: []
|
|
144
|
+
"f" characters is: ["f"]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
it: "returns its first character as a fixnum ascii value" with: 'character when: {
|
|
148
|
+
"A" character is: 65
|
|
149
|
+
"a" character is: 97
|
|
150
|
+
"ab" character is: $ "a" character
|
|
151
|
+
"" character is: nil
|
|
152
|
+
}
|
|
99
153
|
|
|
100
|
-
|
|
154
|
+
it: "returns an enumerator for its all bytes (fixnum ascii values)" with: 'bytes when: {
|
|
155
|
+
"foo" bytes class is: FancyEnumerator
|
|
156
|
+
"" bytes class is: FancyEnumerator
|
|
101
157
|
}
|
|
102
158
|
|
|
103
|
-
it: "
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"FooBar?!" to_sym should == 'FooBar?!
|
|
107
|
-
"+-&/^\?a!" to_sym should '+-&/^\?a!
|
|
159
|
+
it: "returns a joined string using FancyEnumerable#join:" for: 'join: when: {
|
|
160
|
+
"foobar" join: "-" . is: "f-o-o-b-a-r"
|
|
161
|
+
"" join: "-" . is: ""
|
|
108
162
|
}
|
|
109
163
|
}
|