fancygrid 1.0.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.
Files changed (97) hide show
  1. data/.bundle/config +2 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG +34 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +125 -0
  6. data/LICENSE +20 -0
  7. data/README.rdoc +299 -0
  8. data/ROADMAP +1 -0
  9. data/Rakefile +45 -0
  10. data/VERSION +1 -0
  11. data/app/views/fancygrid/_cells.html.haml +13 -0
  12. data/app/views/fancygrid/base/controls.html.haml +40 -0
  13. data/app/views/fancygrid/base/list_frame.html.haml +37 -0
  14. data/app/views/fancygrid/base/search.html.haml +33 -0
  15. data/app/views/fancygrid/base/sort.html.haml +20 -0
  16. data/app/views/fancygrid/base/table_frame.html.haml +45 -0
  17. data/config/initializers/fancygrid.rb +67 -0
  18. data/config/locales/fancygrid.de.yml +41 -0
  19. data/config/locales/fancygrid.en.yml +42 -0
  20. data/fancygrid.gemspec +162 -0
  21. data/init.rb +1 -0
  22. data/lib/fancygrid.rb +73 -0
  23. data/lib/fancygrid/grid.rb +387 -0
  24. data/lib/fancygrid/helper.rb +129 -0
  25. data/lib/fancygrid/node.rb +533 -0
  26. data/lib/fancygrid/query_generator.rb +338 -0
  27. data/lib/fancygrid/view.rb +148 -0
  28. data/lib/generators/install_generator.rb +61 -0
  29. data/lib/generators/views_generator.rb +25 -0
  30. data/lib/version.rb +0 -0
  31. data/public/images/fancygrid/add.png +0 -0
  32. data/public/images/fancygrid/clear.png +0 -0
  33. data/public/images/fancygrid/ddn.png +0 -0
  34. data/public/images/fancygrid/dn.png +0 -0
  35. data/public/images/fancygrid/dots.png +0 -0
  36. data/public/images/fancygrid/loading.gif +0 -0
  37. data/public/images/fancygrid/magnifier.png +0 -0
  38. data/public/images/fancygrid/next.png +0 -0
  39. data/public/images/fancygrid/order.png +0 -0
  40. data/public/images/fancygrid/prev.png +0 -0
  41. data/public/images/fancygrid/reload.png +0 -0
  42. data/public/images/fancygrid/remove.png +0 -0
  43. data/public/images/fancygrid/spacer.gif +0 -0
  44. data/public/images/fancygrid/submit.png +0 -0
  45. data/public/images/fancygrid/th_bg.png +0 -0
  46. data/public/images/fancygrid/up.png +0 -0
  47. data/public/images/fancygrid/uup.png +0 -0
  48. data/public/javascripts/fancygrid.js +477 -0
  49. data/public/javascripts/fancygrid.min.js +17 -0
  50. data/public/stylesheets/fancygrid.css +289 -0
  51. data/public/stylesheets/fancygrid.scss +302 -0
  52. data/spec/dummy/Rakefile +7 -0
  53. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  55. data/spec/dummy/app/models/project.rb +3 -0
  56. data/spec/dummy/app/models/ticket.rb +3 -0
  57. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  58. data/spec/dummy/config.ru +4 -0
  59. data/spec/dummy/config/application.rb +45 -0
  60. data/spec/dummy/config/boot.rb +10 -0
  61. data/spec/dummy/config/database.yml +22 -0
  62. data/spec/dummy/config/environment.rb +5 -0
  63. data/spec/dummy/config/environments/development.rb +26 -0
  64. data/spec/dummy/config/environments/production.rb +49 -0
  65. data/spec/dummy/config/environments/test.rb +35 -0
  66. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  67. data/spec/dummy/config/initializers/inflections.rb +10 -0
  68. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  69. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  70. data/spec/dummy/config/initializers/session_store.rb +8 -0
  71. data/spec/dummy/config/locales/en.yml +5 -0
  72. data/spec/dummy/config/routes.rb +58 -0
  73. data/spec/dummy/db/migrate/20110112183948_create_projects.rb +11 -0
  74. data/spec/dummy/db/migrate/20110112183956_create_tickets.rb +14 -0
  75. data/spec/dummy/db/test.sqlite3 +0 -0
  76. data/spec/dummy/log/development.log +0 -0
  77. data/spec/dummy/log/production.log +0 -0
  78. data/spec/dummy/log/server.log +0 -0
  79. data/spec/dummy/log/test.log +1026 -0
  80. data/spec/dummy/public/404.html +26 -0
  81. data/spec/dummy/public/422.html +26 -0
  82. data/spec/dummy/public/500.html +26 -0
  83. data/spec/dummy/public/favicon.ico +0 -0
  84. data/spec/dummy/public/javascripts/application.js +2 -0
  85. data/spec/dummy/public/javascripts/controls.js +965 -0
  86. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  87. data/spec/dummy/public/javascripts/effects.js +1123 -0
  88. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  89. data/spec/dummy/public/javascripts/rails.js +175 -0
  90. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  91. data/spec/dummy/script/rails +6 -0
  92. data/spec/grid_spec.rb +15 -0
  93. data/spec/integration/navigation_spec.rb +9 -0
  94. data/spec/node_spec.rb +326 -0
  95. data/spec/query_generator_spec.rb +358 -0
  96. data/spec/spec_helper.rb +53 -0
  97. metadata +214 -0
@@ -0,0 +1,175 @@
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
+ })();
File without changes
@@ -0,0 +1,6 @@
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'
data/spec/grid_spec.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe Fancygrid::Grid do
4
+ it "should get table name from model name" do
5
+ grid = Fancygrid::Grid.new(:ticket)
6
+ grid.record_table_name.should == "tickets"
7
+ end
8
+
9
+ it "should get table name from class constant" do
10
+ grid = Fancygrid::Grid.new(:foo, Ticket)
11
+ grid.record_table_name.should == "tickets"
12
+ end
13
+
14
+
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Navigation" do
4
+ include Capybara
5
+
6
+ it "should be a valid app" do
7
+ ::Rails.application.should be_a(Dummy::Application)
8
+ end
9
+ end
data/spec/node_spec.rb ADDED
@@ -0,0 +1,326 @@
1
+ require "spec_helper"
2
+
3
+ describe Fancygrid::Node do
4
+
5
+ # builds a test structure with
6
+ # 14 leafs
7
+ # 3 nodes
8
+ # 3 levels
9
+ #
10
+ # tickets
11
+ # +- title
12
+ # +- description
13
+ # +- status
14
+ # +- is_finished?
15
+ # +- actions
16
+ # +- project_id
17
+ # +- project
18
+ # +- title
19
+ # +- class
20
+ # +- actions
21
+ # +- id
22
+ # +- foo
23
+ # +- title
24
+ # +- foo
25
+ # +- bar
26
+ # +- id
27
+ #
28
+ def build_testgrid
29
+ grid = Fancygrid::Grid.new(:ticket)
30
+ grid.attributes(:title, :description, :status)
31
+ grid.methods(:is_finished?)
32
+ grid.rendered(:actions)
33
+ grid.hidden(:project_id)
34
+ grid.columns_for(:project) do |p|
35
+ p.attributes(:title)
36
+ p.methods(:class)
37
+ p.rendered(:actions)
38
+ p.hidden(:id)
39
+
40
+ p.columns_for(:foo, Project) do |f|
41
+ f.attributes(:title)
42
+ f.methods(:foo)
43
+ f.rendered(:bar)
44
+ f.hidden(:id)
45
+ end
46
+ end
47
+
48
+ return grid
49
+ end
50
+
51
+ it "should build a fancygrid tree" do
52
+
53
+ grid = build_testgrid
54
+ grid.children.length.should be 7
55
+ grid.leafs.length.should be 14
56
+
57
+ end
58
+
59
+ it "should find node by path" do
60
+
61
+ grid = build_testgrid
62
+ grid.find_by_path("ticket").name.should == :ticket
63
+ grid.find_by_path("ticket.title").name.should == :title
64
+ grid.find_by_path("ticket.description").name.should == :description
65
+ grid.find_by_path("ticket.status").name.should == :status
66
+ grid.find_by_path("ticket.is_finished?").name.should == :is_finished?
67
+ grid.find_by_path("ticket.actions").name.should == :actions
68
+ grid.find_by_path("ticket.project_id").name.should == :project_id
69
+
70
+ grid.find_by_path("ticket.project").name.should == :project
71
+ grid.find_by_path("ticket.project.title").name.should == :title
72
+ grid.find_by_path("ticket.project.class").name.should == :class
73
+ grid.find_by_path("ticket.project.actions").name.should == :actions
74
+ grid.find_by_path("ticket.project.id").name.should == :id
75
+
76
+ grid.find_by_path("ticket.project.foo").name.should == :foo
77
+ grid.find_by_path("ticket.project.foo.title").name.should == :title
78
+ grid.find_by_path("ticket.project.foo.foo").name.should == :foo
79
+ grid.find_by_path("ticket.project.foo.bar").name.should == :bar
80
+ grid.find_by_path("ticket.project.foo.id").name.should == :id
81
+
82
+ end
83
+
84
+ it "should have a fancygrid instance as root" do
85
+
86
+ grid = build_testgrid
87
+ grid.find_by_path("ticket").root.should be(grid)
88
+ grid.find_by_path("ticket.title").root.should be(grid)
89
+ grid.find_by_path("ticket.description").root.should be(grid)
90
+ grid.find_by_path("ticket.status").root.should be(grid)
91
+ grid.find_by_path("ticket.is_finished?").root.should be(grid)
92
+ grid.find_by_path("ticket.actions").root.should be(grid)
93
+ grid.find_by_path("ticket.project_id").root.should be(grid)
94
+
95
+ grid.find_by_path("ticket.project").root.should be(grid)
96
+ grid.find_by_path("ticket.project.title").root.should be(grid)
97
+ grid.find_by_path("ticket.project.class").root.should be(grid)
98
+ grid.find_by_path("ticket.project.actions").root.should be(grid)
99
+ grid.find_by_path("ticket.project.id").root.should be(grid)
100
+
101
+ grid.find_by_path("ticket.project.foo").root.should be(grid)
102
+ grid.find_by_path("ticket.project.foo.title").root.should be(grid)
103
+ grid.find_by_path("ticket.project.foo.foo").root.should be(grid)
104
+ grid.find_by_path("ticket.project.foo.bar").root.should be(grid)
105
+ grid.find_by_path("ticket.project.foo.id").root.should be(grid)
106
+
107
+ end
108
+
109
+ it "should be a leaf if has no children" do
110
+
111
+ grid = build_testgrid
112
+ grid.find_by_path("ticket").is_leaf?.should be(false)
113
+ grid.find_by_path("ticket.title").is_leaf?.should be(true)
114
+ grid.find_by_path("ticket.description").is_leaf?.should be(true)
115
+ grid.find_by_path("ticket.status").is_leaf?.should be(true)
116
+ grid.find_by_path("ticket.is_finished?").is_leaf?.should be(true)
117
+ grid.find_by_path("ticket.actions").is_leaf?.should be(true)
118
+ grid.find_by_path("ticket.project_id").is_leaf?.should be(true)
119
+
120
+ grid.find_by_path("ticket.project").is_leaf?.should be(false)
121
+ grid.find_by_path("ticket.project.title").is_leaf?.should be(true)
122
+ grid.find_by_path("ticket.project.class").is_leaf?.should be(true)
123
+ grid.find_by_path("ticket.project.actions").is_leaf?.should be(true)
124
+ grid.find_by_path("ticket.project.id").is_leaf?.should be(true)
125
+
126
+ grid.find_by_path("ticket.project.foo").is_leaf?.should be(false)
127
+ grid.find_by_path("ticket.project.foo.title").is_leaf?.should be(true)
128
+ grid.find_by_path("ticket.project.foo.foo").is_leaf?.should be(true)
129
+ grid.find_by_path("ticket.project.foo.bar").is_leaf?.should be(true)
130
+ grid.find_by_path("ticket.project.foo.id").is_leaf?.should be(true)
131
+
132
+ end
133
+
134
+ it "should have a tag name if is a leaf" do
135
+
136
+ grid = build_testgrid
137
+ grid.find_by_path("ticket").tag_name.should == nil
138
+ grid.find_by_path("ticket.title").tag_name.should == "tickets[title]"
139
+ grid.find_by_path("ticket.description").tag_name.should == "tickets[description]"
140
+ grid.find_by_path("ticket.status").tag_name.should == "tickets[status]"
141
+ grid.find_by_path("ticket.is_finished?").tag_name.should == "tickets[is_finished?]"
142
+ grid.find_by_path("ticket.actions").tag_name.should == "tickets[actions]"
143
+ grid.find_by_path("ticket.project_id").tag_name.should == "tickets[project_id]"
144
+
145
+ grid.find_by_path("ticket.project").tag_name.should == nil
146
+ grid.find_by_path("ticket.project.title").tag_name.should == "projects[title]"
147
+ grid.find_by_path("ticket.project.class").tag_name.should == "projects[class]"
148
+ grid.find_by_path("ticket.project.actions").tag_name.should == "projects[actions]"
149
+ grid.find_by_path("ticket.project.id").tag_name.should == "projects[id]"
150
+
151
+ grid.find_by_path("ticket.project.foo").tag_name.should == nil
152
+ grid.find_by_path("ticket.project.foo.title").tag_name.should == "projects[title]"
153
+ grid.find_by_path("ticket.project.foo.foo").tag_name.should == "projects[foo]"
154
+ grid.find_by_path("ticket.project.foo.bar").tag_name.should == "projects[bar]"
155
+ grid.find_by_path("ticket.project.foo.id").tag_name.should == "projects[id]"
156
+
157
+ end
158
+
159
+ it "should have a select name if is a leaf and is selectable" do
160
+
161
+ grid = build_testgrid
162
+ grid.find_by_path("ticket").select_name.should == nil
163
+ grid.find_by_path("ticket.title").select_name.should == "tickets.title"
164
+ grid.find_by_path("ticket.description").select_name.should == "tickets.description"
165
+ grid.find_by_path("ticket.status").select_name.should == "tickets.status"
166
+ grid.find_by_path("ticket.is_finished?").select_name.should == nil
167
+ grid.find_by_path("ticket.actions").select_name.should == nil
168
+ grid.find_by_path("ticket.project_id").select_name.should == "tickets.project_id"
169
+
170
+ grid.find_by_path("ticket.project").select_name.should == nil
171
+ grid.find_by_path("ticket.project.title").select_name.should == "projects.title"
172
+ grid.find_by_path("ticket.project.class").select_name.should == nil
173
+ grid.find_by_path("ticket.project.actions").select_name.should == nil
174
+ grid.find_by_path("ticket.project.id").select_name.should == "projects.id"
175
+
176
+ grid.find_by_path("ticket.project.foo").select_name.should == nil
177
+ grid.find_by_path("ticket.project.foo.title").select_name.should == "projects.title"
178
+ grid.find_by_path("ticket.project.foo.foo").select_name.should == nil
179
+ grid.find_by_path("ticket.project.foo.bar").select_name.should == nil
180
+ grid.find_by_path("ticket.project.foo.id").select_name.should == "projects.id"
181
+
182
+ end
183
+
184
+ it "have a css class if is a leaf" do
185
+
186
+ grid = build_testgrid
187
+ grid.find_by_path("ticket").css_class.should == nil
188
+ grid.find_by_path("ticket.title").css_class.should == "tickets title fg-orderable"
189
+ grid.find_by_path("ticket.description").css_class.should == "tickets description fg-orderable"
190
+ grid.find_by_path("ticket.status").css_class.should == "tickets status fg-orderable"
191
+ grid.find_by_path("ticket.is_finished?").css_class.should == "tickets is_finished?"
192
+ grid.find_by_path("ticket.actions").css_class.should == "tickets actions"
193
+ grid.find_by_path("ticket.project_id").css_class.should == "tickets project_id fg-orderable"
194
+
195
+ grid.find_by_path("ticket.project").css_class.should == nil
196
+ grid.find_by_path("ticket.project.title").css_class.should == "projects title fg-orderable"
197
+ grid.find_by_path("ticket.project.class").css_class.should == "projects class"
198
+ grid.find_by_path("ticket.project.actions").css_class.should == "projects actions"
199
+ grid.find_by_path("ticket.project.id").css_class.should == "projects id fg-orderable"
200
+
201
+ grid.find_by_path("ticket.project.foo").css_class.should == nil
202
+ grid.find_by_path("ticket.project.foo.title").css_class.should == "projects title fg-orderable"
203
+ grid.find_by_path("ticket.project.foo.foo").css_class.should == "projects foo"
204
+ grid.find_by_path("ticket.project.foo.bar").css_class.should == "projects bar"
205
+ grid.find_by_path("ticket.project.foo.id").css_class.should == "projects id fg-orderable"
206
+
207
+ end
208
+
209
+ it "should have an i18n path if is a leaf" do
210
+
211
+ grid = build_testgrid
212
+ grid.find_by_path("ticket").i18n_path.should == nil
213
+ grid.find_by_path("ticket.title").i18n_path.should_not be nil
214
+ grid.find_by_path("ticket.description").i18n_path.should_not be nil
215
+ grid.find_by_path("ticket.status").i18n_path.should_not be nil
216
+ grid.find_by_path("ticket.is_finished?").i18n_path.should_not be nil
217
+ grid.find_by_path("ticket.actions").i18n_path.should_not be nil
218
+ grid.find_by_path("ticket.project_id").i18n_path.should_not be nil
219
+
220
+ grid.find_by_path("ticket.project").i18n_path.should == nil
221
+ grid.find_by_path("ticket.project.title").i18n_path.should_not be nil
222
+ grid.find_by_path("ticket.project.class").i18n_path.should_not be nil
223
+ grid.find_by_path("ticket.project.actions").i18n_path.should_not be nil
224
+ grid.find_by_path("ticket.project.id").i18n_path.should_not be nil
225
+
226
+ grid.find_by_path("ticket.project.foo").i18n_path.should == nil
227
+ grid.find_by_path("ticket.project.foo.title").i18n_path.should_not be nil
228
+ grid.find_by_path("ticket.project.foo.foo").i18n_path.should_not be nil
229
+ grid.find_by_path("ticket.project.foo.bar").i18n_path.should_not be nil
230
+ grid.find_by_path("ticket.project.foo.id").i18n_path.should_not be nil
231
+
232
+ end
233
+
234
+ it "should have a trace path" do
235
+
236
+ grid = build_testgrid
237
+ grid.find_by_path("ticket").trace_path.should == "ticket"
238
+ grid.find_by_path("ticket.title").trace_path.should == "ticket.title"
239
+ grid.find_by_path("ticket.description").trace_path.should == "ticket.description"
240
+ grid.find_by_path("ticket.status").trace_path.should == "ticket.status"
241
+ grid.find_by_path("ticket.is_finished?").trace_path.should == "ticket.is_finished?"
242
+ grid.find_by_path("ticket.actions").trace_path.should == "ticket.actions"
243
+ grid.find_by_path("ticket.project_id").trace_path.should == "ticket.project_id"
244
+
245
+ grid.find_by_path("ticket.project").trace_path.should == "ticket.project"
246
+ grid.find_by_path("ticket.project.title").trace_path.should == "ticket.project.title"
247
+ grid.find_by_path("ticket.project.class").trace_path.should == "ticket.project.class"
248
+ grid.find_by_path("ticket.project.actions").trace_path.should == "ticket.project.actions"
249
+ grid.find_by_path("ticket.project.id").trace_path.should == "ticket.project.id"
250
+
251
+ grid.find_by_path("ticket.project.foo").trace_path.should == "ticket.project.foo"
252
+ grid.find_by_path("ticket.project.foo.title").trace_path.should == "ticket.project.foo.title"
253
+ grid.find_by_path("ticket.project.foo.foo").trace_path.should == "ticket.project.foo.foo"
254
+ grid.find_by_path("ticket.project.foo.bar").trace_path.should == "ticket.project.foo.bar"
255
+ grid.find_by_path("ticket.project.foo.id").trace_path.should == "ticket.project.foo.id"
256
+
257
+ end
258
+
259
+
260
+ it "should get attributes from model" do
261
+ ticket = Ticket.new({
262
+ :title => "ticket title",
263
+ :description => "ticket description",
264
+ :status => "ticket status",
265
+ :project => Project.new({ :title => "project title" })
266
+ })
267
+
268
+ grid = build_testgrid
269
+ grid.find_by_path("ticket.title").value_from(ticket).should == "ticket title"
270
+ grid.find_by_path("ticket.description").value_from(ticket).should == "ticket description"
271
+ grid.find_by_path("ticket.status").value_from(ticket).should == "ticket status"
272
+ grid.find_by_path("ticket.project.title").value_from(ticket).should == "project title"
273
+
274
+ end
275
+
276
+ it "should pass the visible option to node" do
277
+
278
+ grid = Fancygrid::Grid.new(:ticket)
279
+ grid.column(:title, :visible => true )
280
+ grid.find_by_path("ticket.title").visible.should be true
281
+
282
+ grid = Fancygrid::Grid.new(:ticket)
283
+ grid.column(:title, :visible => false )
284
+ grid.find_by_path("ticket.title").visible.should be false
285
+ end
286
+
287
+ it "should pass the formatable option to node" do
288
+
289
+ grid = Fancygrid::Grid.new(:ticket)
290
+ grid.column(:title, :formatable => true )
291
+ grid.find_by_path("ticket.title").formatable.should be true
292
+
293
+ grid = Fancygrid::Grid.new(:ticket)
294
+ grid.column(:title, :formatable => false )
295
+ grid.find_by_path("ticket.title").formatable.should be false
296
+ end
297
+
298
+ it "should pass the searchable option to node" do
299
+
300
+ grid = Fancygrid::Grid.new(:ticket)
301
+ grid.column(:title, :searchable => true )
302
+ grid.find_by_path("ticket.title").searchable.should be true
303
+
304
+ grid = Fancygrid::Grid.new(:ticket)
305
+ grid.column(:title, :searchable => false )
306
+ grid.find_by_path("ticket.title").searchable.should be false
307
+ end
308
+
309
+ it "should pass the human name option to node" do
310
+
311
+ grid = Fancygrid::Grid.new(:ticket)
312
+ grid.column(:title, :human_name => "custom human name" )
313
+ grid.find_by_path("ticket.title").human_name.should == "custom human name"
314
+
315
+ end
316
+
317
+ it "should pass the proc option to node" do
318
+
319
+ ticket = Ticket.new(:title => "ticket title")
320
+
321
+ grid = Fancygrid::Grid.new(:ticket)
322
+ grid.column(:title, :proc => Proc.new { |t| t.title } )
323
+ grid.find_by_path("ticket.title").proc_block.call(ticket).should == "ticket title"
324
+ grid.find_by_path("ticket.title").value_from(ticket).should == "ticket title"
325
+ end
326
+ end