bone_tree 0.5.6 → 0.9.2

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 (57) hide show
  1. data/.gitignore +26 -3
  2. data/Gemfile +5 -12
  3. data/Rakefile +7 -9
  4. data/bone_tree.gemspec +30 -14
  5. data/config.rb +8 -0
  6. data/lib/assets/javascripts/bone_tree.js +277 -981
  7. data/lib/assets/stylesheets/bone_tree.css +108 -0
  8. data/lib/bone_tree/rails.rb +5 -0
  9. data/lib/bone_tree/sprockets.rb +3 -0
  10. data/lib/{version.rb → bone_tree/version.rb} +1 -1
  11. data/lib/bone_tree.rb +11 -6
  12. data/source/index.html.haml +10 -382
  13. data/source/javascripts/{_backbone.js → backbone.js} +282 -142
  14. data/source/javascripts/bone_tree/models/directory.js.coffee +109 -0
  15. data/source/javascripts/bone_tree/models/file.js.coffee +12 -0
  16. data/source/javascripts/bone_tree/models/node.js.coffee +24 -0
  17. data/source/javascripts/bone_tree/models/settings.js.coffee +5 -0
  18. data/source/javascripts/bone_tree/{_namespace.js.coffee → namespace.js.coffee} +1 -1
  19. data/source/javascripts/bone_tree/views/directory.js.coffee +56 -0
  20. data/source/javascripts/bone_tree/views/file.js.coffee +25 -0
  21. data/source/javascripts/bone_tree/views/tree.js.coffee +87 -0
  22. data/source/javascripts/bone_tree.js.coffee +2 -1
  23. data/source/stylesheets/bone_tree.css.sass +0 -38
  24. data/spec/javascripts/directory_spec.coffee +26 -0
  25. data/spec/javascripts/helpers/spec_helper.coffee +3 -4
  26. data/spec/javascripts/sorting_spec.coffee +12 -0
  27. data/spec/javascripts/support/jasmine.yml +6 -4
  28. metadata +143 -36
  29. data/Gemfile.lock +0 -190
  30. data/docs/index.html +0 -222
  31. data/docs/resources/base.css +0 -70
  32. data/docs/resources/index.css +0 -20
  33. data/docs/resources/module.css +0 -24
  34. data/docs/source/javascripts/bone_tree/_namespace.js.html +0 -45
  35. data/docs/source/javascripts/bone_tree/models/_directory.js.html +0 -126
  36. data/docs/source/javascripts/bone_tree/models/_file.js.html +0 -112
  37. data/docs/source/javascripts/bone_tree/models/_nodes.js.html +0 -174
  38. data/docs/source/javascripts/bone_tree/models/_settings.js.html +0 -75
  39. data/docs/source/javascripts/bone_tree/views/_directory.js.html +0 -94
  40. data/docs/source/javascripts/bone_tree/views/_file.js.html +0 -82
  41. data/docs/source/javascripts/bone_tree/views/_menu.js.html +0 -110
  42. data/docs/source/javascripts/bone_tree/views/_tree.js.html +0 -432
  43. data/source/javascripts/_jquery.min.js +0 -5
  44. data/source/javascripts/_underscore.js +0 -999
  45. data/source/javascripts/bone_tree/models/_directory.js.coffee +0 -63
  46. data/source/javascripts/bone_tree/models/_file.js.coffee +0 -55
  47. data/source/javascripts/bone_tree/models/_nodes.js.coffee +0 -117
  48. data/source/javascripts/bone_tree/models/_settings.js.coffee +0 -25
  49. data/source/javascripts/bone_tree/views/_directory.js.coffee +0 -73
  50. data/source/javascripts/bone_tree/views/_file.js.coffee +0 -51
  51. data/source/javascripts/bone_tree/views/_menu.js.coffee +0 -97
  52. data/source/javascripts/bone_tree/views/_tree.js.coffee +0 -498
  53. data/spec/javascripts/directory_view_spec.coffee +0 -91
  54. data/spec/javascripts/file_view_spec.coffee +0 -70
  55. data/spec/javascripts/menu_view_spec.coffee +0 -42
  56. data/spec/javascripts/nodes_spec.coffee +0 -37
  57. data/spec/javascripts/tree_view_spec.coffee +0 -39
@@ -1,498 +0,0 @@
1
- #= require ../_namespace
2
-
3
- #= require_tree ../models
4
- #= require_tree ../views
5
-
6
- BoneTree.namespace "BoneTree.Views", (Views) ->
7
- {Models} = BoneTree
8
-
9
- class Views.Tree extends Backbone.View
10
- ###
11
- Public: The base tree object. Events from other objects are proxied to the tree
12
- so API consumers only need to know about this top level object.
13
-
14
- ###
15
- className: 'tree'
16
-
17
- events:
18
- 'contextmenu .file': '_contextMenu'
19
- 'contextmenu .directory': '_contextMenu'
20
- 'click .directory': '_openDirectory'
21
- 'click .file': '_openFile'
22
-
23
- initialize: ->
24
- ###
25
- Public: Initialize a new filetree widget
26
-
27
- * options - An Object of global configuration options for the file tree.
28
- * confirmDeletes - A Boolean. If true, the tree will prompt the user, making
29
- sure they want to delete the file (default: false).
30
- * showExtensions - A Boolean. If true, files display their extensions. Internally,
31
- extensions are always kept track of but by default they are
32
- hidden (default: false).
33
-
34
- ###
35
- $(document).click @_closeMenu
36
-
37
- @_currentFileData = null
38
-
39
- settingsConfig = _.extend({}, @options, {treeView: @})
40
-
41
- @settings = new Models.Settings(settingsConfig)
42
-
43
- @menuView = new Views.Menu
44
- settings: @settings
45
- @menuView.render().$el.appendTo $('body')
46
-
47
- @root = new Models.Node
48
-
49
- @root.collection.bind 'add', @render
50
-
51
- @root.collection.bind 'remove', (model, collection) =>
52
- @$("[data-cid='#{model.cid}']").remove()
53
-
54
- @render()
55
-
56
- @trigger 'remove', model
57
-
58
- file: (filePath, fileData) =>
59
- filePath = filePath.replace('/', '') if filePath[0] is '/'
60
-
61
- if fileData?
62
- @_currentFileData = _.extend(fileData, path: filePath)
63
-
64
- @_currentFileData.autoOpen = true unless @_currentFileData.autoOpen?
65
- @_currentFileData.hidden = false unless @_currentFileData.hidden?
66
- else
67
- return @_getFile(filePath)
68
-
69
- [dirs..., fileName] = filePath.split '/'
70
-
71
- if file = @_getFile(filePath)
72
- file.set(@_currentFileData)
73
- else
74
- @addToTree(@root, dirs, fileName)
75
-
76
- addFromJSON: (data, currentPath="") =>
77
- ###
78
- Public: Creates a file tree from a JSON representation. Expects the
79
- JSON object to have a `name` property at each level, specifying
80
- the name of the file or directory, and a files array if the
81
- current node has child directories or files.
82
-
83
- * data - An Object that represents hierarchical file data.
84
-
85
- * currentPath - A String representing the current location in the tree.
86
- Defaults to the file tree root. (default: "")
87
-
88
- Examples
89
-
90
- data = {
91
- name: "My Project"
92
- files: [
93
- { name: "Empty Folder" }
94
- { name: "SomeFile.coffee" }
95
- { name: "AnotherFile.coffee" }
96
- {
97
- name: "Folder with Files inside"
98
- files: [
99
- { name: "NestedFile.coffee" }
100
- ]
101
- }
102
- ]
103
- }
104
-
105
- tree.addFromJSON(data)
106
- # => <Tree>
107
-
108
- Returns the Tree view object.
109
- ###
110
- name = ""
111
-
112
- if data.name?
113
- name = data.name + '/'
114
- delete data.name
115
-
116
- if data.extension?
117
- name = name.replace('/', '.' + data.extension)
118
- delete data.extension
119
-
120
- currentPath += name
121
-
122
- if data.files?
123
- for file in data.files
124
- @addFromJSON(file, currentPath)
125
- else
126
- @file(currentPath, data)
127
-
128
- return @
129
-
130
- addToTree: (currentDirectory, remainingDirectories, fileName) =>
131
- ###
132
- Internal: Recursive method that traverses nodes, creating
133
- Files and Directories.
134
-
135
- * currentDirectory - A Node object representing which directory we are
136
- adding the current Directory or File to.
137
- * remainingDirectories - A '/' separated String representing the remaining
138
- directories to add.
139
- * fileName - The String name of the file to be added. This can
140
- include the extension name separated by a '.'.
141
-
142
- Examples
143
-
144
- tree.addToTree(@root, '/source/subdirectory/', 'main.coffee')
145
- # => <File>
146
-
147
- Returns the File object if it was created and null if no file was given.
148
- ###
149
- if remainingDirectories.length
150
- nextDirectoryName = remainingDirectories.shift()
151
-
152
- if matchingDirectory = Models.Directory.find(currentDirectory, nextDirectoryName)
153
- matchingDirectory.set
154
- open: true
155
-
156
- @addToTree(matchingDirectory, remainingDirectories, fileName)
157
- else
158
- newNode = new Models.Directory {name: nextDirectoryName, open: true}
159
-
160
- newDirectory = currentDirectory.collection.add newNode
161
- @addToTree(newNode, remainingDirectories, fileName)
162
- else
163
- return null if fileName is ""
164
-
165
- file = Models.File.createFromFileName(fileName, @_currentFileData)
166
- @_currentFileData = null
167
-
168
- currentDirectory.collection.add file
169
-
170
- if file.get('autoOpen')
171
- @trigger 'openFile', file
172
-
173
- return file
174
-
175
- findOrCreateView: (node) =>
176
- ###
177
- Internal: Look up existing view in the view cache or Create a new view
178
- of the correct type (either File or Directory).
179
-
180
- * node - A Node object. Either a File object or a Directory object.
181
- This is the model that the view will be associated with.
182
-
183
- Examples
184
-
185
- file = new BoneTree.Models.File
186
-
187
- # This will create a new view since we just created the File
188
- tree.findOrCreateView(file)
189
- # => <FileView>
190
-
191
- Returns the view corresponding to the model passed in.
192
- ###
193
- type = node.constantize()
194
- viewCache = @settings.get 'viewCache'
195
-
196
- unless view = viewCache[node.cid]
197
- view = viewCache[node.cid] = new Views[type]
198
- model: node
199
- settings: @settings
200
-
201
- return view
202
-
203
- # TODO this seems unneeded and backward. I shouldn't need to look up
204
- # a model from the view cache. I should be able to just find it in
205
- # the collection.
206
- getModelByCid: (cid) =>
207
- viewCache = @settings.get 'viewCache'
208
-
209
- for modelCid, view of viewCache
210
- return view.model if modelCid is cid
211
-
212
- closeDirectories: =>
213
- ###
214
- Public: Close all the directories in the file tree.
215
-
216
- Examples
217
-
218
- tree.closeDirectories()
219
- # => <Tree>
220
-
221
- Returns the Tree view object.
222
- ###
223
- directories = _.filter(@flatten(), (node) ->
224
- node.get('nodeType') is 'directory'
225
- )
226
-
227
- _.invoke(directories, 'set', {open: false})
228
-
229
- return @
230
-
231
- _closeMenu: (e) =>
232
- ###
233
- Internal: Close the context menu. This is called every click on
234
- the document and closes the menu unless you are clicking
235
- within it. This shouldn't be called directly, it is called
236
- automatically by Backbone from user interactions.
237
-
238
- Returns the Menu view object.
239
- ###
240
- @menuView.$el.hide() unless $(e.currentTarget).is('.menu')
241
-
242
- return @menuView
243
-
244
- _contextMenu: (e) =>
245
- ###
246
- Internal: Open the context menu. This prevents the default browser
247
- context menu event. This shouldn't be called directly, it is
248
- called automatically by Backbone from user interations.
249
-
250
- Returns the Menu view object.
251
- ###
252
- e.preventDefault()
253
-
254
- model = @getModelFromClick(e)
255
-
256
- @menuView.model = model
257
-
258
- @menuView.$el.css(
259
- left: e.pageX
260
- top: e.pageY
261
- ).show()
262
-
263
- return @menuView
264
-
265
- filterNodes: (nodeType, nodeName) =>
266
- ###
267
- Internal: Returns file tree nodes that match the nodeType and nodeName.
268
-
269
- * nodeType - A String that represents the nodeType to match. Choices are
270
- 'file' or 'directory'.
271
- * nodeName - A String that represents the name of the node to match.
272
-
273
- Examples
274
-
275
- # Add some files to the tree
276
- tree.file('/source/main.coffee')
277
- tree.file('/source/player.coffee')
278
-
279
- # returns an array containing the File 'main.coffee'
280
- tree.filterNodes('file', 'main')
281
- # => [<File>]
282
-
283
- Returns an Array of nodes that match the filter criteria.
284
- ###
285
- results = _.filter @flatten(), (node) =>
286
- node.get('nodeType') is nodeType and node.get('name') is nodeName
287
-
288
- return results
289
-
290
- flatten: (currentNode=@root, results=[]) =>
291
- ###
292
- Internal: Returns a one dimensional ordered array representing the
293
- Directory and File nodes in the tree.
294
-
295
- * currentNode - The node to start at when flattening
296
- * nodeName - A String that represents the name of the node to match.
297
-
298
- Examples
299
-
300
- # Add some files to the tree
301
- tree.file('/source/main.coffee', {aFile: true})
302
- tree.file('/source/player.coffee', {playerData: {x: 50, y: 30}})
303
-
304
- # returns an array containing the File 'main.coffee'
305
- tree.filterNodes('file', 'main')
306
- # => [<File>]
307
-
308
- Returns an Array of nodes that match the filter criteria.
309
- ###
310
- currentNode.collection.each (node) =>
311
- results.push node
312
-
313
- @flatten(node, results) if node.collection.length
314
-
315
- return results
316
-
317
- getDirectory: (directoryName) =>
318
- ###
319
- Public: Returns an array of directories matching the given directoryName.
320
-
321
- * directoryName - A String naming the directory to match.
322
-
323
- Examples
324
-
325
- # Add some files to the tree
326
- tree.file('/source/main.coffee', {size: 4039})
327
- tree.file('/source/player.coffee', {size: 399})
328
- tree.file('/directory2/file.coffee', {size: 23})
329
-
330
- # returns an array containing the Directory 'source'
331
- tree.getDirectory('source')
332
- # => [<Directory>]
333
-
334
- Returns an Array of Directory nodes that match directoryName.
335
- ###
336
- @filterNodes('directory', directoryName)
337
-
338
- _getFile: (filePath) =>
339
- ###
340
- Internal: Returns a file at the specified location.
341
-
342
- * fileName - A String describing the file path.
343
-
344
- Examples
345
-
346
- # Add some files to the tree
347
- tree.file('/source/main.coffee', {size: 30459})
348
- tree.file('/source/player.coffee', {size: 943})
349
- tree.file('/directory2/main.coffee', {size: 4945})
350
-
351
- # returns an array containing both the files named main.
352
- tree._getFile('source/main.coffee')
353
- # => <File>
354
-
355
- Returns a File at the given location.
356
- ###
357
-
358
- filePath = filePath.replace('/', '') if filePath[0] is '/'
359
-
360
- nodes = @flatten()
361
-
362
- filtered = _.filter(nodes, (node) ->
363
- return node.get('nodeType') is 'file' and node.get('path') is filePath
364
- )
365
-
366
- return filtered[0]
367
-
368
- files: (directoryName) =>
369
- ###
370
- Public: Returns an array of files contained within the directory
371
- matching directoryName.
372
-
373
- * directoryName - A String naming the directory to look inside.
374
-
375
- Examples
376
-
377
- # Add some files to the tree
378
- tree.file('/source/main.coffee', {main: true})
379
- tree.file('/source/player.coffee', {active: true})
380
- tree.file('/directory2/main.coffee', {active: true})
381
-
382
- # returns an array containing the files 'player.coffee' and 'main.coffee'
383
- tree.files('source')
384
- # => [<File>, <File>]
385
-
386
- Returns an Array of File nodes that are contained in the
387
- Directory matching directoryName.
388
- ###
389
-
390
- # return all files if no directory is provided
391
- unless directoryName?
392
- return _.filter(@flatten(), (node) ->
393
- return node.get('nodeType') is 'file'
394
- )
395
-
396
- directory = @getDirectory(directoryName)[0]
397
-
398
- # short circuit if directory name isn't in the tree
399
- # Otherwise flatten will return all the files in
400
- # the filetree
401
- return [] unless directory
402
-
403
- nodesInDirectory = @flatten(directory)
404
-
405
- return _.filter nodesInDirectory, (node) ->
406
- node.get('nodeType') is 'file'
407
-
408
- toAscii: (collection, indentation=0, output="\n") =>
409
- ###
410
- Internal: A String representation of the filetree.
411
-
412
- * collection - A NodeCollection object describing which folder to start at.
413
- * indentation - A Number describing how many spaces to indent the next filetree element (default: 0).
414
- * output - A String representing the current filetree output (default: "\n").
415
-
416
- Examples
417
-
418
- # Add some files to the tree
419
- tree.file('/source/main.coffee', {main: true})
420
- tree.file('/source/player.coffee', {active: true})
421
- tree.file('/directory2/main.coffee', {active: false})
422
-
423
- tree.toAscii()
424
- # => "
425
- -directory2
426
- -main.coffee
427
- -source
428
- -main.coffee
429
- -player.coffee
430
- "
431
-
432
- Returns a String representation of the sorted nodes of the file tree.
433
- ###
434
- rootCollection = collection || @root.collection
435
-
436
- spaces = ""
437
-
438
- for n in [0..indentation]
439
- spaces += " "
440
-
441
- rootCollection.each (nodes) =>
442
- typeChar = if nodes.get('type') is 'directory' then '+' else '-'
443
-
444
- output += (spaces + typeChar + nodes.nameWithExtension() + '\n')
445
-
446
- output = @toAscii(nodes.collection, indentation + 1, output)
447
-
448
- return output
449
-
450
- getModelFromClick: (e) =>
451
- ###
452
- Internal: Look up a model based on the cid of the clicked view element.
453
-
454
- Returns the Node corresponding to the view element that the user clicked on.
455
- ###
456
- e.stopPropagation()
457
- @menuView.$el.hide()
458
-
459
- cid = $(e.currentTarget).data('cid')
460
-
461
- return @getModelByCid(cid)
462
-
463
- _openDirectory: (e) =>
464
- ###
465
- Internal: Toggle the directory icon and display the contents of the clicked Directory.
466
-
467
- ###
468
- model = @getModelFromClick(e)
469
-
470
- model.toggleOpen()
471
-
472
- _openFile: (e) =>
473
- ###
474
- Internal: Trigger the 'openFile' event, passing in the file corresponding
475
- to the view element that the user clicked.
476
-
477
- ###
478
- model = @getModelFromClick(e)
479
-
480
- # events are emitted by the filetree itself. This way API
481
- # consumers don't have to know anything about the internals.
482
- @trigger 'openFile', model
483
-
484
- render: =>
485
- ###
486
- Internal: Call render on each of the nodes underneath the root node.
487
- Also calls sort on each of the subcollections.
488
-
489
-
490
- ###
491
- @root.collection.sort().each (node) =>
492
- node.collection.sort()
493
- view = @findOrCreateView(node)
494
-
495
- @$el.append view.render().$el unless view.model.get('hidden')
496
-
497
- return @
498
-
@@ -1,91 +0,0 @@
1
- #= require bone_tree/_namespace
2
- #= require bone_tree/views/_directory
3
-
4
- describe 'BoneTree.Views.Directory', ->
5
- beforeEach ->
6
- setFixtures("<div id='test'></div>")
7
-
8
- treeView = new Backbone.View
9
- treeView.findView = (model) ->
10
- @view.model = model
11
-
12
- return @view
13
-
14
- treeView.settings = @settings
15
-
16
- @settings = new Backbone.Model
17
- treeView: treeView
18
-
19
- @model = new Backbone.Model
20
- name: "TestDir"
21
- open: false
22
-
23
- @model.collection = new Backbone.Collection
24
- @model.collection.comparator = (item) =>
25
- return item.get('name')
26
-
27
- @view = new BoneTree.Views.Directory
28
- model: @model
29
- settings: @settings
30
-
31
- $('#test').append @view.render().$el
32
-
33
- afterEach ->
34
- @view.remove()
35
- $('#test').empty()
36
-
37
- describe 'rendering', ->
38
- it 'should render the correct element', ->
39
- expect($('#test ul.directory')).toExist()
40
- expect($('#test ul.directory').length).toEqual(1)
41
-
42
- it 'should render the directory name as the DOM text', ->
43
- expect($('#test ul.directory').text()).toEqual(@model.get('name'))
44
-
45
- it 'should change the directory name in the DOM when the model name is updated', ->
46
- renameSpy = sinon.spy()
47
-
48
- @settings.get('treeView').bind 'rename', renameSpy
49
-
50
- @model.set
51
- name: "NewDir"
52
-
53
- expect(renameSpy).toHaveBeenCalledOnce()
54
- expect(renameSpy).toHaveBeenCalledWith(@model, @model.get('name'))
55
-
56
- it 'should toggle the open class based on the model state', ->
57
- #TODO this should be the case. Change it so that appendView doesn't automatically open the dir
58
- # expect($('#test ul.directory')).not.toHaveClass('open')
59
-
60
- @model.set
61
- open: false
62
-
63
- expect($('#test ul.directory')).not.toHaveClass('open')
64
-
65
- @model.set
66
- open: true
67
-
68
- expect($('#test ul.directory')).toHaveClass('open')
69
-
70
- #TODO mock findView properly so you can test this
71
- #it 'should render new directories to the DOM', ->
72
- # newDir = new Backbone.Model
73
- # name: 'newDir'
74
- # open: false
75
-
76
- # @model.collection.add newDir
77
-
78
- # expect($('#test ul.directory ul.directory').length).toEqual(1)
79
-
80
- #TODO tests around hiding children directories
81
-
82
- it 'should trigger a rename event on the tree when the directory name is changed', ->
83
- spy = sinon.spy()
84
-
85
- @settings.get('treeView').bind 'rename', spy
86
-
87
- @model.set
88
- name: 'dir2'
89
-
90
- expect(spy).toHaveBeenCalledOnce()
91
- expect(spy).toHaveBeenCalledWith(@model, @model.get('name'))
@@ -1,70 +0,0 @@
1
- #= require bone_tree/_namespace
2
- #= require bone_tree/views/_file
3
-
4
- describe "BoneTree.Views.File", ->
5
- beforeEach ->
6
- setFixtures("<div id='test'></div>")
7
-
8
- @settings = new Backbone.Model
9
- treeView: new Backbone.View
10
- showExtensions: true
11
-
12
- @model = new Backbone.Model
13
- name: "Testing"
14
- extension: "exe"
15
-
16
- @model.nameWithExtension = =>
17
- @model.get('name') + "." + @model.get('extension')
18
-
19
- @view = new BoneTree.Views.File
20
- model: @model
21
- settings: @settings
22
-
23
- $('#test').append @view.render().el
24
-
25
- afterEach ->
26
- $('#test').empty()
27
- @view.remove()
28
-
29
- describe 'rendering', ->
30
- it 'should render the correct element', ->
31
- expect($('#test li.file')).toExist()
32
- expect($('#test li.file').length).toEqual(1)
33
-
34
- it 'should have the extension as a class name', ->
35
- expect($('#test li.file')).toHaveClass('exe')
36
-
37
- it 'should have the filename as the text of the node', ->
38
- expect($('#test li.file').text()).toEqual('Testing.exe')
39
-
40
- it 'should exclude the extension if that option is set', ->
41
- @settings.set
42
- showExtensions: false
43
-
44
- @view.render()
45
-
46
- expect($('#test li.file').text()).toEqual('Testing')
47
-
48
- describe 'events', ->
49
- it 'should trigger a change event on the file tree when the name has changed', ->
50
- spy = sinon.spy()
51
-
52
- @settings.get('treeView').bind 'rename', spy
53
-
54
- @model.set
55
- name: 'new name'
56
-
57
- expect(spy).toHaveBeenCalledOnce()
58
- expect(spy).toHaveBeenCalledWith(@model, @model.nameWithExtension())
59
-
60
- it 'should trigger a change event on the file tree when the extension has changed', ->
61
- spy = sinon.spy()
62
-
63
- @settings.get('treeView').bind 'rename', spy
64
-
65
- @model.set
66
- extension: 'js'
67
-
68
- expect(spy).toHaveBeenCalledOnce()
69
- expect(spy).toHaveBeenCalledWith(@model, @model.nameWithExtension())
70
-
@@ -1,42 +0,0 @@
1
- #= require bone_tree/_namespace
2
- #= require bone_tree/views/_menu
3
-
4
- describe "BoneTree.Views.Menu", ->
5
- beforeEach ->
6
- setFixtures("<div id='test'></div>")
7
-
8
- @model = new Backbone.Model
9
-
10
- @settings = new Backbone.Model
11
- confirmDeletes: false
12
-
13
- @menu = new BoneTree.Views.Menu
14
- model: @model
15
- settings: @settings
16
-
17
- $('#test').append @menu.render().el
18
-
19
- afterEach ->
20
- @menu.remove()
21
- $('#test').empty()
22
-
23
- describe "rendering", ->
24
- it "should render the correct DOM elements", ->
25
- expect($('#test .filetree_context_menu')).toExist()
26
- expect($('#test .filetree_context_menu').length).toEqual(1)
27
-
28
- expect($('#test .filetree_context_menu li').length).toEqual(2)
29
- expect($('#test .filetree_context_menu li.rename')).toExist()
30
- expect($('#test .filetree_context_menu li.delete')).toExist()
31
-
32
- describe "interactions", ->
33
- it "should delete", ->
34
- spy = sinon.spy()
35
-
36
- @model.bind 'destroy', spy
37
-
38
- $('#test .delete').click()
39
-
40
- expect(spy).toHaveBeenCalled()
41
- expect($('#test .filetree_context_menu')).toBeHidden()
42
-