teacup 0.0.1.pre → 0.3.1
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/.gitignore +5 -3
- data/CHANGES.md +26 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +1 -1
- data/LICENSE +26 -0
- data/README.md +383 -95
- data/Rakefile +8 -36
- data/app/app_delegate.rb +14 -0
- data/app/controllers/first_controller.rb +71 -0
- data/app/controllers/landscape_only_controller.rb +16 -0
- data/app/controllers/tableview_controller.rb +0 -0
- data/app/styles/main_styles.rb +111 -0
- data/app/views/custom_view.rb +4 -0
- data/lib/dummy.rb +56 -0
- data/lib/teacup/handler.rb +99 -0
- data/lib/teacup/layout.rb +22 -74
- data/lib/teacup/merge_defaults.rb +45 -0
- data/lib/teacup/style.rb +93 -0
- data/lib/teacup/stylesheet.rb +242 -0
- data/lib/teacup/stylesheet_extensions/rotation.rb +38 -0
- data/lib/teacup/version.rb +1 -1
- data/lib/teacup/z_core_extensions/ca_layer.rb +6 -0
- data/lib/teacup/z_core_extensions/ui_view.rb +119 -0
- data/lib/teacup/z_core_extensions/ui_view_controller.rb +179 -0
- data/lib/teacup/z_core_extensions/ui_view_getters.rb +34 -0
- data/lib/teacup/z_core_extensions/z_handlers.rb +57 -0
- data/lib/teacup.rb +16 -33
- data/samples/Hai/Rakefile +7 -2
- data/samples/Hai/app/app_delegate.rb +2 -2
- data/samples/Hai/app/hai_controller.rb +8 -4
- data/samples/Hai/styles/iphone.rb +40 -0
- data/spec/main_spec.rb +226 -0
- data/spec/style_spec.rb +171 -0
- data/spec/stylesheet_spec.rb +348 -0
- data/spec/view_spec.rb +103 -0
- data/teacup.gemspec +13 -13
- metadata +47 -46
- data/.rspec +0 -2
- data/lib/teacup/contributors.rb +0 -7
- data/lib/teacup/core_extensions/ui_view.rb +0 -4
- data/lib/teacup/core_extensions/ui_view_controller.rb +0 -62
- data/lib/teacup/style_sheet.rb +0 -195
- data/lib/teacup/view.rb +0 -123
- data/pkg/teacup-0.0.0.gem +0 -0
- data/pkg/teacup-0.0.1.gem +0 -0
- data/proposals/other/README.md +0 -45
- data/proposals/other/app/config/application.rb +0 -1
- data/proposals/other/app/config/boot.rb +0 -1
- data/proposals/other/app/config/initializers/twitter.rb +0 -7
- data/proposals/other/app/controllers/events_controller.rb +0 -28
- data/proposals/other/app/controllers/venues_controller.rb +0 -4
- data/proposals/other/app/db/README.md +0 -16
- data/proposals/other/app/db/migrations/20120514201043_create_events.rb +0 -9
- data/proposals/other/app/db/migrations/20120514201044_add_price_to_events.rb +0 -5
- data/proposals/other/app/db/migrations/20120514201045_create_venues.rb +0 -8
- data/proposals/other/app/db/schema.rb +0 -19
- data/proposals/other/app/models/event.rb +0 -14
- data/proposals/other/app/models/venue.rb +0 -3
- data/proposals/other/app/views/events/edit.ipad.rb +0 -8
- data/proposals/other/app/views/events/edit.iphone.rb +0 -7
- data/proposals/other/app/views/events/show.ipad.rb +0 -2
- data/proposals/other/app/views/events/show.iphone.rb +0 -3
- data/samples/Hai/styles/ipad.rb +0 -11
- data/samples/Hai/styles/ipad_vertical.rb +0 -3
- data/spec/spec_helper.rb +0 -5
- data/spec/teacup/contributions_spec.rb +0 -13
- data/spec/teacup/version_spec.rb +0 -9
data/lib/teacup.rb
CHANGED
@@ -1,41 +1,24 @@
|
|
1
1
|
unless defined?(Motion::Project::Config)
|
2
|
-
raise "
|
2
|
+
raise "The teacup gem must be required within a RubyMotion project Rakefile."
|
3
3
|
end
|
4
4
|
|
5
|
-
# In order that we can prepend our files to the load path after the user has
|
6
|
-
# configured their app.files, we need to run code *after* the user has set up
|
7
|
-
# their app.
|
8
|
-
#
|
9
|
-
# Unfortunately, the canonical place to require rubygems is at the top of the
|
10
|
-
# file (while we could just add to the instructions "please `require 'teacup'`
|
11
|
-
# at the bottom, that would be odd, and no-one would read the instructions).
|
12
|
-
#
|
13
|
-
# To this end, we tweak the App setup function so that whenever setup is called,
|
14
|
-
# we configure teacup after that.
|
15
|
-
#
|
16
|
-
# This is not great though, as other gems may (following the instructions at
|
17
|
-
# http://reality.hk/posts/2012/05/22/create-gems-for-rubymotion/) also call
|
18
|
-
# setup...
|
19
|
-
#
|
20
|
-
# For sanity reasons, we therefore delete teacup requires from the load order
|
21
|
-
# and re-add them to the front every single time {setup} is called.
|
22
|
-
#
|
23
|
-
# TODO: We should send a patch to rubymotion that adds first-class support for
|
24
|
-
# app.gems. These could then be required *after* the user has finished running
|
25
|
-
# the setup block, so that they can just run setup properly.
|
26
|
-
#
|
27
|
-
class << Motion::Project::App
|
28
5
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
6
|
+
Motion::Project::App.setup do |app|
|
7
|
+
# scans app.files until it finds app/ (the default)
|
8
|
+
# if found, it inserts just before those files, otherwise it will insert to
|
9
|
+
# the end of the list
|
10
|
+
insert_point = 0
|
11
|
+
app.files.each_index do |index|
|
12
|
+
file = app.files[index]
|
13
|
+
if file =~ /^(?:\.\/)?app\//
|
14
|
+
# found app/, so stop looking
|
15
|
+
break
|
36
16
|
end
|
17
|
+
insert_point = index + 1
|
37
18
|
end
|
38
19
|
|
39
|
-
|
40
|
-
|
20
|
+
app.files.insert(insert_point, File.join(File.dirname(__FILE__), 'dummy.rb'))
|
21
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'teacup/**/*.rb')).reverse.each do |file|
|
22
|
+
app.files.insert(insert_point, file)
|
23
|
+
end
|
41
24
|
end
|
data/samples/Hai/Rakefile
CHANGED
@@ -4,9 +4,14 @@ require 'motion/project'
|
|
4
4
|
Motion::Project::App.setup do |app|
|
5
5
|
app.name = 'Hai'
|
6
6
|
|
7
|
-
app.device_family = :
|
7
|
+
app.device_family = :iphone
|
8
8
|
|
9
|
-
app.files += Dir.glob(File.join(app.project_dir, '
|
9
|
+
app.files += Dir.glob(File.join(app.project_dir, '../../lib/**/*.rb'))
|
10
10
|
app.files += Dir.glob(File.join(app.project_dir, 'styles/**/*.rb'))
|
11
11
|
app.files += Dir.glob(File.join(app.project_dir, 'app/**/*.rb'))
|
12
|
+
app.files_dependencies './../../lib/teacup/layout.rb' => './../../lib/teacup/stylesheet.rb'
|
13
|
+
app.files_dependencies './../../lib/teacup/z_core_extensions/ui_view_controller.rb' => './../../lib/teacup/layout.rb'
|
14
|
+
app.files_dependencies './../../lib/teacup/z_core_extensions/ui_view.rb' => './../../lib/teacup/z_core_extensions/ui_view_controller.rb'
|
15
|
+
app.files_dependencies 'app/app_delegate.rb' => './../../lib/teacup/z_core_extensions/ui_view.rb'
|
16
|
+
app.files_dependencies 'app/hai_controller.rb' => './../../lib/teacup/z_core_extensions/ui_view.rb'
|
12
17
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
class AppDelegate
|
2
2
|
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
3
3
|
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
4
|
-
@window.rootViewController = HaiViewController.alloc.init
|
4
|
+
@window.rootViewController = HaiViewController.alloc.init
|
5
5
|
@window.makeKeyAndVisible
|
6
|
-
|
6
|
+
|
7
7
|
true
|
8
8
|
end
|
9
9
|
end
|
@@ -1,9 +1,13 @@
|
|
1
1
|
class HaiViewController < UIViewController
|
2
|
+
stylesheet :iphone
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
layout :hai do
|
5
|
+
subview(UILabel, :label)
|
6
|
+
subview(UILabel, :footer)
|
7
|
+
end
|
8
|
+
|
9
|
+
def shouldAutorotateToInterfaceOrientation(orientation)
|
10
|
+
autorotateToOrientation(orientation)
|
7
11
|
end
|
8
12
|
|
9
13
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
Teacup::Stylesheet.new(:iphone) do
|
3
|
+
label_color = UIColor.blueColor
|
4
|
+
|
5
|
+
style :hai,
|
6
|
+
landscape: true
|
7
|
+
|
8
|
+
style UILabel,
|
9
|
+
textColor: label_color
|
10
|
+
|
11
|
+
style :label,
|
12
|
+
text: 'Hai!',
|
13
|
+
backgroundColor: UIColor.whiteColor,
|
14
|
+
top: 10,
|
15
|
+
left: 100,
|
16
|
+
width: 50,
|
17
|
+
height: 20,
|
18
|
+
layer: {
|
19
|
+
transform: identity,
|
20
|
+
},
|
21
|
+
landscape_left: {
|
22
|
+
layer: {
|
23
|
+
transform: rotate(identity, pi/6, 0.3, 0.3, 0.3)
|
24
|
+
},
|
25
|
+
width: 75
|
26
|
+
}
|
27
|
+
|
28
|
+
style :footer,
|
29
|
+
text: 'brought to you by teacup',
|
30
|
+
backgroundColor: UIColor.lightGrayColor,
|
31
|
+
top: 440,
|
32
|
+
left: 120,
|
33
|
+
width: 200,
|
34
|
+
height: 20,
|
35
|
+
landscape: {
|
36
|
+
left: 280,
|
37
|
+
top: 280
|
38
|
+
}
|
39
|
+
|
40
|
+
end
|
data/spec/main_spec.rb
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
describe "Application 'Teacup'" do
|
2
|
+
before do
|
3
|
+
UIDevice.currentDevice.beginGeneratingDeviceOrientationNotifications
|
4
|
+
@app = UIApplication.sharedApplication
|
5
|
+
@view_ctrlr = @app.windows[0].rootViewController
|
6
|
+
end
|
7
|
+
|
8
|
+
after do
|
9
|
+
UIDevice.currentDevice.endGeneratingDeviceOrientationNotifications
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has one window" do
|
13
|
+
@app.windows.size.should == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have a root view" do
|
17
|
+
view_ctrlr_view = @view_ctrlr.view
|
18
|
+
view_ctrlr_view.subviews.length.should == 1
|
19
|
+
view_ctrlr_view.subviews[0].class.should == CustomView
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "view controller" do
|
23
|
+
|
24
|
+
it "should be able to rotate" do
|
25
|
+
@view_ctrlr.shouldAutorotateToInterfaceOrientation(UIDeviceOrientationPortrait).should == true
|
26
|
+
@view_ctrlr.shouldAutorotateToInterfaceOrientation(UIDeviceOrientationLandscapeLeft).should == true
|
27
|
+
@view_ctrlr.shouldAutorotateToInterfaceOrientation(UIDeviceOrientationLandscapeRight).should == true
|
28
|
+
@view_ctrlr.shouldAutorotateToInterfaceOrientation(UIDeviceOrientationPortraitUpsideDown).should == false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "root view" do
|
33
|
+
|
34
|
+
before do
|
35
|
+
@root_view = @app.windows[0].subviews[0]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "root view should be styled as 'root'" do
|
39
|
+
@root_view.stylename.should == :root
|
40
|
+
@root_view.frame.origin.x.should == 0
|
41
|
+
@root_view.frame.origin.y.should == 0
|
42
|
+
@root_view.frame.size.width.should == 320
|
43
|
+
@root_view.frame.size.height.should == 480
|
44
|
+
@root_view.backgroundColor.should == UIColor.yellowColor
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "background view" do
|
50
|
+
|
51
|
+
before do
|
52
|
+
@background = @app.windows[0].subviews[0].subviews[0]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should be styled as :background" do
|
56
|
+
@background.stylename.should == :background
|
57
|
+
@background.frame.origin.x.should == 10
|
58
|
+
@background.frame.origin.y.should == 30
|
59
|
+
@background.frame.size.width.should == 300
|
60
|
+
@background.frame.size.height.should == 440
|
61
|
+
@background.backgroundColor.should == UIColor.darkGrayColor
|
62
|
+
end
|
63
|
+
|
64
|
+
it "background view should have subviews" do
|
65
|
+
@background.subviews.length.should == 3
|
66
|
+
@background.subviews[0].class.should == UILabel
|
67
|
+
@background.subviews[1].class.should == UILabel
|
68
|
+
@background.subviews[2].class.ancestors.include?(UIButton).should == true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not have styles overridden by base classes" do
|
72
|
+
@background.alpha.should == 0.5
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should have styles overridden orientation styles" do
|
76
|
+
@background.backgroundColor.should == UIColor.darkGrayColor
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "background subviews" do
|
80
|
+
|
81
|
+
before do
|
82
|
+
@welcome = @background.subviews[0]
|
83
|
+
@footer = @background.subviews[1]
|
84
|
+
@button = @background.subviews[2]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have all UILabels with color blue" do
|
88
|
+
@welcome.textColor.should == UIColor.blueColor
|
89
|
+
@footer.textColor.should == UIColor.blueColor
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "welcome" do
|
93
|
+
it "should be styled as :welcome" do
|
94
|
+
@welcome.stylename.should == :welcome
|
95
|
+
@welcome.frame.origin.x.should == 10
|
96
|
+
@welcome.frame.origin.y.should == 40
|
97
|
+
@welcome.frame.size.width.should == 280
|
98
|
+
@welcome.frame.size.height.should == 20
|
99
|
+
@welcome.text.should == "Welcome to teacup"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "footer" do
|
104
|
+
it "should be styled as :footer" do
|
105
|
+
@footer.stylename.should == :footer
|
106
|
+
@footer.frame.origin.x.should == 10
|
107
|
+
@footer.frame.origin.y.should == 410
|
108
|
+
@footer.frame.size.width.should == 280
|
109
|
+
@footer.frame.size.height.should == 20
|
110
|
+
@footer.text.should == "This is a teacup example"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "button" do
|
115
|
+
it "should be styled as :next_message" do
|
116
|
+
@button.stylename.should == :next_message
|
117
|
+
@button.frame.origin.x.should == 150
|
118
|
+
@button.frame.origin.y.should == 370
|
119
|
+
@button.frame.size.width.should == 130
|
120
|
+
@button.frame.size.height.should == 20
|
121
|
+
@button.titleForState(UIControlStateNormal).should == "Next Message..."
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "background view in landscape" do
|
130
|
+
|
131
|
+
before do
|
132
|
+
@background = @app.windows[0].subviews[0].subviews[0]
|
133
|
+
@view_ctrlr.landscape_only
|
134
|
+
UIApplication.sharedApplication.setStatusBarOrientation(UIDeviceOrientationLandscapeLeft, animated:false)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be in landscape" do
|
138
|
+
# the rest of these tests *pass*, but the device orientation isn't actually
|
139
|
+
# updated to be landscape yet... :-/
|
140
|
+
UIDevice.currentDevice.orientation.should > 0
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should be styled as :background - landscape" do
|
144
|
+
@background.stylename.should == :background
|
145
|
+
@background.frame.origin.x.should == 10
|
146
|
+
@background.frame.origin.y.should == 30
|
147
|
+
@background.frame.size.width.should == 460
|
148
|
+
@background.frame.size.height.should == 280
|
149
|
+
@background.backgroundColor.should == UIColor.lightGrayColor
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should not have styles overridden by base classes" do
|
153
|
+
@background.alpha.should == 0.8
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should have styles overridden orientation styles" do
|
157
|
+
@background.backgroundColor.should == UIColor.lightGrayColor
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "background subviews in landscape" do
|
161
|
+
|
162
|
+
before do
|
163
|
+
@welcome = @background.subviews[0]
|
164
|
+
@footer = @background.subviews[1]
|
165
|
+
@button = @background.subviews[2]
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "welcome" do
|
169
|
+
it "should be styled as :welcome - landscape" do
|
170
|
+
@welcome.stylename.should == :welcome
|
171
|
+
@welcome.frame.origin.x.should == 90
|
172
|
+
@welcome.frame.origin.y.should == 40
|
173
|
+
@welcome.frame.size.width.should == 280
|
174
|
+
@welcome.frame.size.height.should == 20
|
175
|
+
@welcome.text.should == "Welcome to teacup"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "footer" do
|
180
|
+
it "should be styled as :footer - landscape" do
|
181
|
+
@footer.stylename.should == :footer
|
182
|
+
@footer.frame.origin.x.should == 90
|
183
|
+
@footer.frame.origin.y.should == 250
|
184
|
+
@footer.frame.size.width.should == 280
|
185
|
+
@footer.frame.size.height.should == 20
|
186
|
+
@footer.text.should == "This is a teacup example"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "button" do
|
191
|
+
it "should be styled as :next_message - landscape" do
|
192
|
+
@button.stylename.should == :next_message
|
193
|
+
@button.frame.origin.x.should == 20
|
194
|
+
@button.frame.origin.y.should == 200
|
195
|
+
@button.frame.size.width.should == 130
|
196
|
+
@button.frame.size.height.should == 20
|
197
|
+
@button.titleForState(UIControlStateNormal).should == "Next Message..."
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "Stylesheet 'first'" do
|
208
|
+
before do
|
209
|
+
@stylesheet = Teacup::Stylesheet[:first]
|
210
|
+
end
|
211
|
+
|
212
|
+
it "should exist" do
|
213
|
+
@stylesheet.nil?.should == false
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should define some styles" do
|
217
|
+
@stylesheet.query(:footer)[:text].nil?.should == false
|
218
|
+
@stylesheet.query(:footer)[:text].should == "This is a teacup example"
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should union the next_message styles" do
|
222
|
+
@stylesheet.query(:next_message)[:title].should == "Next Message..."
|
223
|
+
(@stylesheet.query(:next_message)[:portrait] ? true : false).should == false
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
data/spec/style_spec.rb
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
describe "Teacup::Style" do
|
2
|
+
|
3
|
+
it "should be equal to a Hash" do
|
4
|
+
Teacup::Style.new.should == {}
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should act like a Hash" do
|
8
|
+
style = Teacup::Style.new
|
9
|
+
style[:key] = :value
|
10
|
+
style[:key].should == :value
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should use orientation to override" do
|
14
|
+
style = Teacup::Style.new
|
15
|
+
style[:name] = :default
|
16
|
+
style[:landscape] = {
|
17
|
+
name: :landscape_name,
|
18
|
+
}
|
19
|
+
style[:portrait] = {
|
20
|
+
name: :portrait_name,
|
21
|
+
}
|
22
|
+
style[:upside_down] = {
|
23
|
+
name: :upside_down_name,
|
24
|
+
}
|
25
|
+
# no orientation, which ends up being portrait anyway.
|
26
|
+
style.build()[:name].should == :portrait_name
|
27
|
+
# landscape
|
28
|
+
style.build(nil, UIInterfaceOrientationLandscapeLeft)[:name].should == :landscape_name
|
29
|
+
|
30
|
+
# upside down
|
31
|
+
style.build(nil, UIInterfaceOrientationPortraitUpsideDown)[:name].should == :upside_down_name
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should look in extends" do
|
35
|
+
sheet = Teacup::Stylesheet.new do
|
36
|
+
style :extended,
|
37
|
+
key: :value
|
38
|
+
end
|
39
|
+
sheet.query(:extended)[:key].should == :value
|
40
|
+
|
41
|
+
style = Teacup::Style.new
|
42
|
+
style.stylename = :self
|
43
|
+
style.stylesheet = sheet
|
44
|
+
style[:extends] = :extended
|
45
|
+
style.build()[:key].should == :value
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should look in import" do
|
49
|
+
imported_sheet = Teacup::Stylesheet.new do
|
50
|
+
style :extended,
|
51
|
+
imported: :imported,
|
52
|
+
override: :overridden
|
53
|
+
end
|
54
|
+
|
55
|
+
sheet = Teacup::Stylesheet.new do
|
56
|
+
import imported_sheet
|
57
|
+
|
58
|
+
style :extended,
|
59
|
+
key: :value,
|
60
|
+
override: :override
|
61
|
+
end
|
62
|
+
sheet.query(:extended)[:key].should == :value
|
63
|
+
sheet.query(:extended)[:imported].should == :imported
|
64
|
+
sheet.query(:extended)[:override].should == :override
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should merge :extends properties' do
|
68
|
+
sheet = Teacup::Stylesheet.new do
|
69
|
+
style :style1,
|
70
|
+
a: 'a',
|
71
|
+
b: 'b'
|
72
|
+
end
|
73
|
+
style2 = Teacup::Style.new
|
74
|
+
style2.stylesheet = sheet
|
75
|
+
style2[:a] = 'A'
|
76
|
+
style2[:extends] = :style1
|
77
|
+
|
78
|
+
built = style2.build()
|
79
|
+
built[:a].should == 'A'
|
80
|
+
built[:b].should == 'b'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should merge hashes' do
|
84
|
+
sheet = Teacup::Stylesheet.new do
|
85
|
+
style :style1,
|
86
|
+
layer: { borderWidth: 20, opacity: 0.5 }
|
87
|
+
end
|
88
|
+
|
89
|
+
style2 = Teacup::Style.new
|
90
|
+
style2.stylesheet = sheet
|
91
|
+
style2[:layer] = { borderWidth: 10 }
|
92
|
+
style2[:extends] = :style1
|
93
|
+
|
94
|
+
built = style2.build()
|
95
|
+
built[:layer][:opacity].should == 0.5
|
96
|
+
built[:layer][:borderWidth].should == 10
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should merge multiple extends' do
|
100
|
+
sheet = Teacup::Stylesheet.new do
|
101
|
+
style :style1,
|
102
|
+
layer: { borderWidth: 20 }
|
103
|
+
style :style2,
|
104
|
+
layer: { borderWidth: 10, opacity: 0.5 }
|
105
|
+
end
|
106
|
+
|
107
|
+
style3 = Teacup::Style.new
|
108
|
+
style3.stylesheet = sheet
|
109
|
+
style3[:extends] = [:style1, :style2]
|
110
|
+
|
111
|
+
built = style3.build()
|
112
|
+
built[:layer][:opacity].should == 0.5
|
113
|
+
built[:layer][:borderWidth].should == 20
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should merge and flatten orientation rules' do
|
117
|
+
sheet = Teacup::Stylesheet.new do
|
118
|
+
style :style1,
|
119
|
+
portrait: { text: "ignored", tag: 1 }
|
120
|
+
end
|
121
|
+
|
122
|
+
style2 = Teacup::Style.new
|
123
|
+
style2.stylesheet = sheet
|
124
|
+
style2[:portrait] = { text: "text" }
|
125
|
+
style2[:extends] = :style1
|
126
|
+
|
127
|
+
built = style2.build(nil, UIInterfaceOrientationPortrait)
|
128
|
+
built[:tag].should == 1
|
129
|
+
built[:text].should == "text"
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should respect precedence rules' do
|
133
|
+
sheet = Teacup::Stylesheet.new do
|
134
|
+
style :style1,
|
135
|
+
portrait: { text: "extended", tag: 1 }
|
136
|
+
end
|
137
|
+
|
138
|
+
style2 = Teacup::Style.new
|
139
|
+
style2.stylesheet = sheet
|
140
|
+
style2[:text] = "text"
|
141
|
+
style2[:extends] = :style1
|
142
|
+
|
143
|
+
built = style2.build(nil, UIInterfaceOrientationPortrait)
|
144
|
+
built[:tag].should == 1
|
145
|
+
built[:text].should == "text"
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should respect merge based on class inheritance' do
|
149
|
+
class Foo
|
150
|
+
attr_accessor :bar
|
151
|
+
end
|
152
|
+
|
153
|
+
class Bar < Foo
|
154
|
+
attr_accessor :baz
|
155
|
+
end
|
156
|
+
|
157
|
+
sheet = Teacup::Stylesheet.new do
|
158
|
+
style Foo,
|
159
|
+
bar: 'bar'
|
160
|
+
end
|
161
|
+
|
162
|
+
style = Teacup::Style.new
|
163
|
+
style.stylesheet = sheet
|
164
|
+
style[:baz] = 'baz'
|
165
|
+
|
166
|
+
built = style.build(Bar.new)
|
167
|
+
built[:bar].should == 'bar'
|
168
|
+
built[:baz].should == 'baz'
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|