apotomo 1.0.5 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/.gitignore +5 -0
  2. data/CHANGES.textile +35 -7
  3. data/Gemfile +0 -2
  4. data/README.rdoc +9 -9
  5. data/apotomo.gemspec +3 -3
  6. data/lib/apotomo.rb +4 -47
  7. data/lib/apotomo/event.rb +2 -0
  8. data/lib/apotomo/event_handler.rb +0 -3
  9. data/lib/apotomo/event_methods.rb +6 -2
  10. data/lib/apotomo/invoke_event_handler.rb +5 -3
  11. data/lib/apotomo/javascript_generator.rb +19 -16
  12. data/lib/apotomo/rails/controller_methods.rb +84 -131
  13. data/lib/apotomo/rails/view_helper.rb +15 -31
  14. data/lib/apotomo/railtie.rb +24 -0
  15. data/lib/apotomo/request_processor.rb +17 -48
  16. data/lib/apotomo/test_case.rb +5 -5
  17. data/lib/apotomo/tree_node.rb +52 -61
  18. data/lib/apotomo/version.rb +1 -1
  19. data/lib/apotomo/widget.rb +70 -146
  20. data/lib/apotomo/widget/javascript_methods.rb +39 -0
  21. data/lib/apotomo/widget_shortcuts.rb +14 -40
  22. data/lib/generators/apotomo/widget_generator.rb +8 -9
  23. data/lib/generators/erb/widget_generator.rb +17 -0
  24. data/lib/generators/haml/widget_generator.rb +20 -0
  25. data/lib/generators/{apotomo/templates → templates}/view.erb +1 -1
  26. data/lib/generators/templates/view.haml +4 -0
  27. data/lib/generators/{apotomo/templates → templates}/widget.rb +1 -1
  28. data/lib/generators/{apotomo/templates → templates}/widget_test.rb +1 -1
  29. data/lib/generators/test_unit/widget_generator.rb +14 -0
  30. data/test/rails/caching_test.rb +10 -17
  31. data/test/rails/controller_methods_test.rb +9 -81
  32. data/test/rails/rails_integration_test.rb +76 -60
  33. data/test/rails/view_helper_test.rb +17 -28
  34. data/test/rails/widget_generator_test.rb +19 -31
  35. data/test/support/test_case_methods.rb +6 -20
  36. data/test/test_helper.rb +15 -25
  37. data/test/unit/event_handler_test.rb +1 -0
  38. data/test/unit/event_methods_test.rb +20 -8
  39. data/test/unit/event_test.rb +5 -0
  40. data/test/unit/javascript_generator_test.rb +19 -19
  41. data/test/unit/render_test.rb +17 -112
  42. data/test/unit/request_processor_test.rb +73 -111
  43. data/test/unit/test_case_test.rb +13 -7
  44. data/test/unit/widget_shortcuts_test.rb +24 -53
  45. data/test/unit/widget_test.rb +76 -36
  46. data/test/widgets/mouse/eat.erb +1 -0
  47. data/test/{fixtures → widgets}/mouse/eating.html.erb +0 -0
  48. data/test/{fixtures → widgets}/mouse/educate.html.erb +0 -0
  49. data/test/{fixtures → widgets}/mouse/feed.html.erb +0 -0
  50. data/test/{fixtures → widgets}/mouse/make_me_squeak.html.erb +0 -0
  51. data/test/{fixtures → widgets}/mouse/posing.html.erb +0 -0
  52. data/test/widgets/mouse/snuggle.html.erb +1 -0
  53. metadata +32 -50
  54. data/lib/apotomo/container_widget.rb +0 -10
  55. data/lib/apotomo/persistence.rb +0 -112
  56. data/lib/apotomo/rails/view_methods.rb +0 -7
  57. data/lib/apotomo/stateful_widget.rb +0 -29
  58. data/lib/apotomo/transition.rb +0 -46
  59. data/lib/generators/apotomo/templates/view.haml +0 -4
  60. data/test/dummy/log/production.log +0 -0
  61. data/test/dummy/log/server.log +0 -0
  62. data/test/dummy/public/javascripts/application.js +0 -2
  63. data/test/dummy/public/javascripts/controls.js +0 -965
  64. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  65. data/test/dummy/public/javascripts/effects.js +0 -1123
  66. data/test/dummy/public/javascripts/prototype.js +0 -6001
  67. data/test/dummy/public/javascripts/rails.js +0 -175
  68. data/test/dummy/script/rails +0 -6
  69. data/test/dummy/tmp/app/cells/mouse_widget.rb +0 -11
  70. data/test/dummy/tmp/app/cells/mouse_widget/snuggle.html.erb +0 -7
  71. data/test/dummy/tmp/app/cells/mouse_widget/squeak.html.erb +0 -7
  72. data/test/dummy/tmp/test/widgets/mouse_widget_test.rb +0 -12
  73. data/test/fixtures/application_widget_tree.rb +0 -2
  74. data/test/fixtures/mouse/snuggle.html.erb +0 -1
  75. data/test/rails/view_methods_test.rb +0 -38
  76. data/test/unit/container_test.rb +0 -21
  77. data/test/unit/invoke_test.rb +0 -126
  78. data/test/unit/persistence_test.rb +0 -201
  79. data/test/unit/stateful_widget_test.rb +0 -58
  80. data/test/unit/test_addressing.rb +0 -110
  81. data/test/unit/test_jump_to_state.rb +0 -89
  82. data/test/unit/test_tab_panel.rb +0 -71
  83. data/test/unit/transition_test.rb +0 -34
@@ -1,175 +0,0 @@
1
- (function() {
2
- // Technique from Juriy Zaytsev
3
- // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
- function isEventSupported(eventName) {
5
- var el = document.createElement('div');
6
- eventName = 'on' + eventName;
7
- var isSupported = (eventName in el);
8
- if (!isSupported) {
9
- el.setAttribute(eventName, 'return;');
10
- isSupported = typeof el[eventName] == 'function';
11
- }
12
- el = null;
13
- return isSupported;
14
- }
15
-
16
- function isForm(element) {
17
- return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
- }
19
-
20
- function isInput(element) {
21
- if (Object.isElement(element)) {
22
- var name = element.nodeName.toUpperCase()
23
- return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
- }
25
- else return false
26
- }
27
-
28
- var submitBubbles = isEventSupported('submit'),
29
- changeBubbles = isEventSupported('change')
30
-
31
- if (!submitBubbles || !changeBubbles) {
32
- // augment the Event.Handler class to observe custom events when needed
33
- Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
- function(init, element, eventName, selector, callback) {
35
- init(element, eventName, selector, callback)
36
- // is the handler being attached to an element that doesn't support this event?
37
- if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
- (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
- // "submit" => "emulated:submit"
40
- this.eventName = 'emulated:' + this.eventName
41
- }
42
- }
43
- )
44
- }
45
-
46
- if (!submitBubbles) {
47
- // discover forms on the page by observing focus events which always bubble
48
- document.on('focusin', 'form', function(focusEvent, form) {
49
- // special handler for the real "submit" event (one-time operation)
50
- if (!form.retrieve('emulated:submit')) {
51
- form.on('submit', function(submitEvent) {
52
- var emulated = form.fire('emulated:submit', submitEvent, true)
53
- // if custom event received preventDefault, cancel the real one too
54
- if (emulated.returnValue === false) submitEvent.preventDefault()
55
- })
56
- form.store('emulated:submit', true)
57
- }
58
- })
59
- }
60
-
61
- if (!changeBubbles) {
62
- // discover form inputs on the page
63
- document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
- // special handler for real "change" events
65
- if (!input.retrieve('emulated:change')) {
66
- input.on('change', function(changeEvent) {
67
- input.fire('emulated:change', changeEvent, true)
68
- })
69
- input.store('emulated:change', true)
70
- }
71
- })
72
- }
73
-
74
- function handleRemote(element) {
75
- var method, url, params;
76
-
77
- var event = element.fire("ajax:before");
78
- if (event.stopped) return false;
79
-
80
- if (element.tagName.toLowerCase() === 'form') {
81
- method = element.readAttribute('method') || 'post';
82
- url = element.readAttribute('action');
83
- params = element.serialize();
84
- } else {
85
- method = element.readAttribute('data-method') || 'get';
86
- url = element.readAttribute('href');
87
- params = {};
88
- }
89
-
90
- new Ajax.Request(url, {
91
- method: method,
92
- parameters: params,
93
- evalScripts: true,
94
-
95
- onComplete: function(request) { element.fire("ajax:complete", request); },
96
- onSuccess: function(request) { element.fire("ajax:success", request); },
97
- onFailure: function(request) { element.fire("ajax:failure", request); }
98
- });
99
-
100
- element.fire("ajax:after");
101
- }
102
-
103
- function handleMethod(element) {
104
- var method = element.readAttribute('data-method'),
105
- url = element.readAttribute('href'),
106
- csrf_param = $$('meta[name=csrf-param]')[0],
107
- csrf_token = $$('meta[name=csrf-token]')[0];
108
-
109
- var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
- element.parentNode.insert(form);
111
-
112
- if (method !== 'post') {
113
- var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
- form.insert(field);
115
- }
116
-
117
- if (csrf_param) {
118
- var param = csrf_param.readAttribute('content'),
119
- token = csrf_token.readAttribute('content'),
120
- field = new Element('input', { type: 'hidden', name: param, value: token });
121
- form.insert(field);
122
- }
123
-
124
- form.submit();
125
- }
126
-
127
-
128
- document.on("click", "*[data-confirm]", function(event, element) {
129
- var message = element.readAttribute('data-confirm');
130
- if (!confirm(message)) event.stop();
131
- });
132
-
133
- document.on("click", "a[data-remote]", function(event, element) {
134
- if (event.stopped) return;
135
- handleRemote(element);
136
- event.stop();
137
- });
138
-
139
- document.on("click", "a[data-method]", function(event, element) {
140
- if (event.stopped) return;
141
- handleMethod(element);
142
- event.stop();
143
- });
144
-
145
- document.on("submit", function(event) {
146
- var element = event.findElement(),
147
- message = element.readAttribute('data-confirm');
148
- if (message && !confirm(message)) {
149
- event.stop();
150
- return false;
151
- }
152
-
153
- var inputs = element.select("input[type=submit][data-disable-with]");
154
- inputs.each(function(input) {
155
- input.disabled = true;
156
- input.writeAttribute('data-original-value', input.value);
157
- input.value = input.readAttribute('data-disable-with');
158
- });
159
-
160
- var element = event.findElement("form[data-remote]");
161
- if (element) {
162
- handleRemote(element);
163
- event.stop();
164
- }
165
- });
166
-
167
- document.on("ajax:after", "form", function(event, element) {
168
- var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
- inputs.each(function(input) {
170
- input.value = input.readAttribute('data-original-value');
171
- input.removeAttribute('data-original-value');
172
- input.disabled = false;
173
- });
174
- });
175
- })();
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
-
4
- APP_PATH = File.expand_path('../../config/application', __FILE__)
5
- require File.expand_path('../../config/boot', __FILE__)
6
- require 'rails/commands'
@@ -1,11 +0,0 @@
1
- class MouseWidget < Apotomo::Widget
2
-
3
- def squeak
4
- render
5
- end
6
-
7
- def snuggle
8
- render
9
- end
10
-
11
- end
@@ -1,7 +0,0 @@
1
- <h1>
2
- MouseWidget#snuggle
3
- </h1>
4
-
5
- <p>
6
- Find me in app/cells/mouse_widget/snuggle.html.erb
7
- </p>
@@ -1,7 +0,0 @@
1
- <h1>
2
- MouseWidget#squeak
3
- </h1>
4
-
5
- <p>
6
- Find me in app/cells/mouse_widget/squeak.html.erb
7
- </p>
@@ -1,12 +0,0 @@
1
- require 'test_helper'
2
-
3
- class MouseWidgetTest < Apotomo::TestCase
4
- has_widgets do |root|
5
- root << widget(:mouse_widget, 'me')
6
- end
7
-
8
- test "display" do
9
- render_widget 'me'
10
- assert_select "h1"
11
- end
12
- end
@@ -1,2 +0,0 @@
1
- class ApplicationWidgetTree < Apotomo::WidgetTree
2
- end
@@ -1 +0,0 @@
1
- <div id="<%= @name %>"><snuggle><%= rendered_children.collect{|e| e.last}.join("").html_safe %></snuggle></div>
@@ -1,38 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ViewMethodsTest < ActionController::TestCase
4
- include Apotomo::TestCaseMethods::TestController
5
-
6
- context "A Rails controller view" do
7
- setup do
8
- @controller.instance_variable_set(:@mum, mouse_mock('mum', 'snuggle') {def snuggle; render; end})
9
- @controller.instance_eval do
10
- def widget
11
- use_widgets do |root|
12
- root << @mum
13
- end
14
- render :inline => "<%= render_widget 'mum' %>"
15
- end
16
- end
17
- end
18
-
19
- should "respond to render_widget" do
20
- get :widget
21
- assert_select "#mum>snuggle"
22
- end
23
-
24
- should "respond to url_for_event" do
25
- @controller.instance_eval do
26
- def widget
27
- use_widgets do |root|
28
- root << @mum
29
- end
30
- render :inline => "<%= url_for_event :footsteps, :source => 'mum' %>"
31
- end
32
- end
33
-
34
- get :widget
35
- assert_equal "/barn/render_event_response?source=mum&amp;type=footsteps", @response.body
36
- end
37
- end
38
- end
@@ -1,21 +0,0 @@
1
- require 'test_helper'
2
-
3
- class ContainerTest < Test::Unit::TestCase
4
- include Apotomo::TestCaseMethods::TestController
5
-
6
- context "Rendering a container" do
7
- setup do
8
- @family = container('family')
9
- end
10
-
11
- should "return an empty view if childless" do
12
- assert_equal "<div id=\"family\"></div>", @family.invoke
13
- end
14
-
15
- should "provide a family picture" do
16
- @family << mouse_mock('mum')
17
- @family << mouse_mock('kid')
18
- assert_equal "<div id=\"family\"><div id=\"mum\">burp!</div>\n<div id=\"kid\">burp!</div></div>", @family.invoke
19
- end
20
- end
21
- end
@@ -1,126 +0,0 @@
1
- require 'test_helper'
2
-
3
- class InvokeTest < Test::Unit::TestCase
4
- include Apotomo::TestCaseMethods::TestController
5
-
6
- class LocalMouse < MouseCell
7
- def snuggle; render; end
8
- def educate; render :view => :snuggle; end
9
- end
10
-
11
- context "Invoking a single widget" do
12
- setup do
13
- @mum = LocalMouse.new(parent_controller, 'mum', :snuggle)
14
- end
15
-
16
- context "implicitely" do
17
- should "always enter the given state" do
18
- @mum.invoke :snuggle
19
- assert_equal 'snuggle', @mum.last_state
20
-
21
- @mum.invoke :educate
22
- assert_equal 'educate', @mum.last_state
23
- end
24
- end
25
-
26
- context "explicitely" do
27
- should "per default enter the start state" do
28
- @mum.invoke
29
- assert_equal 'snuggle', @mum.last_state
30
-
31
- @mum.invoke
32
- assert_equal 'snuggle', @mum.last_state
33
- end
34
-
35
- context "with defined transitions" do
36
- setup do
37
- @mum.instance_eval do
38
- self.class.transition :from => :snuggle, :to => :educate
39
- end
40
-
41
- @mum.invoke
42
- assert_equal 'snuggle', @mum.last_state
43
- end
44
-
45
- should "automatically follow the transitions if defined" do
46
- assert_equal 'snuggle', @mum.last_state
47
- @mum.invoke
48
- assert_equal 'educate', @mum.last_state
49
- end
50
-
51
- should "nevertheless allow undefined implicit invokes" do
52
- @mum.invoke :snuggle
53
- assert_equal 'snuggle', @mum.last_state
54
- end
55
- end
56
- end
57
- end
58
-
59
- context "Invoking a widget family" do
60
- setup do
61
- @mum = LocalMouse.new(parent_controller, 'mum', :snuggle)
62
-
63
- # create an anonym class for @kid so we don't pollute with #transition's.
64
- @mum << @kid = mouse_class_mock.new(parent_controller, 'kid', :snooze)
65
- @kid.instance_eval do
66
- def snooze; render :nothing => true; end
67
- def listen; render :nothing => true; end
68
- end
69
- end
70
-
71
- context "implicitely" do
72
- should "per default send kid to its start state" do
73
- @mum.invoke :snuggle
74
- assert_equal 'snuggle', @mum.last_state
75
- assert_equal 'snooze', @kid.last_state
76
-
77
- @mum.invoke :educate
78
- assert_equal 'educate', @mum.last_state
79
- assert_equal 'snooze', @kid.last_state
80
- end
81
-
82
- should "follow the kid's transition if defined" do
83
- @kid.instance_eval do
84
- self.class.transition :from => :snooze, :to => :listen
85
- end
86
-
87
- @mum.invoke :snuggle
88
- @mum.invoke :educate
89
- assert_equal 'educate', @mum.last_state
90
- assert_equal 'listen', @kid.last_state
91
- end
92
-
93
- should "send kid to the given state passed to #render" do
94
- @mum.instance_eval do
95
- def snuggle
96
- render :invoke => {'kid' => :listen}
97
- end
98
- end
99
-
100
- @mum.invoke :snuggle
101
- assert_equal 'snuggle', @mum.last_state
102
- assert_equal 'listen', @kid.last_state
103
- end
104
-
105
- should "send kid to the :invoke state as it overrides #transition" do
106
- @kid.instance_eval do
107
- self.class.transition :from => :snooze, :to => :listen
108
- end
109
-
110
- @mum.instance_eval do
111
- def educate
112
- render :nothing => true, :invoke => {'kid' => :snooze}
113
- end
114
- end
115
-
116
- @mum.invoke :snuggle
117
- assert_equal 'snuggle', @mum.last_state
118
- assert_equal 'snooze', @kid.last_state
119
-
120
- @mum.invoke :educate
121
- assert_equal 'educate', @mum.last_state
122
- assert_equal 'snooze', @kid.last_state
123
- end
124
- end
125
- end
126
- end
@@ -1,201 +0,0 @@
1
- require 'test_helper'
2
-
3
- class PersistenceTest < Test::Unit::TestCase
4
- include Apotomo::TestCaseMethods::TestController
5
-
6
- class PersistentMouse < Apotomo::StatefulWidget # we need a named class for marshalling.
7
- attr_reader :who, :what
8
-
9
- def educate
10
- @who = "the cat"
11
- @what = "run away"
12
- render :nothing => true
13
- end
14
-
15
- def recap; render :nothing => true; end
16
- end
17
-
18
- def stateless(name)
19
- Apotomo::Widget.new(parent_controller, name, :eat)
20
- end
21
-
22
- def stateful(name)
23
- PersistentMouse.new(parent_controller, name, :educate)
24
- end
25
-
26
- context "StatefulWidget" do
27
-
28
- context ".stateful_branches_for" do
29
- should "provide all stateful branch-roots seen from root" do
30
- @root = stateless('root')
31
- @root << mum_and_kid!
32
- @root << stateless('berry') << @jerry = mouse_mock('jerry', :eat)
33
-
34
- assert_equal ['mum', 'jerry'], Apotomo::StatefulWidget.stateful_branches_for(@root).collect {|n| n.name}
35
- end
36
- end
37
- end
38
-
39
- context "freezing and thawing a widget family" do
40
- setup do
41
- mum_and_kid!
42
- @storage = {}
43
- end
44
-
45
- context "and calling #flush_storage" do
46
- should "clear the storage from frozen data" do
47
- @root = stateless('root')
48
- @root << @mum
49
-
50
- Apotomo::StatefulWidget.freeze_for(@storage, @root)
51
-
52
- assert @storage[:apotomo_stateful_branches]
53
- assert @storage[:apotomo_widget_ivars]
54
-
55
- Apotomo::StatefulWidget.flush_storage(@storage)
56
-
57
- assert_nil @storage[:apotomo_stateful_branches]
58
- assert_nil @storage[:apotomo_widget_ivars]
59
- end
60
- end
61
-
62
- should "push @mum's freezable ivars to the storage when calling #freeze_ivars_to" do
63
- @mum.freeze_ivars_to(@storage)
64
-
65
- assert_equal 1, @storage.size
66
- assert_equal 6, @storage['mum'].size
67
- end
68
-
69
- should "push family's freezable ivars to the storage when calling #freeze_data_to" do
70
- @kid << mouse_mock('pet')
71
- @mum.freeze_data_to(@storage)
72
-
73
- assert_equal 3, @storage.size
74
- assert_equal 6, @storage['mum'].size
75
- assert_equal 6, @storage['mum/kid'].size
76
- assert_equal 5, @storage['mum/kid/pet'].size
77
- end
78
-
79
- should "push ivars and structure to the storage when calling #freeze_to" do
80
- @mum.freeze_to(@storage)
81
- assert_equal 2, @storage[:apotomo_widget_ivars].size
82
- assert_kind_of Apotomo::StatefulWidget, @storage[:apotomo_root]
83
- end
84
-
85
- context "that has also stateless widgets" do
86
- setup do
87
- @root = stateless('root')
88
- @root << mum_and_kid!
89
- @root << stateless('berry') << @jerry = mouse_mock('jerry', :eat)
90
- @root << stateless('tom')
91
-
92
- Apotomo::StatefulWidget.freeze_for(@storage, @root)
93
- end
94
-
95
- should "ignore stateless widgets when calling #freeze_for" do
96
- assert_equal(['root/mum', 'root/mum/kid', "root/berry/jerry"], @storage[:apotomo_widget_ivars].keys)
97
- end
98
-
99
- should "save stateful branches only" do
100
- assert_equal([[[MouseCell, 'mum', 'root'], [MouseCell, 'kid', 'mum']], [[MouseCell, 'jerry', 'berry']]], @storage[:apotomo_stateful_branches])
101
- end
102
-
103
- should "attach stateful branches to the tree in thaw_for" do
104
- @new_root = stateless('root')
105
- @new_root << stateless('berry')
106
- assert_equal @new_root, Apotomo::StatefulWidget.thaw_for(@controller, @storage, @new_root)
107
-
108
- assert_equal 5, @new_root.size # without tom.
109
- end
110
-
111
- should "re-establish ivars recursivly when calling #thaw_for" do
112
- @storage[:apotomo_stateful_branches] = Marshal.load(Marshal.dump(@storage[:apotomo_stateful_branches]))
113
-
114
- @new_root = stateless('root')
115
- @new_root << stateless('berry')
116
- @new_root = Apotomo::StatefulWidget.thaw_for(@controller, @storage, @new_root)
117
-
118
- assert_equal :answer_squeak, @new_root['mum'].instance_variable_get(:@start_state)
119
- assert_equal :peek, @new_root['mum']['kid'].instance_variable_get(:@start_state)
120
- end
121
-
122
- should "raise an exception when thaw_for can't find the branch's parent" do
123
- @new_root = stateless('dad')
124
-
125
- assert_raises RuntimeError do
126
- Apotomo::StatefulWidget.thaw_for(@controller, @storage, @new_root)
127
- end
128
- end
129
-
130
- should "clear the fields in the storage when fetching in #thaw_for" do
131
- @new_root = stateless('root')
132
- @new_root << stateless('berry')
133
-
134
- Apotomo::StatefulWidget.thaw_for(@controller, @storage, @new_root)
135
-
136
- assert_nil @storage[:apotomo_stateful_branches]
137
- assert_nil @storage[:apotomo_widget_ivars]
138
- end
139
- end
140
-
141
- should "update @mum's ivars when calling #thaw_ivars_from" do
142
- @mum.instance_variable_set(:@name, "zombie mum")
143
- assert_equal 'zombie mum', @mum.name
144
-
145
- @mum.thaw_ivars_from({'zombie mum' => {'@name' => 'mum'}})
146
- assert_equal 'mum', @mum.name
147
- end
148
-
149
- should "update family's ivars when calling #thaw_data_from" do
150
- @kid << @pet = mouse_mock('pet')
151
- @kid.instance_variable_set(:@name, "paranoid kid")
152
- @pet.instance_variable_set(:@name, "mad dog")
153
- assert_equal "paranoid kid", @kid.name
154
-
155
- @mum.thaw_data_from({ "mum/paranoid kid" => {'@name' => 'kid'},
156
- "mum/kid/mad dog" => {'@name' => 'pet'}})
157
- assert_equal 'kid', @kid.name
158
- assert_equal 'pet', @pet.name
159
- end
160
-
161
-
162
- end
163
-
164
- context "#dump_tree" do
165
- setup do
166
- @mum = stateful('mum')
167
- @mum << @kid = stateful('kid')
168
- @kid << @pet = stateful('pet')
169
- @mum << @berry = stateful('berry')
170
-
171
- end
172
-
173
- should "return a list of widget metadata" do
174
- assert_equal [[PersistentMouse, 'mum', nil], [PersistentMouse, 'kid', 'mum'], [PersistentMouse, 'pet', 'kid'], [PersistentMouse, 'berry', 'mum']], @mum.dump_tree
175
- end
176
-
177
- should "return a tree for #load_tree" do
178
- cold_widgets = @mum.dump_tree
179
- assert_equal ['mum', 'kid', 'pet', 'berry'], Apotomo::StatefulWidget.send(:load_tree, @controller, cold_widgets).collect { |n| n.name }
180
- end
181
-
182
- context "#frozen_widget_in?" do
183
- should "return true if a valid widget is passed" do
184
- @session = {}
185
- assert_not Apotomo::StatefulWidget.frozen_widget_in?(@session)
186
- Apotomo::StatefulWidget.freeze_for(@session, @berry)
187
- assert Apotomo::StatefulWidget.frozen_widget_in?(@session)
188
- end
189
- end
190
- end
191
-
192
-
193
-
194
- context "#symbolized_instance_variables?" do
195
- should "return instance_variables as symbols" do
196
- @mum = mouse_mock
197
- assert_equal @mum.instance_variables.size, @mum.symbolized_instance_variables.size
198
- assert_not @mum.symbolized_instance_variables.find { |ivar| ivar.kind_of? String }
199
- end
200
- end
201
- end