savage 0.1.0 → 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.
@@ -17,13 +17,9 @@ describe CubicCurveTo do
17
17
  @dir.respond_to?(:target).should == true
18
18
  @dir.target.class.should == Point
19
19
  end
20
- it 'should have a first control point' do
21
- @dir.respond_to?(:control_1).should == true
22
- @dir.control_1.class.should == Point
23
- end
24
- it 'should have a first control point' do
25
- @dir.respond_to?(:control_2).should == true
26
- @dir.control_2.class.should == Point
20
+ it 'should have a control point' do
21
+ @dir.respond_to?(:control).should == true
22
+ @dir.control.class.should == Point
27
23
  end
28
24
  it 'should have an accessible target x, based on the constructor argument' do
29
25
  @dir.target.x.should == 500
@@ -31,55 +27,60 @@ describe CubicCurveTo do
31
27
  it 'should have an accessible target y, based on the constructor argument' do
32
28
  @dir.target.y.should == 600
33
29
  end
34
- it 'should have an accessible first control x, based on the constructor argument' do
35
- @dir.control_1.x.should == 100
36
- end
37
- it 'should have an accessible first control y, based on the constructor argument' do
38
- @dir.control_1.y.should == 200
39
- end
40
30
  it 'should have an accessible second control x, based on the constructor argument' do
41
31
  @dir.control_2.x.should == 300
42
32
  end
43
33
  it 'should have an accessible second control y, based on the constructor argument' do
44
34
  @dir.control_2.y.should == 400
45
35
  end
46
- it 'should be constructed with at least target x and y, a control 1 x and y, and a control 2 x and y parameters' do
47
- lambda { dir_class.new }.should raise_error
48
- lambda { dir_class.new 45 }.should raise_error
49
- lambda { dir_class.new 45, 50 }.should raise_error
50
- lambda { dir_class.new 45, 50, 60 }.should raise_error
51
- lambda { dir_class.new 45, 50, 60, 70 }.should raise_error
52
- lambda { dir_class.new 45, 50, 60, 70, 80 }.should raise_error
53
- lambda { dir_class.new 45, 50, 60, 70, 80, 90 }.should_not raise_error
54
- lambda { dir_class.new 45, 50, 60, 70, 80, 90, true }.should_not raise_error
55
- end
56
- it 'should be relative if constructed with a true seventh parameter' do
57
- direction = dir_class.new 45, 50, 60, 70, 80, 90, false
58
- direction.absolute?.should == false
59
- end
60
- it 'should be absolute if constructed with a false seventh parameter' do
61
- direction = dir_class.new 45, 50, 60, 70, 80, 90, true
62
- direction.absolute?.should == true
63
- end
64
- it 'should be absolute if constructed with only six parameters' do
65
- direction = dir_class.new 45, 50, 60, 70, 80, 90
66
- direction.absolute?.should == true
67
- end
68
- describe '#to_command' do
69
- context 'when not asked to be continuous' do
36
+ context 'when in verbose format' do
37
+ it 'should be constructed with at least target x and y, control 1 x and y, and control 2 x and y parameters' do
38
+ lambda { dir_class.new }.should raise_error
39
+ lambda { dir_class.new 45 }.should raise_error
40
+ lambda { dir_class.new 45, 50 }.should raise_error
41
+ lambda { dir_class.new 45, 50, 60 }.should raise_error
42
+ lambda { dir_class.new 45, 50, 60, 70, 80 }.should raise_error
43
+ lambda { dir_class.new 45, 50, 60, 70, 80, 90 }.should_not raise_error
44
+ lambda { dir_class.new 45, 50, 60, 70, 80, 90, true }.should_not raise_error
45
+ end
46
+ it 'should be relative if constructed with a false seventh parameter' do
47
+ direction = dir_class.new 45, 50, 60, 70, 80, 90, false
48
+ direction.absolute?.should == false
49
+ end
50
+ it 'should be absolute if constructed with a true seventh parameter' do
51
+ direction = dir_class.new 45, 50, 60, 70, 80, 90, true
52
+ direction.absolute?.should == true
53
+ end
54
+ it 'should be absolute if constructed with only six parameters' do
55
+ direction = dir_class.new 45, 50, 60, 70, 80, 90
56
+ direction.absolute?.should == true
57
+ end
58
+ it 'should have an accessible first control x, based on the constructor argument' do
59
+ @dir.control_1.x.should == 100
60
+ end
61
+ it 'should have an accessible first control y, based on the constructor argument' do
62
+ @dir.control_1.y.should == 200
63
+ end
64
+ describe '#to_command' do
65
+ it 'should start with a lower-case c when not absolute' do
66
+ extract_command(CubicCurveTo.new(100,200,300,400,500,600,false).to_command).should == 'c'
67
+ end
68
+ it 'should start with a capital C when absolute' do
69
+ extract_command(@dir.to_command).should == 'C'
70
+ end
70
71
  it 'should have exactly 6 numerical parameters' do
71
72
  extract_coordinates(@dir.to_command).length.should == 6
72
73
  end
73
- it 'should show the provided control 1 X value as the first parameter' do
74
+ it 'should show the provided first control X value as the first parameter' do
74
75
  extract_coordinates(@dir.to_command)[0].should == 100
75
76
  end
76
- it 'should show the provided control 1 Y value as the second parameter' do
77
+ it 'should show the provided first control Y value as the second parameter' do
77
78
  extract_coordinates(@dir.to_command)[1].should == 200
78
79
  end
79
- it 'should show the provided control 2 X value as the third parameter' do
80
+ it 'should show the provided second control X value as the third parameter' do
80
81
  extract_coordinates(@dir.to_command)[2].should == 300
81
82
  end
82
- it 'should show the provided control 2 Y value as the fourth parameter' do
83
+ it 'should show the provided second control Y value as the fourth parameter' do
83
84
  extract_coordinates(@dir.to_command)[3].should == 400
84
85
  end
85
86
  it 'should show the provided target X value as the fifth parameter' do
@@ -89,28 +90,55 @@ describe CubicCurveTo do
89
90
  extract_coordinates(@dir.to_command)[5].should == 600
90
91
  end
91
92
  end
92
- context 'when asked to be continuous' do
93
+ end
94
+ context 'when in shorthand format' do
95
+ before :each do
96
+ @dir = CubicCurveTo.new(100,200,300,400)
97
+ end
98
+ it 'should be constructed with at least target x and y parameters' do
99
+ lambda { dir_class.new }.should raise_error
100
+ lambda { dir_class.new 45 }.should raise_error
101
+ lambda { dir_class.new 45, 50 }.should raise_error
102
+ lambda { dir_class.new 45, 50, 60 }.should raise_error
103
+ lambda { dir_class.new 45, 50, 60, 70 }.should_not raise_error
104
+ lambda { dir_class.new 45, 50, 60, 70, true }.should_not raise_error
105
+ end
106
+ it 'should be relative if constructed with a false third parameter' do
107
+ direction = dir_class.new 45, 50, 60, 70, false
108
+ direction.absolute?.should == false
109
+ end
110
+ it 'should be absolute if constructed with a true third parameter' do
111
+ direction = dir_class.new 45, 50, 60, 70, true
112
+ direction.absolute?.should == true
113
+ end
114
+ it 'should be absolute if constructed with only two parameters' do
115
+ direction = dir_class.new 45, 50, 60, 70
116
+ direction.absolute?.should == true
117
+ end
118
+ it 'should have an nil first control, based on the constructor argument' do
119
+ @dir.control_1.should == nil
120
+ end
121
+ describe '#to_command' do
93
122
  it 'should start with a lower-case s when not absolute' do
94
- rel_dir = create_relative
95
- extract_command(rel_dir.to_command(true)).should == 's'
123
+ extract_command(CubicCurveTo.new(100,200,300,400,false).to_command).should == 's'
96
124
  end
97
125
  it 'should start with a capital S when absolute' do
98
- extract_command(@dir.to_command(true)).should == 'S'
126
+ extract_command(@dir.to_command).should == 'S'
99
127
  end
100
- it 'should have exactly 4 numerical parameters' do
101
- extract_coordinates(@dir.to_command(true)).length.should == 4
128
+ it 'should have exactly 2 numerical parameters' do
129
+ extract_coordinates(@dir.to_command).length.should == 4
102
130
  end
103
- it 'should show the provided control 2 X value as the first parameter' do
104
- extract_coordinates(@dir.to_command(true))[0].should == 300
131
+ it 'should show the provided second control X value as the first parameter' do
132
+ extract_coordinates(@dir.to_command)[0].should == 100
105
133
  end
106
- it 'should show the provided control 2 Y value as the second parameter' do
107
- extract_coordinates(@dir.to_command(true))[1].should == 400
134
+ it 'should show the provided second control Y value as the second parameter' do
135
+ extract_coordinates(@dir.to_command)[1].should == 200
108
136
  end
109
137
  it 'should show the provided target X value as the third parameter' do
110
- extract_coordinates(@dir.to_command(true))[2].should == 500
138
+ extract_coordinates(@dir.to_command)[2].should == 300
111
139
  end
112
140
  it 'should show the provided target Y value as the fourth parameter' do
113
- extract_coordinates(@dir.to_command(true))[3].should == 600
141
+ extract_coordinates(@dir.to_command)[3].should == 400
114
142
  end
115
143
  end
116
144
  end
@@ -27,54 +27,96 @@ describe QuadraticCurveTo do
27
27
  it 'should have an accessible target y, based on the constructor argument' do
28
28
  @dir.target.y.should == 400
29
29
  end
30
- it 'should have an accessible first control x, based on the constructor argument' do
31
- @dir.control.x.should == 100
32
- end
33
- it 'should have an accessible first control y, based on the constructor argument' do
34
- @dir.control.y.should == 200
35
- end
36
- it 'should be constructed with at least target x and y, a control 1 x and y, and a control 2 x and y parameters' do
37
- lambda { dir_class.new }.should raise_error
38
- lambda { dir_class.new 45 }.should raise_error
39
- lambda { dir_class.new 45, 50 }.should raise_error
40
- lambda { dir_class.new 45, 50, 60 }.should raise_error
41
- lambda { dir_class.new 45, 50, 60, 70 }.should_not raise_error
42
- lambda { dir_class.new 45, 50, 60, 70, true }.should_not raise_error
43
- end
44
- it 'should be relative if constructed with a false fifth parameter' do
45
- direction = dir_class.new 45, 50, 60, 70, false
46
- direction.absolute?.should == false
47
- end
48
- it 'should be absolute if constructed with a true fifth parameter' do
49
- direction = dir_class.new 45, 50, 60, 70, true
50
- direction.absolute?.should == true
51
- end
52
- it 'should be absolute if constructed with only four parameters' do
53
- direction = dir_class.new 45, 50, 60, 70
54
- direction.absolute?.should == true
30
+ context 'when in verbose format' do
31
+ it 'should be constructed with at least target x and y and control x and y parameters' do
32
+ lambda { dir_class.new }.should raise_error
33
+ lambda { dir_class.new 45 }.should raise_error
34
+ lambda { dir_class.new 45, 50, 60 }.should raise_error
35
+ lambda { dir_class.new 45, 50, 60, 70 }.should_not raise_error
36
+ lambda { dir_class.new 45, 50, 60, 70, true }.should_not raise_error
37
+ end
38
+ it 'should be relative if constructed with a false fifth parameter' do
39
+ direction = dir_class.new 45, 50, 60, 70, false
40
+ direction.absolute?.should == false
41
+ end
42
+ it 'should be absolute if constructed with a true fifth parameter' do
43
+ direction = dir_class.new 45, 50, 60, 70, true
44
+ direction.absolute?.should == true
45
+ end
46
+ it 'should be absolute if constructed with only four parameters' do
47
+ direction = dir_class.new 45, 50, 60, 70
48
+ direction.absolute?.should == true
49
+ end
50
+ it 'should have an accessible first control x, based on the constructor argument' do
51
+ @dir.control.x.should == 100
52
+ end
53
+ it 'should have an accessible first control y, based on the constructor argument' do
54
+ @dir.control.y.should == 200
55
+ end
56
+ describe '#to_command' do
57
+ it 'should start with a lower-case q when not absolute' do
58
+ extract_command(QuadraticCurveTo.new(100,200,300,400,false).to_command).should == 'q'
59
+ end
60
+ it 'should start with a capital Q when absolute' do
61
+ extract_command(@dir.to_command).should == 'Q'
62
+ end
63
+ it 'should have exactly 4 numerical parameters' do
64
+ extract_coordinates(@dir.to_command).length.should == 4
65
+ end
66
+ it 'should show the provided control X value as the first parameter' do
67
+ extract_coordinates(@dir.to_command)[0].should == 100
68
+ end
69
+ it 'should show the provided control Y value as the second parameter' do
70
+ extract_coordinates(@dir.to_command)[1].should == 200
71
+ end
72
+ it 'should show the provided target X value as the third parameter' do
73
+ extract_coordinates(@dir.to_command)[2].should == 300
74
+ end
75
+ it 'should show the provided target Y value as the fourth parameter' do
76
+ extract_coordinates(@dir.to_command)[3].should == 400
77
+ end
78
+ end
55
79
  end
56
- describe '#to_command' do
57
- it 'should start with a capital T when not absolute' do
58
- rel_dir = create_relative
59
- extract_command(rel_dir.to_command(true)).should == 't'
80
+ context 'when in shorthand format' do
81
+ before :each do
82
+ @dir = QuadraticCurveTo.new(100,200)
60
83
  end
61
- it 'should start with a lower-case t when absolute' do
62
- extract_command(@dir.to_command(true)).should == 'T'
84
+ it 'should be constructed with at least target x and y parameters' do
85
+ lambda { dir_class.new }.should raise_error
86
+ lambda { dir_class.new 45 }.should raise_error
87
+ lambda { dir_class.new 45, 50 }.should_not raise_error
63
88
  end
64
- it 'should have exactly 4 numerical parameters' do
65
- extract_coordinates(@dir.to_command).length.should == 4
89
+ it 'should be relative if constructed with a false third parameter' do
90
+ direction = dir_class.new 45, 50, false
91
+ direction.absolute?.should == false
66
92
  end
67
- it 'should show the provided control X value as the first parameter' do
68
- extract_coordinates(@dir.to_command)[0].should == 100
93
+ it 'should be absolute if constructed with a true third parameter' do
94
+ direction = dir_class.new 45, 50, true
95
+ direction.absolute?.should == true
69
96
  end
70
- it 'should show the provided control Y value as the second parameter' do
71
- extract_coordinates(@dir.to_command)[1].should == 200
97
+ it 'should be absolute if constructed with only two parameters' do
98
+ direction = dir_class.new 45, 50
99
+ direction.absolute?.should == true
72
100
  end
73
- it 'should show the provided target X value as the third parameter' do
74
- extract_coordinates(@dir.to_command)[2].should == 300
101
+ it 'should have an nil control, based on the constructor argument' do
102
+ @dir.control.should == nil
75
103
  end
76
- it 'should show the provided target Y value as the fourth parameter' do
77
- extract_coordinates(@dir.to_command)[3].should == 400
104
+ describe '#to_command' do
105
+ it 'should start with a lower-case t when not absolute' do
106
+ extract_command(QuadraticCurveTo.new(100,200,false).to_command).should == 't'
107
+ end
108
+ it 'should start with a capital T when absolute' do
109
+ extract_command(@dir.to_command).should == 'T'
110
+ end
111
+ it 'should have exactly 2 numerical parameters' do
112
+ extract_coordinates(@dir.to_command).length.should == 2
113
+ end
114
+ it 'should show the provided target X value as the first parameter' do
115
+ extract_coordinates(@dir.to_command)[0].should == 100
116
+ end
117
+ it 'should show the provided target Y value as the second parameter' do
118
+ extract_coordinates(@dir.to_command)[1].should == 200
119
+ end
78
120
  end
79
121
  end
80
122
  end
@@ -0,0 +1,174 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ include Savage
4
+
5
+ describe Parser do
6
+ it 'should have a parse method' do
7
+ Parser.respond_to?(:parse).should == true
8
+ end
9
+ describe '.parse' do
10
+ it 'should accept a single string as argument' do
11
+ lambda { Parser.parse }.should raise_error
12
+ lambda { Parser.parse("M100 200") }.should_not raise_error
13
+ lambda { Parser.parse(2) }.should raise_error
14
+ end
15
+ it 'should return a path object with one subpath containing one move_to when the string is only a move_to command' do
16
+ path = Parser.parse("M100 200")
17
+ path.class.should == Path
18
+ path.subpaths.length.should == 1
19
+ path.subpaths.last.directions.length.should == 1
20
+ path.subpaths.last.directions.last.class.should == Directions::MoveTo
21
+ end
22
+
23
+ it 'should return a path object with one subpath containing a move_to and a line_to when the string is a move_to command followed by a line_to command' do
24
+ path = Parser.parse("M100 200l-342.65 21")
25
+ path.class.should == Path
26
+ path.subpaths.length.should == 1
27
+ path.subpaths.last.directions.length.should == 2
28
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
29
+ path.subpaths.last.directions[1].should_not be_absolute
30
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
31
+ end
32
+ it 'should return a path object with one subpath containing a move_to and a horizontal_to when the string is a move_to command followed by a horizontal_to command' do
33
+ path = Parser.parse("M100 200H-342.65")
34
+ path.class.should == Path
35
+ path.subpaths.length.should == 1
36
+ path.subpaths.last.directions.length.should == 2
37
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
38
+ path.subpaths.last.directions[1].class.should == Directions::HorizontalTo
39
+ end
40
+ it 'should return a path object with one subpath containing a move_to and a vertical_to when the string is a move_to command followed by a vertical_to command' do
41
+ path = Parser.parse("M100 200V-342.65")
42
+ path.class.should == Path
43
+ path.subpaths.length.should == 1
44
+ path.subpaths.last.directions.length.should == 2
45
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
46
+ path.subpaths.last.directions[1].class.should == Directions::VerticalTo
47
+ end
48
+ it 'should return a path object with one subpath containing a move_to and a full cubic_curve_to when the string is a move_to command followed by a full cubic_curve_to command' do
49
+ path = Parser.parse("M100 200C-342.65-32 1.233-34 255 12")
50
+ path.class.should == Path
51
+ path.subpaths.length.should == 1
52
+ path.subpaths.last.directions.length.should == 2
53
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
54
+ path.subpaths.last.directions[1].class.should == Directions::CubicCurveTo
55
+ path.subpaths.last.directions[1].command_code.should == 'C'
56
+ end
57
+ it 'should return a path object with one subpath containing a move_to and a short cubic_curve_to when the string is a move_to command followed by a short cubic_curve_to command' do
58
+ path = Parser.parse("M100 200S1.233-34 255 12")
59
+ path.class.should == Path
60
+ path.subpaths.length.should == 1
61
+ path.subpaths.last.directions.length.should == 2
62
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
63
+ path.subpaths.last.directions[1].class.should == Directions::CubicCurveTo
64
+ path.subpaths.last.directions[1].command_code.should == 'S'
65
+ end
66
+ it 'should return a path object with one subpath containing a move_to and a full quadratic_curve_to when the string is a move_to command followed by a full quadratic_curve_to command' do
67
+ path = Parser.parse("M100 200Q1.233-34 255 12")
68
+ path.class.should == Path
69
+ path.subpaths.length.should == 1
70
+ path.subpaths.last.directions.length.should == 2
71
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
72
+ path.subpaths.last.directions[1].class.should == Directions::QuadraticCurveTo
73
+ path.subpaths.last.directions[1].command_code.should == 'Q'
74
+ end
75
+ it 'should return a path object with one subpath containing a move_to and a short quadratic_curve_to when the string is a move_to command followed by a short quadratic_curve_to command' do
76
+ path = Parser.parse("M100 200T255 12")
77
+ path.class.should == Path
78
+ path.subpaths.length.should == 1
79
+ path.subpaths.last.directions.length.should == 2
80
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
81
+ path.subpaths.last.directions[1].class.should == Directions::QuadraticCurveTo
82
+ path.subpaths.last.directions[1].command_code.should == 'T'
83
+ end
84
+ it 'should return a path object with one subpath containing a move_to and an arc_to when the string is a move_to command followed by an arc_to command' do
85
+ path = Parser.parse("M100 200A255 12-123 1 0 23-93.4")
86
+ path.class.should == Path
87
+ path.subpaths.length.should == 1
88
+ path.subpaths.last.directions.length.should == 2
89
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
90
+ path.subpaths.last.directions[1].class.should == Directions::ArcTo
91
+ path.subpaths.last.directions[1].command_code.should == 'A'
92
+ end
93
+ it 'should return a path object with one subpath containing a move_to, a line_to, and a close_path command when the string is a move_to command followed by a line_to followed by a close_path command' do
94
+ path = Parser.parse("M100 200l-342.65 21Z")
95
+ path.class.should == Path
96
+ path.subpaths.length.should == 1
97
+ path.subpaths.last.directions.length.should == 3
98
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
99
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
100
+ path.subpaths.last.directions[2].class.should == Directions::ClosePath
101
+ path.subpaths.last.closed?.should == true
102
+ end
103
+
104
+ it 'should return a path object with one subpath containing two line_to directions when the string is a line_to command followed by implicit coordinates' do
105
+ path = Parser.parse("L100 200 300 400")
106
+ path.class.should == Path
107
+ path.subpaths.length.should == 1
108
+ path.subpaths.last.directions.length.should == 2
109
+ path.subpaths.last.directions[0].class.should == Directions::LineTo
110
+ path.subpaths.last.directions[0].target.x.should == 100
111
+ path.subpaths.last.directions[0].target.y.should == 200
112
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
113
+ path.subpaths.last.directions[1].target.x.should == 300
114
+ path.subpaths.last.directions[1].target.y.should == 400
115
+ end
116
+ it 'should return a path object with one subpath containing two line_to directions when the string is a line_to command followed by implicit coordinates' do
117
+ path = Parser.parse("L100 200 300 400")
118
+ path.class.should == Path
119
+ path.subpaths.length.should == 1
120
+ path.subpaths.last.directions.length.should == 2
121
+ path.subpaths.last.directions[0].class.should == Directions::LineTo
122
+ path.subpaths.last.directions[0].target.x.should == 100
123
+ path.subpaths.last.directions[0].target.y.should == 200
124
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
125
+ path.subpaths.last.directions[1].target.x.should == 300
126
+ path.subpaths.last.directions[1].target.y.should == 400
127
+ end
128
+ it 'should return a path object with one subpath containing a move_to and a line_to direction when the string is a move_to command followed by implicit coordinates' do
129
+ path = Parser.parse("M100 200 300 400")
130
+ path.class.should == Path
131
+ path.subpaths.length.should == 1
132
+ path.subpaths.last.directions.length.should == 2
133
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
134
+ path.subpaths.last.directions[0].target.x.should == 100
135
+ path.subpaths.last.directions[0].target.y.should == 200
136
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
137
+ path.subpaths.last.directions[1].target.x.should == 300
138
+ path.subpaths.last.directions[1].target.y.should == 400
139
+ end
140
+ it 'should return a path object with one subpath containing a move_to and two line_to directions when the string is a move_to command followed by more than one set of implicit coordinates' do
141
+ path = Parser.parse("M100 200 300 400 500 600 ")
142
+ path.class.should == Path
143
+ path.subpaths.length.should == 1
144
+ path.subpaths.last.directions.length.should == 3
145
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
146
+ path.subpaths.last.directions[0].target.x.should == 100
147
+ path.subpaths.last.directions[0].target.y.should == 200
148
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
149
+ path.subpaths.last.directions[1].target.x.should == 300
150
+ path.subpaths.last.directions[1].target.y.should == 400
151
+ path.subpaths.last.directions[2].class.should == Directions::LineTo
152
+ path.subpaths.last.directions[2].target.x.should == 500
153
+ path.subpaths.last.directions[2].target.y.should == 600
154
+ end
155
+ it 'should return a path object with two subpaths containing one line_to directions each when the string is two move_to commands each followed by a line_to command' do
156
+ path = Parser.parse("M100 200 332 -12.3M594 230-423 11.1")
157
+ path.class.should == Path
158
+ path.subpaths.length.should == 2
159
+ path.subpaths[0].directions.length.should == 2
160
+ path.subpaths[0].directions[0].class.should == Directions::MoveTo
161
+ path.subpaths[0].directions[0].target.x.should == 100
162
+ path.subpaths[0].directions[0].target.y.should == 200
163
+ path.subpaths[0].directions[1].class.should == Directions::LineTo
164
+ path.subpaths[0].directions[1].target.x.should == 332
165
+ path.subpaths[0].directions[1].target.y.should == -12.3
166
+ path.subpaths[1].directions[0].class.should == Directions::MoveTo
167
+ path.subpaths[1].directions[0].target.x.should == 594
168
+ path.subpaths[1].directions[0].target.y.should == 230
169
+ path.subpaths[1].directions[1].class.should == Directions::LineTo
170
+ path.subpaths[1].directions[1].target.x.should == -423
171
+ path.subpaths[1].directions[1].target.y.should == 11.1
172
+ end
173
+ end
174
+ end
@@ -6,14 +6,61 @@ describe Path do
6
6
  it 'should accept no parameters in a constructor for a new, empty path' do
7
7
  lambda{ Path.new }.should_not raise_error
8
8
  end
9
- it 'should accept a string parameter to build a path based on existing path data' do
10
- lambda{ Path.new("M100 200") }.should_not raise_error
9
+ it 'should be able to be constructed with a starting point (absolute move to)' do
10
+ path = Path.new(100,200)
11
+ path.subpaths.length.should == 1
12
+ path.subpaths.last.directions.length.should == 1
13
+ path.subpaths.last.directions.last.class.should == Directions::MoveTo
11
14
  end
12
- it 'should raise an error if anything besides a string is passed to the constructor' do
13
- lambda{ Path.new([]) }.should raise_error
14
- lambda{ Path.new({}) }.should raise_error
15
- lambda{ Path.new(56) }.should raise_error
16
- lambda{ Path.new(Object.new) }.should raise_error
15
+ it 'should be able to build itself in a block' do
16
+ path = Path.new(100,200) do |p|
17
+ p.line_to 300, 400
18
+ p.cubic_curve_to 500,600,700,800,900,1000
19
+ p.arc_to 100,200,123,1,1,300,400
20
+ end
21
+ path.subpaths.last.directions[0].class.should == Directions::MoveTo
22
+ path.subpaths.last.directions[1].class.should == Directions::LineTo
23
+ path.subpaths.last.directions[2].class.should == Directions::CubicCurveTo
24
+ path.subpaths.last.directions[3].class.should == Directions::ArcTo
25
+
26
+ path2 = Path.new do |p|
27
+ p.line_to 300, 400
28
+ p.cubic_curve_to 500,600,700,800,900,1000
29
+ p.arc_to 100,200,123,1,1,300,400
30
+ end
31
+ path2.subpaths.last.directions[0].class.should == Directions::LineTo
32
+ path2.subpaths.last.directions[1].class.should == Directions::CubicCurveTo
33
+ path2.subpaths.last.directions[2].class.should == Directions::ArcTo
34
+ end
35
+ it 'should have a directions list' do
36
+ Path.new.respond_to?(:directions).should == true
37
+ end
38
+ it 'should have a move_to method' do
39
+ Path.new.respond_to?(:move_to).should == true
40
+ end
41
+ it 'should have a line_to method' do
42
+ Path.new.respond_to?(:line_to).should == true
43
+ end
44
+ it 'should have a horizontal_to method' do
45
+ Path.new.respond_to?(:horizontal_to).should == true
46
+ end
47
+ it 'should have a vertical_to method' do
48
+ Path.new.respond_to?(:vertical_to).should == true
49
+ end
50
+ it 'should have a quadratic_curve_to method' do
51
+ Path.new.respond_to?(:quadratic_curve_to).should == true
52
+ end
53
+ it 'should have a cubic_curve_to method' do
54
+ Path.new.respond_to?(:cubic_curve_to).should == true
55
+ end
56
+ it 'should have a arc_to method' do
57
+ Path.new.respond_to?(:arc_to).should == true
58
+ end
59
+ it 'should have a close_path method' do
60
+ Path.new.respond_to?(:close_path).should == true
61
+ end
62
+ it 'should have a closed? method' do
63
+ Path.new.respond_to?(:closed?).should == true
17
64
  end
18
65
  it 'should have subpaths' do
19
66
  Path.new.respond_to?(:subpaths).should == true
@@ -21,4 +68,38 @@ describe Path do
21
68
  it 'should have a to_command method' do
22
69
  Path.new.respond_to?(:to_command).should == true
23
70
  end
71
+ describe '#move_to' do
72
+ it 'should create a new subpath with that movement therein if there is already a populated subpath' do
73
+ path = Path.new(200,300) do |p|
74
+ p.line_to(123,456)
75
+ p.close_path
76
+ end
77
+ path.move_to(200,300)
78
+ path.subpaths.length.should == 2
79
+ path.subpaths.last.directions.length.should == 1
80
+ path.subpaths.last.directions.last.class.should == Directions::MoveTo
81
+ end
82
+ it 'should create append the movement if the last subpath is empty a populated subpath' do
83
+ path = Path.new
84
+ path.move_to(200,300)
85
+ path.subpaths.length.should == 1
86
+ path.subpaths.last.directions.length.should == 1
87
+ path.subpaths.last.directions.last.class.should == Directions::MoveTo
88
+ end
89
+ end
90
+ describe '#to_command' do
91
+ it 'should concatenate all its subpaths command strings' do
92
+ path = Path.new(100,200) do |p|
93
+ p.line_to 300, 400
94
+ p.cubic_curve_to 500,600,700,800,900,1000
95
+ p.arc_to 100,200,123,1,1,300,400
96
+ p.close_path
97
+ p.move_to 499, 232
98
+ p.line_to 2433.4, -231
99
+ p.line_to -233, 122
100
+ end
101
+ concatenated = path.subpaths.collect { |subpath| subpath.to_command }.join
102
+ path.to_command.should == concatenated
103
+ end
104
+ end
24
105
  end