2012-05-09 06:20:33 +04:00
RootView = require ' root-view '
2012-06-20 04:03:45 +04:00
EditSession = require ' edit-session '
2012-01-05 23:13:55 +04:00
Buffer = require ' buffer '
2011-12-16 02:13:34 +04:00
Editor = require ' editor '
2012-01-28 00:42:33 +04:00
Range = require ' range '
2012-04-19 02:57:58 +04:00
Project = require ' project '
2011-12-16 02:13:34 +04:00
$ = require ' jquery '
2012-03-13 00:21:00 +04:00
{ $$ } = require ' space-pen '
2012-01-24 04:45:00 +04:00
_ = require ' underscore '
2011-12-17 02:42:38 +04:00
fs = require ' fs '
2011-12-16 02:13:34 +04:00
2012-06-05 20:47:45 +04:00
describe " Editor " , ->
2012-06-19 23:00:18 +04:00
[ rootView , project , buffer , editor , cachedLineHeight ] = [ ]
2012-05-10 19:27:04 +04:00
getLineHeight = ->
2012-05-16 23:47:59 +04:00
return cachedLineHeight if cachedLineHeight ?
2012-07-18 22:19:25 +04:00
editorForMeasurement = new Editor ( editSession: rootView . project . buildEditSessionForPath ( ' sample.js ' ) )
2012-05-10 19:27:04 +04:00
editorForMeasurement . attachToDom ( )
cachedLineHeight = editorForMeasurement . lineHeight
editorForMeasurement . remove ( )
cachedLineHeight
2011-12-16 02:13:34 +04:00
beforeEach ->
2012-05-16 21:35:50 +04:00
rootView = new RootView ( require . resolve ( ' fixtures/sample.js ' ) )
2012-06-28 22:57:52 +04:00
project = rootView . project
2012-07-03 05:46:33 +04:00
editor = rootView . getActiveEditor ( )
2012-07-04 22:27:30 +04:00
buffer = editor . getBuffer ( )
2012-04-19 02:57:58 +04:00
2012-05-10 21:40:16 +04:00
editor.attachToDom = ({ heightInLines } = {}) ->
2012-07-04 22:27:30 +04:00
heightInLines ? = this . getBuffer ( ) . getLineCount ( )
2012-05-10 19:27:04 +04:00
this . height ( getLineHeight ( ) * heightInLines )
$ ( ' # jasmine-content ' ) . append ( this )
2012-05-27 00:05:25 +04:00
editor.lineOverdraw = 2
2012-06-20 04:55:51 +04:00
rootView . project . setAutoIndent ( false )
2012-01-18 06:13:50 +04:00
editor . enableKeymap ( )
2012-03-19 19:04:39 +04:00
editor.isFocused = true
2011-12-16 02:13:34 +04:00
2012-06-06 00:23:34 +04:00
afterEach ->
2012-06-29 21:20:19 +04:00
rootView . remove ( )
2012-06-06 00:23:34 +04:00
2012-03-23 20:50:41 +04:00
describe " construction " , ->
2012-06-19 23:00:18 +04:00
it " throws an error if no editor session is given " , ->
expect ( -> new Editor ) . toThrow ( )
2012-03-23 20:50:41 +04:00
2012-04-13 21:39:16 +04:00
describe " .copy() " , ->
it " builds a new editor with the same edit sessions, cursor position, and scroll position as the receiver " , ->
2012-05-12 03:51:47 +04:00
rootView . attachToDom ( )
rootView . height ( 8 * editor . lineHeight )
rootView . width ( 50 * editor . charWidth )
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ' two-hundred.txt ' ) )
2012-06-27 17:53:32 +04:00
editor . setCursorScreenPosition ( [ 5 , 1 ] )
2012-05-16 23:47:59 +04:00
editor . scrollTop ( 1.5 * editor . lineHeight )
2012-05-12 03:51:47 +04:00
editor . scrollView . scrollLeft ( 44 )
2012-04-13 21:39:16 +04:00
2012-06-29 21:20:19 +04:00
# proves this test covers serialization and deserialization
2012-04-13 21:39:16 +04:00
spyOn ( editor , ' serialize ' ) . andCallThrough ( )
spyOn ( Editor , ' deserialize ' ) . andCallThrough ( )
newEditor = editor . copy ( )
expect ( editor . serialize ) . toHaveBeenCalled ( )
expect ( Editor . deserialize ) . toHaveBeenCalled ( )
2012-05-12 03:51:47 +04:00
2012-07-04 22:27:30 +04:00
expect ( newEditor . getBuffer ( ) ) . toBe editor . getBuffer ( )
2012-04-13 21:39:16 +04:00
expect ( newEditor . getCursorScreenPosition ( ) ) . toEqual editor . getCursorScreenPosition ( )
2012-06-27 17:53:32 +04:00
expect ( newEditor . editSessions ) . toEqual ( editor . editSessions )
expect ( newEditor . activeEditSession ) . toEqual ( editor . activeEditSession )
expect ( newEditor . getActiveEditSessionIndex ( ) ) . toEqual ( editor . getActiveEditSessionIndex ( ) )
2012-04-14 00:29:58 +04:00
2012-05-12 03:51:47 +04:00
newEditor . height ( editor . height ( ) )
newEditor . width ( editor . width ( ) )
rootView . remove ( )
newEditor . attachToDom ( )
2012-06-05 07:57:10 +04:00
expect ( newEditor . scrollTop ( ) ) . toBe editor . scrollTop ( )
2012-05-12 03:51:47 +04:00
expect ( newEditor . scrollView . scrollLeft ( ) ) . toBe 44
2012-06-13 01:59:55 +04:00
describe " when the editor is attached to the dom " , ->
it " calculates line height and char width and updates the pixel position of the cursor " , ->
expect ( editor . lineHeight ) . toBeNull ( )
expect ( editor . charWidth ) . toBeNull ( )
editor . setCursorScreenPosition ( row: 2 , column: 2 )
editor . attachToDom ( )
expect ( editor . lineHeight ) . not . toBeNull ( )
expect ( editor . charWidth ) . not . toBeNull ( )
expect ( editor . find ( ' .cursor ' ) . offset ( ) ) . toEqual pagePixelPositionForPoint ( editor , [ 2 , 2 ] )
it " is focused " , ->
editor . attachToDom ( )
expect ( editor ) . toMatchSelector " :has(:focus) "
describe " when the editor recieves focus " , ->
it " focuses the hidden input " , ->
editor . attachToDom ( )
editor . focus ( )
expect ( editor ) . not . toMatchSelector ' :focus '
expect ( editor . hiddenInput ) . toMatchSelector ' :focus '
describe " when the hidden input is focused / unfocused " , ->
it " assigns the isFocused flag on the editor and also adds/removes the .focused css class " , ->
editor . attachToDom ( )
editor.isFocused = false
editor . hiddenInput . focus ( )
expect ( editor . isFocused ) . toBeTruthy ( )
expect ( editor ) . toHaveClass ( ' focused ' )
editor . hiddenInput . focusout ( )
expect ( editor . isFocused ) . toBeFalsy ( )
expect ( editor ) . not . toHaveClass ( ' focused ' )
2012-07-26 21:37:32 +04:00
describe " when the activeEditSession ' s file is modified on disk " , ->
it " triggers an alert " , ->
path = " /tmp/atom-changed-file.txt "
fs . write ( path , " " )
editSession = project . buildEditSessionForPath ( path )
editor . edit ( editSession )
editor . insertText ( " now the buffer is modified " )
fileChangeHandler = jasmine . createSpy ( ' fileChange ' )
editSession . buffer . file . on ' contents-change ' , fileChangeHandler
spyOn ( $native , " alert " )
fs . write ( path , " a file change " )
waitsFor " file to trigger contents-change event " , ->
fileChangeHandler . callCount > 0
runs ->
expect ( $native . alert ) . toHaveBeenCalled ( )
2012-06-06 22:48:45 +04:00
describe " .remove() " , ->
it " removes subscriptions from all edit session buffers " , ->
2012-06-20 04:03:45 +04:00
previousEditSession = editor . activeEditSession
2012-07-18 22:19:25 +04:00
otherEditSession = rootView . project . buildEditSessionForPath ( rootView . project . resolve ( ' sample.txt ' ) )
2012-06-20 04:03:45 +04:00
expect ( previousEditSession . buffer . subscriptionCount ( ) ) . toBeGreaterThan 1
2012-06-06 22:48:45 +04:00
2012-06-20 04:03:45 +04:00
editor . edit ( otherEditSession )
expect ( otherEditSession . buffer . subscriptionCount ( ) ) . toBeGreaterThan 1
2012-06-06 22:48:45 +04:00
editor . remove ( )
2012-07-06 06:06:09 +04:00
expect ( previousEditSession . buffer . subscriptionCount ( ) ) . toBe 0
expect ( otherEditSession . buffer . subscriptionCount ( ) ) . toBe 0
2012-06-06 22:48:45 +04:00
2012-06-13 01:59:55 +04:00
describe " when ' close ' is triggered " , ->
it " closes active edit session and loads next edit session " , ->
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ) )
2012-06-29 00:54:07 +04:00
editSession = editor . activeEditSession
spyOn ( editSession , ' destroy ' ) . andCallThrough ( )
2012-06-30 02:08:16 +04:00
spyOn ( editor , " remove " ) . andCallThrough ( )
2012-06-13 01:59:55 +04:00
editor . trigger " close "
2012-06-29 00:54:07 +04:00
expect ( editSession . destroy ) . toHaveBeenCalled ( )
2012-06-13 01:59:55 +04:00
expect ( editor . remove ) . not . toHaveBeenCalled ( )
2012-07-04 22:27:30 +04:00
expect ( editor . getBuffer ( ) ) . toBe buffer
2012-06-13 01:59:55 +04:00
it " calls remove on the editor if there is one edit session and mini is false " , ->
2012-06-29 00:54:07 +04:00
editSession = editor . activeEditSession
2012-06-13 01:59:55 +04:00
expect ( editor . mini ) . toBeFalsy ( )
expect ( editor . editSessions . length ) . toBe 1
2012-06-30 02:08:16 +04:00
spyOn ( editor , ' remove ' ) . andCallThrough ( )
2012-06-13 01:59:55 +04:00
editor . trigger ' close '
2012-06-29 00:54:07 +04:00
spyOn ( editSession , ' destroy ' ) . andCallThrough ( )
2012-06-13 01:59:55 +04:00
expect ( editor . remove ) . toHaveBeenCalled ( )
2012-06-30 02:08:16 +04:00
miniEditor = new Editor ( mini: true )
spyOn ( miniEditor , ' remove ' ) . andCallThrough ( )
miniEditor . trigger ' close '
expect ( miniEditor . remove ) . not . toHaveBeenCalled ( )
2012-06-13 01:59:55 +04:00
describe " when buffer is modified " , ->
it " triggers alert and does not close session " , ->
2012-06-30 02:08:16 +04:00
spyOn ( editor , ' remove ' ) . andCallThrough ( )
2012-06-13 01:59:55 +04:00
spyOn ( $native , ' alert ' )
editor . insertText ( " I AM CHANGED! " )
editor . trigger " close "
expect ( editor . remove ) . not . toHaveBeenCalled ( )
expect ( $native . alert ) . toHaveBeenCalled ( )
2012-06-20 04:03:45 +04:00
describe " .edit(editSession) " , ->
otherEditSession = null
2012-06-07 03:00:02 +04:00
beforeEach ->
2012-07-18 22:19:25 +04:00
otherEditSession = rootView . project . buildEditSessionForPath ( )
2012-06-07 03:00:02 +04:00
2012-06-20 04:03:45 +04:00
describe " when the edit session wasn ' t previously assigned to this editor " , ->
it " adds edit session to editor " , ->
originalEditSessionCount = editor . editSessions . length
editor . edit ( otherEditSession )
expect ( editor . activeEditSession ) . toBe otherEditSession
expect ( editor . editSessions . length ) . toBe originalEditSessionCount + 1
2012-05-10 19:58:38 +04:00
2012-06-20 04:03:45 +04:00
describe " when the edit session was previously assigned to this editor " , ->
it " restores the previous edit session associated with the editor " , ->
2012-06-13 00:23:49 +04:00
previousEditSession = editor . activeEditSession
2012-05-10 19:58:38 +04:00
2012-06-20 04:03:45 +04:00
editor . edit ( otherEditSession )
2012-06-13 00:23:49 +04:00
expect ( editor . activeEditSession ) . not . toBe previousEditSession
2012-05-10 19:58:38 +04:00
2012-06-20 04:03:45 +04:00
editor . edit ( previousEditSession )
2012-06-13 00:23:49 +04:00
expect ( editor . activeEditSession ) . toBe previousEditSession
2012-05-10 19:58:38 +04:00
2012-06-20 04:03:45 +04:00
it " handles buffer manipulation correctly after switching to a new edit session " , ->
2012-06-07 03:00:02 +04:00
editor . attachToDom ( )
editor . insertText ( " abc \n " )
expect ( editor . lineElementForScreenRow ( 0 ) . text ( ) ) . toBe ' abc '
2012-06-20 04:03:45 +04:00
editor . edit ( otherEditSession )
2012-06-07 03:00:02 +04:00
expect ( editor . lineElementForScreenRow ( 0 ) . html ( ) ) . toBe ' '
editor . insertText ( " def \n " )
expect ( editor . lineElementForScreenRow ( 0 ) . text ( ) ) . toBe ' def '
2012-06-12 08:01:27 +04:00
describe " switching edit sessions " , ->
[ session0 , session1 , session2 ] = [ ]
2012-05-10 19:58:38 +04:00
2012-06-12 08:01:27 +04:00
beforeEach ->
session0 = editor . activeEditSession
2012-05-10 19:58:38 +04:00
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ' sample.txt ' ) )
2012-06-12 08:01:27 +04:00
session1 = editor . activeEditSession
2012-06-12 02:12:09 +04:00
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ' two-hundred.txt ' ) )
2012-06-12 08:01:27 +04:00
session2 = editor . activeEditSession
describe " .setActiveEditSessionIndex(index) " , ->
it " restores the buffer, cursors, selections, and scroll position of the edit session associated with the index " , ->
editor . attachToDom ( heightInLines: 10 )
2012-06-13 21:49:01 +04:00
editor . setSelectedBufferRange ( [ [ 40 , 0 ] , [ 43 , 1 ] ] )
2012-06-12 08:01:27 +04:00
expect ( editor . getSelection ( ) . getScreenRange ( ) ) . toEqual [ [ 40 , 0 ] , [ 43 , 1 ] ]
2012-06-13 00:23:49 +04:00
previousScrollHeight = editor . verticalScrollbar . prop ( ' scrollHeight ' )
2012-06-12 08:01:27 +04:00
editor . scrollTop ( 750 )
expect ( editor . scrollTop ( ) ) . toBe 750
editor . setActiveEditSessionIndex ( 0 )
2012-07-04 22:27:30 +04:00
expect ( editor . getBuffer ( ) ) . toBe session0 . buffer
2012-06-12 08:01:27 +04:00
editor . setActiveEditSessionIndex ( 2 )
2012-07-04 22:27:30 +04:00
expect ( editor . getBuffer ( ) ) . toBe session2 . buffer
2012-06-12 08:01:27 +04:00
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 43 , 1 ]
2012-06-13 00:23:49 +04:00
expect ( editor . verticalScrollbar . prop ( ' scrollHeight ' ) ) . toBe previousScrollHeight
2012-06-12 08:01:27 +04:00
expect ( editor . scrollTop ( ) ) . toBe 750
expect ( editor . getSelection ( ) . getScreenRange ( ) ) . toEqual [ [ 40 , 0 ] , [ 43 , 1 ] ]
expect ( editor . getSelectionView ( ) . find ( ' .selection ' ) ) . toExist ( )
editor . setActiveEditSessionIndex ( 0 )
editor . activeEditSession . selectToEndOfLine ( )
expect ( editor . getSelectionView ( ) . find ( ' .selection ' ) ) . toExist ( )
2012-07-26 21:37:32 +04:00
it " triggers alert if edit session ' s file changed on disk " , ->
path = " /tmp/atom-changed-file.txt "
fs . write ( path , " " )
editSession = project . buildEditSessionForPath ( path )
2012-07-27 22:11:45 +04:00
editor . edit editSession
2012-07-26 21:37:32 +04:00
editSession . insertText ( " a buffer change " )
2012-07-27 22:11:45 +04:00
bufferContentsChangeHandler = jasmine . createSpy ( ' fileChange ' )
editSession . on ' buffer-contents-change-on-disk ' , bufferContentsChangeHandler
2012-07-26 21:37:32 +04:00
spyOn ( $native , " alert " )
fs . write ( path , " a file change " )
waitsFor " file to trigger contents-change event " , ->
2012-07-27 22:11:45 +04:00
bufferContentsChangeHandler . callCount > 0
2012-07-26 21:37:32 +04:00
runs ->
expect ( $native . alert ) . toHaveBeenCalled ( )
2012-06-12 08:01:27 +04:00
describe " .loadNextEditSession() " , ->
it " loads the next editor state and wraps to beginning when end is reached " , ->
expect ( editor . activeEditSession ) . toBe session2
editor . loadNextEditSession ( )
expect ( editor . activeEditSession ) . toBe session0
editor . loadNextEditSession ( )
expect ( editor . activeEditSession ) . toBe session1
editor . loadNextEditSession ( )
expect ( editor . activeEditSession ) . toBe session2
describe " .loadPreviousEditSession() " , ->
it " loads the next editor state and wraps to beginning when end is reached " , ->
expect ( editor . activeEditSession ) . toBe session2
editor . loadPreviousEditSession ( )
expect ( editor . activeEditSession ) . toBe session1
editor . loadPreviousEditSession ( )
expect ( editor . activeEditSession ) . toBe session0
editor . loadPreviousEditSession ( )
expect ( editor . activeEditSession ) . toBe session2
2012-05-10 19:58:38 +04:00
2012-06-13 01:59:55 +04:00
describe " .save() " , ->
describe " when the current buffer has a path " , ->
tempFilePath = null
beforeEach ->
2012-06-29 21:20:19 +04:00
rootView . remove ( )
2012-06-30 02:08:16 +04:00
2012-06-13 01:59:55 +04:00
tempFilePath = ' /tmp/atom-temp.txt '
2012-06-29 21:20:19 +04:00
fs . write ( tempFilePath , " " )
2012-06-20 04:03:45 +04:00
rootView = new RootView ( tempFilePath )
2012-07-03 05:46:33 +04:00
editor = rootView . getActiveEditor ( )
2012-06-20 04:03:45 +04:00
project = rootView . project
2012-07-04 22:40:17 +04:00
expect ( editor . getPath ( ) ) . toBe tempFilePath
2012-06-13 01:59:55 +04:00
afterEach ->
expect ( fs . remove ( tempFilePath ) )
it " saves the current buffer to disk " , ->
2012-07-04 22:27:30 +04:00
editor . getBuffer ( ) . setText ' Edited! '
2012-06-29 21:20:19 +04:00
expect ( fs . read ( tempFilePath ) ) . not . toBe " Edited! "
2012-06-13 01:59:55 +04:00
editor . save ( )
expect ( fs . exists ( tempFilePath ) ) . toBeTruthy ( )
expect ( fs . read ( tempFilePath ) ) . toBe ' Edited! '
describe " when the current buffer has no path " , ->
selectedFilePath = null
beforeEach ->
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ) )
2012-06-20 04:03:45 +04:00
2012-07-04 22:40:17 +04:00
expect ( editor . getPath ( ) ) . toBeUndefined ( )
2012-07-04 22:27:30 +04:00
editor . getBuffer ( ) . setText ' Save me to a new path '
2012-06-13 01:59:55 +04:00
spyOn ( $native , ' saveDialog ' ) . andCallFake -> selectedFilePath
it " presents a ' save as ' dialog " , ->
editor . save ( )
expect ( $native . saveDialog ) . toHaveBeenCalled ( )
describe " when a path is chosen " , ->
it " saves the buffer to the chosen path " , ->
selectedFilePath = ' /tmp/temp.txt '
editor . save ( )
expect ( fs . exists ( selectedFilePath ) ) . toBeTruthy ( )
expect ( fs . read ( selectedFilePath ) ) . toBe ' Save me to a new path '
describe " when dialog is cancelled " , ->
it " does not save the buffer " , ->
selectedFilePath = null
editor . save ( )
expect ( fs . exists ( selectedFilePath ) ) . toBeFalsy ( )
2012-05-17 19:49:03 +04:00
describe " .scrollTop(n) " , ->
beforeEach ->
editor . attachToDom ( heightInLines: 5 )
expect ( editor . verticalScrollbar . scrollTop ( ) ) . toBe 0
describe " when called with a scroll top argument " , ->
2012-06-01 22:03:21 +04:00
it " sets the scrollTop of the vertical scrollbar and sets scrollTop on the line numbers and lines " , ->
2012-05-17 19:49:03 +04:00
editor . scrollTop ( 100 )
expect ( editor . verticalScrollbar . scrollTop ( ) ) . toBe 100
2012-06-12 02:47:32 +04:00
expect ( editor . scrollView . scrollTop ( ) ) . toBe 0
expect ( editor . renderedLines . css ( ' top ' ) ) . toBe " -100px "
2012-07-03 21:09:34 +04:00
expect ( editor . gutter . lineNumbers . css ( ' top ' ) ) . toBe " -100px "
2012-05-17 19:49:03 +04:00
2012-06-01 22:03:21 +04:00
editor . scrollTop ( 120 )
expect ( editor . verticalScrollbar . scrollTop ( ) ) . toBe 120
2012-06-12 02:47:32 +04:00
expect ( editor . scrollView . scrollTop ( ) ) . toBe 0
expect ( editor . renderedLines . css ( ' top ' ) ) . toBe " -120px "
2012-07-03 21:09:34 +04:00
expect ( editor . gutter . lineNumbers . css ( ' top ' ) ) . toBe " -120px "
2012-05-17 19:49:03 +04:00
it " does not allow negative scrollTops to be assigned " , ->
editor . scrollTop ( - 100 )
expect ( editor . scrollTop ( ) ) . toBe 0
it " doesn ' t do anything if the scrollTop hasn ' t changed " , ->
editor . scrollTop ( 100 )
spyOn ( editor . verticalScrollbar , ' scrollTop ' )
2012-06-05 04:53:58 +04:00
spyOn ( editor . renderedLines , ' css ' )
2012-05-17 19:49:03 +04:00
spyOn ( editor . gutter . lineNumbers , ' css ' )
editor . scrollTop ( 100 )
expect ( editor . verticalScrollbar . scrollTop ) . not . toHaveBeenCalled ( )
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . css ) . not . toHaveBeenCalled ( )
2012-05-17 19:49:03 +04:00
expect ( editor . gutter . lineNumbers . css ) . not . toHaveBeenCalled ( )
describe " when the ' adjustVerticalScrollbar ' option is false (defaults to true) " , ->
it " doesn ' t adjust the scrollTop of the vertical scrollbar " , ->
editor . scrollTop ( 100 , adjustVerticalScrollbar: false )
expect ( editor . verticalScrollbar . scrollTop ( ) ) . toBe 0
2012-06-12 02:47:32 +04:00
expect ( editor . renderedLines . css ( ' top ' ) ) . toBe " -100px "
2012-07-03 21:09:34 +04:00
expect ( editor . gutter . lineNumbers . css ( ' top ' ) ) . toBe " -100px "
2012-05-17 19:49:03 +04:00
describe " when called with no argument " , ->
it " returns the last assigned value or 0 if none has been assigned " , ->
expect ( editor . scrollTop ( ) ) . toBe 0
editor . scrollTop ( 50 )
expect ( editor . scrollTop ( ) ) . toBe 50
2012-06-13 01:59:55 +04:00
describe " split methods " , ->
describe " when inside a pane " , ->
fakePane = null
beforeEach ->
fakePane = { splitUp: jasmine . createSpy ( ' splitUp ' ) . andReturn ( { } ) , remove: -> }
spyOn ( editor , ' pane ' ) . andReturn ( fakePane )
2012-07-13 20:24:14 +04:00
it " calls the corresponding split method on the containing pane with a new editor containing a copy of the active edit session " , ->
2012-07-18 22:19:25 +04:00
editor . edit project . buildEditSessionForPath ( " sample.txt " )
2012-06-13 01:59:55 +04:00
editor . splitUp ( )
expect ( fakePane . splitUp ) . toHaveBeenCalled ( )
2012-07-13 20:24:14 +04:00
[ newEditor ] = fakePane . splitUp . argsForCall [ 0 ]
expect ( newEditor . editSessions . length ) . toEqual 1
expect ( newEditor . activeEditSession . buffer ) . toBe editor . activeEditSession . buffer
newEditor . remove ( )
2012-06-13 01:59:55 +04:00
describe " when not inside a pane " , ->
it " does not split the editor, but doesn ' t throw an exception " , ->
2012-06-30 02:08:16 +04:00
editor . splitUp ( ) . remove ( )
editor . splitDown ( ) . remove ( )
editor . splitLeft ( ) . remove ( )
editor . splitRight ( ) . remove ( )
2012-06-13 01:59:55 +04:00
2012-04-20 04:55:41 +04:00
describe " editor-open event " , ->
2012-04-20 05:12:55 +04:00
it ' only triggers an editor-open event when it is first added to the DOM ' , ->
2012-04-20 04:55:41 +04:00
openHandler = jasmine . createSpy ( ' openHandler ' )
editor . on ' editor-open ' , openHandler
editor . simulateDomAttachment ( )
expect ( openHandler ) . toHaveBeenCalled ( )
[ event , eventEditor ] = openHandler . argsForCall [ 0 ]
expect ( eventEditor ) . toBe editor
2012-04-20 05:12:55 +04:00
openHandler . reset ( )
editor . simulateDomAttachment ( )
expect ( openHandler ) . not . toHaveBeenCalled ( )
2012-06-13 01:59:55 +04:00
describe " editor-path-change event " , ->
2012-06-29 21:20:19 +04:00
path = null
beforeEach ->
path = " /tmp/something.txt "
fs . write ( path , path )
afterEach ->
fs . remove ( path ) if fs . exists ( path )
2012-06-13 01:59:55 +04:00
it " emits event when buffer ' s path is changed " , ->
eventHandler = jasmine . createSpy ( ' eventHandler ' )
editor . on ' editor-path-change ' , eventHandler
2012-07-04 22:27:30 +04:00
editor . getBuffer ( ) . saveAs ( path )
2012-06-29 21:20:19 +04:00
expect ( eventHandler ) . toHaveBeenCalled ( )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
it " emits event when editor receives a new buffer " , ->
eventHandler = jasmine . createSpy ( ' eventHandler ' )
editor . on ' editor-path-change ' , eventHandler
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( path ) )
2012-06-13 01:59:55 +04:00
expect ( eventHandler ) . toHaveBeenCalled ( )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
it " stops listening to events on previously set buffers " , ->
eventHandler = jasmine . createSpy ( ' eventHandler ' )
2012-07-04 22:27:30 +04:00
oldBuffer = editor . getBuffer ( )
2012-06-13 01:59:55 +04:00
editor . on ' editor-path-change ' , eventHandler
2012-05-10 19:27:04 +04:00
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( path ) )
2012-06-13 01:59:55 +04:00
expect ( eventHandler ) . toHaveBeenCalled ( )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
eventHandler . reset ( )
2012-06-29 21:20:19 +04:00
oldBuffer . saveAs ( " /tmp/atom-bad.txt " )
2012-06-13 01:59:55 +04:00
expect ( eventHandler ) . not . toHaveBeenCalled ( )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
eventHandler . reset ( )
2012-07-04 22:27:30 +04:00
editor . getBuffer ( ) . saveAs ( " /tmp/atom-new.txt " )
2012-06-13 01:59:55 +04:00
expect ( eventHandler ) . toHaveBeenCalled ( )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " font size " , ->
it " sets the initial font size based on the value assigned to the root view " , ->
rootView . setFontSize ( 20 )
rootView . simulateDomAttachment ( )
newEditor = editor . splitRight ( )
expect ( editor . css ( ' font-size ' ) ) . toBe ' 20px '
expect ( newEditor . css ( ' font-size ' ) ) . toBe ' 20px '
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the font size changes on the view " , ->
it " updates the font sizes of editors and recalculates dimensions critical to cursor positioning " , ->
rootView . attachToDom ( )
rootView . setFontSize ( 10 )
lineHeightBefore = editor . lineHeight
charWidthBefore = editor . charWidth
editor . setCursorScreenPosition [ 5 , 5 ]
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
rootView . setFontSize ( 30 )
expect ( editor . css ( ' font-size ' ) ) . toBe ' 30px '
expect ( editor . lineHeight ) . toBeGreaterThan lineHeightBefore
expect ( editor . charWidth ) . toBeGreaterThan charWidthBefore
expect ( editor . getCursorView ( ) . position ( ) ) . toEqual { top: 5 * editor . lineHeight , left: 5 * editor . charWidth }
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
# ensure we clean up font size subscription
editor . trigger ( ' close ' )
rootView . setFontSize ( 22 )
expect ( editor . css ( ' font-size ' ) ) . toBe ' 30px '
2012-05-10 19:27:04 +04:00
2012-06-16 03:44:15 +04:00
it " updates the gutter width and font size " , ->
rootView . attachToDom ( )
originalFontSize = rootView . getFontSize ( )
originalGutterWidth = editor . gutter . width ( )
rootView . setFontSize ( originalFontSize * 4 )
expect ( editor . gutter . css ( ' font-size ' ) ) . toBe " #{ originalFontSize * 4 } px "
expect ( editor . gutter . width ( ) ) . toBe ( originalGutterWidth * 4 )
2012-06-13 01:59:55 +04:00
it " updates lines if there are unrendered lines " , ->
editor . attachToDom ( heightInLines: 5 )
originalLineCount = editor . renderedLines . find ( " .line " ) . length
expect ( originalLineCount ) . toBeGreaterThan 0
editor . setFontSize ( 10 )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBeGreaterThan originalLineCount
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " mouse events " , ->
beforeEach ->
editor . attachToDom ( )
editor . css ( position: ' absolute ' , top: 10 , left: 10 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " single-click " , ->
it " re-positions the cursor to the clicked row / column " , ->
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 0 , column: 0 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 3 , 10 ] )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 3 , column: 10 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the lines are scrolled to the right " , ->
it " re-positions the cursor on the clicked location " , ->
setEditorWidthInChars ( editor , 30 )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 0 , column: 0 )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 3 , 30 ] ) # scrolls lines to the right
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 3 , 50 ] )
expect ( editor . getCursorBufferPosition ( ) ) . toEqual ( row: 3 , column: 50 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " double-click " , ->
it " selects the word under the cursor " , ->
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 0 , column: 0 )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 0 , 8 ] , originalEvent: { detail: 1 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 0 , 8 ] , originalEvent: { detail: 2 } )
editor . renderedLines . trigger ' mouseup '
expect ( editor . getSelectedText ( ) ) . toBe " quicksort "
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " triple/quardruple/etc-click " , ->
it " selects the line under the cursor " , ->
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 0 , column: 0 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
# Triple click
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 1 , 8 ] , originalEvent: { detail: 1 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 1 , 8 ] , originalEvent: { detail: 2 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 1 , 8 ] , originalEvent: { detail: 3 } )
editor . renderedLines . trigger ' mouseup '
expect ( editor . getSelectedText ( ) ) . toBe " var sort = function(items) { "
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
# Quad click
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 2 , 3 ] , originalEvent: { detail: 1 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 2 , 3 ] , originalEvent: { detail: 2 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 2 , 3 ] , originalEvent: { detail: 3 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 2 , 3 ] , originalEvent: { detail: 4 } )
editor . renderedLines . trigger ' mouseup '
expect ( editor . getSelectedText ( ) ) . toBe " if (items.length <= 1) return items; "
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " shift-click " , ->
it " selects from the cursor ' s current location to the clicked location " , ->
editor . setCursorScreenPosition ( [ 4 , 7 ] )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true )
expect ( editor . getSelection ( ) . getScreenRange ( ) ) . toEqual [ [ 4 , 7 ] , [ 5 , 24 ] ]
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " shift-double-click " , ->
it " expands the selection to include the double-clicked word " , ->
editor . setCursorScreenPosition ( [ 4 , 7 ] )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true , originalEvent: { detail: 1 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true , originalEvent: { detail: 2 } )
editor . renderedLines . trigger ' mouseup '
expect ( editor . getSelection ( ) . getScreenRange ( ) ) . toEqual [ [ 4 , 7 ] , [ 5 , 27 ] ]
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " shift-triple-click " , ->
it " expands the selection to include the triple-clicked line " , ->
editor . setCursorScreenPosition ( [ 4 , 7 ] )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true , originalEvent: { detail: 1 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true , originalEvent: { detail: 2 } )
editor . renderedLines . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 5 , 24 ] , shiftKey: true , originalEvent: { detail: 3 } )
editor . renderedLines . trigger ' mouseup '
expect ( editor . getSelection ( ) . getScreenRange ( ) ) . toEqual [ [ 4 , 7 ] , [ 5 , 30 ] ]
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
describe " meta-click " , ->
it " places an additional cursor " , ->
editor . attachToDom ( )
setEditorHeightInLines ( editor , 5 )
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 3 , 0 ] )
editor . scrollTop ( editor . lineHeight * 6 )
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
spyOn ( editor , " scrollTo " ) . andCallThrough ( )
2012-05-15 02:18:37 +04:00
2012-06-13 01:59:55 +04:00
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 6 , 0 ] , metaKey: true )
expect ( editor . scrollTo . callCount ) . toBe 1
2012-05-10 19:27:04 +04:00
2012-06-13 01:59:55 +04:00
[ cursor1 , cursor2 ] = editor . getCursorViews ( )
expect ( cursor1 . position ( ) ) . toEqual ( top: 3 * editor . lineHeight , left: 0 )
expect ( cursor1 . getBufferPosition ( ) ) . toEqual [ 3 , 0 ]
expect ( cursor2 . position ( ) ) . toEqual ( top: 6 * editor . lineHeight , left: 0 )
expect ( cursor2 . getBufferPosition ( ) ) . toEqual [ 6 , 0 ]
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
describe " click and drag " , ->
it " creates a selection from the initial click to mouse cursor ' s location " , ->
editor . attachToDom ( )
editor . css ( position: ' absolute ' , top: 10 , left: 10 )
2012-05-31 20:46:00 +04:00
2012-06-13 01:59:55 +04:00
# start
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 10 ] )
2012-05-31 20:46:00 +04:00
2012-06-13 01:59:55 +04:00
# moving changes selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 5 , 27 ] )
2012-05-31 20:46:00 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 10 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-05-31 20:46:00 +04:00
2012-06-13 01:59:55 +04:00
# mouse up may occur outside of editor, but still need to halt selection
$ ( document ) . trigger ' mouseup '
2012-05-31 20:46:00 +04:00
2012-06-13 01:59:55 +04:00
# moving after mouse up should not change selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 8 , 8 ] )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 10 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
describe " double-click and drag " , ->
it " creates a selection from the word underneath an initial double click to mouse ' s new location " , ->
editor . attachToDom ( )
editor . css ( position: ' absolute ' , top: 10 , left: 10 )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
# double click
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 7 ] , originalEvent: { detail: 1 } )
$ ( document ) . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 7 ] , originalEvent: { detail: 2 } )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
# moving changes selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 5 , 27 ] )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 4 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
# mouse up may occur outside of editor, but still need to halt selection
$ ( document ) . trigger ' mouseup '
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
# moving after mouse up should not change selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 8 , 8 ] )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 4 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-06-01 03:48:50 +04:00
2012-06-13 01:59:55 +04:00
describe " trip-click and drag " , ->
it " creates a selection from the line underneath an initial triple click to mouse ' s new location " , ->
editor . attachToDom ( )
editor . css ( position: ' absolute ' , top: 10 , left: 10 )
2012-05-27 00:52:48 +04:00
2012-06-13 01:59:55 +04:00
# double click
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 7 ] , originalEvent: { detail: 1 } )
$ ( document ) . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 7 ] , originalEvent: { detail: 2 } )
$ ( document ) . trigger ' mouseup '
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 7 ] , originalEvent: { detail: 3 } )
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
# moving changes selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 5 , 27 ] )
2012-05-30 01:12:11 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 0 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-06-05 06:29:40 +04:00
2012-06-13 01:59:55 +04:00
# mouse up may occur outside of editor, but still need to halt selection
$ ( document ) . trigger ' mouseup '
2012-05-17 03:28:07 +04:00
2012-06-13 01:59:55 +04:00
# moving after mouse up should not change selection
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 8 , 8 ] )
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
range = editor . getSelection ( ) . getScreenRange ( )
expect ( range . start ) . toEqual ( { row: 4 , column: 0 } )
expect ( range . end ) . toEqual ( { row: 5 , column: 27 } )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 5 , column: 27 )
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
describe " meta-click and drag " , ->
it " adds an additional selection " , ->
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 4 , 10 ] )
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 5 , 27 ] )
editor . renderedLines . trigger ' mouseup '
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
editor . renderedLines . trigger mousedownEvent ( editor: editor , point: [ 6 , 10 ] , metaKey: true )
editor . renderedLines . trigger mousemoveEvent ( editor: editor , point: [ 8 , 27 ] , metaKey: true )
editor . renderedLines . trigger ' mouseup '
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
selections = editor . getSelections ( )
expect ( selections . length ) . toBe 2
[ selection1 , selection2 ] = selections
expect ( selection1 . getScreenRange ( ) ) . toEqual [ [ 4 , 10 ] , [ 5 , 27 ] ]
expect ( selection2 . getScreenRange ( ) ) . toEqual [ [ 6 , 10 ] , [ 8 , 27 ] ]
2012-05-27 00:05:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when text input events are triggered on the hidden input element " , ->
it " inserts the typed character at the cursor position, both in the buffer and the pre element " , ->
editor . attachToDom ( )
editor . setCursorScreenPosition ( row: 1 , column: 6 )
2012-05-11 02:11:05 +04:00
2012-06-13 01:59:55 +04:00
expect ( buffer . lineForRow ( 1 ) . charAt ( 6 ) ) . not . toBe ' q '
2012-05-11 01:15:34 +04:00
2012-06-13 01:59:55 +04:00
editor . hiddenInput . textInput ' q '
2012-05-24 22:43:09 +04:00
2012-06-13 01:59:55 +04:00
expect ( buffer . lineForRow ( 1 ) . charAt ( 6 ) ) . toBe ' q '
expect ( editor . getCursorScreenPosition ( ) ) . toEqual ( row: 1 , column: 7 )
expect ( editor . renderedLines . find ( ' .line:eq(1) ' ) ) . toHaveText buffer . lineForRow ( 1 )
2012-05-24 22:43:09 +04:00
2012-06-13 20:19:24 +04:00
describe " selection rendering " , ->
[ charWidth , lineHeight , selection , selectionView ] = [ ]
beforeEach ->
editor . attachToDom ( )
editor . width ( 500 )
{ charWidth , lineHeight } = editor
selection = editor . getSelection ( )
selectionView = editor . getSelectionView ( )
describe " when a selection is added " , ->
it " adds a selection view for it with the proper regions " , ->
editor . activeEditSession . addSelectionForBufferRange ( [ [ 2 , 7 ] , [ 2 , 25 ] ] )
selectionViews = editor . getSelectionViews ( )
expect ( selectionViews . length ) . toBe 2
expect ( selectionViews [ 1 ] . regions . length ) . toBe 1
region = selectionViews [ 1 ] . regions [ 0 ]
expect ( region . position ( ) . top ) . toBe ( 2 * lineHeight )
expect ( region . position ( ) . left ) . toBe ( 7 * charWidth )
expect ( region . height ( ) ) . toBe lineHeight
expect ( region . width ( ) ) . toBe ( ( 25 - 7 ) * charWidth )
describe " when a selection changes " , ->
describe " when the selection is within a single line " , ->
it " covers the selection ' s range with a single region " , ->
selection . setBufferRange ( new Range ( { row: 2 , column: 7 } , { row: 2 , column: 25 } ) )
expect ( selectionView . regions . length ) . toBe 1
region = selectionView . regions [ 0 ]
expect ( region . position ( ) . top ) . toBe ( 2 * lineHeight )
expect ( region . position ( ) . left ) . toBe ( 7 * charWidth )
expect ( region . height ( ) ) . toBe lineHeight
expect ( region . width ( ) ) . toBe ( ( 25 - 7 ) * charWidth )
describe " when the selection spans 2 lines " , ->
it " covers the selection ' s range with 2 regions " , ->
selection . setBufferRange ( new Range ( { row: 2 , column: 7 } , { row: 3 , column: 25 } ) )
expect ( selectionView . regions . length ) . toBe 2
region1 = selectionView . regions [ 0 ]
expect ( region1 . position ( ) . top ) . toBe ( 2 * lineHeight )
expect ( region1 . position ( ) . left ) . toBe ( 7 * charWidth )
expect ( region1 . height ( ) ) . toBe lineHeight
expect ( region1 . width ( ) ) . toBe ( editor . renderedLines . width ( ) - region1 . position ( ) . left )
region2 = selectionView . regions [ 1 ]
expect ( region2 . position ( ) . top ) . toBe ( 3 * lineHeight )
expect ( region2 . position ( ) . left ) . toBe ( 0 )
expect ( region2 . height ( ) ) . toBe lineHeight
expect ( region2 . width ( ) ) . toBe ( 25 * charWidth )
describe " when the selection spans more than 2 lines " , ->
it " covers the selection ' s range with 3 regions " , ->
selection . setBufferRange ( new Range ( { row: 2 , column: 7 } , { row: 6 , column: 25 } ) )
expect ( selectionView . regions . length ) . toBe 3
region1 = selectionView . regions [ 0 ]
expect ( region1 . position ( ) . top ) . toBe ( 2 * lineHeight )
expect ( region1 . position ( ) . left ) . toBe ( 7 * charWidth )
expect ( region1 . height ( ) ) . toBe lineHeight
expect ( region1 . width ( ) ) . toBe ( editor . renderedLines . width ( ) - region1 . position ( ) . left )
region2 = selectionView . regions [ 1 ]
expect ( region2 . position ( ) . top ) . toBe ( 3 * lineHeight )
expect ( region2 . position ( ) . left ) . toBe ( 0 )
expect ( region2 . height ( ) ) . toBe ( 3 * lineHeight )
expect ( region2 . width ( ) ) . toBe ( editor . renderedLines . width ( ) )
# resizes with the editor
expect ( editor . width ( ) ) . toBeLessThan ( 800 )
editor . width ( 800 )
expect ( region2 . width ( ) ) . toBe ( editor . renderedLines . width ( ) )
region3 = selectionView . regions [ 2 ]
expect ( region3 . position ( ) . top ) . toBe ( 6 * lineHeight )
expect ( region3 . position ( ) . left ) . toBe ( 0 )
expect ( region3 . height ( ) ) . toBe lineHeight
expect ( region3 . width ( ) ) . toBe ( 25 * charWidth )
it " clears previously drawn regions before creating new ones " , ->
selection . setBufferRange ( new Range ( { row: 2 , column: 7 } , { row: 4 , column: 25 } ) )
expect ( selectionView . regions . length ) . toBe 3
expect ( selectionView . find ( ' .selection ' ) . length ) . toBe 3
selectionView . updateAppearance ( )
expect ( selectionView . regions . length ) . toBe 3
expect ( selectionView . find ( ' .selection ' ) . length ) . toBe 3
2012-06-14 20:28:21 +04:00
describe " when a selection merges with another selection " , ->
it " removes the merged selection view " , ->
editSession = editor . activeEditSession
editSession . setCursorScreenPosition ( [ 4 , 10 ] )
editSession . selectToScreenPosition ( [ 5 , 27 ] )
editSession . addCursorAtScreenPosition ( [ 3 , 10 ] )
editSession . selectToScreenPosition ( [ 6 , 27 ] )
expect ( editor . getSelectionViews ( ) . length ) . toBe 1
expect ( editor . find ( ' .selection ' ) . length ) . toBe 3
2012-06-13 21:04:17 +04:00
describe " cursor rendering " , ->
describe " when the cursor moves " , ->
charWidth = null
2012-05-29 22:52:39 +04:00
2012-06-13 21:04:17 +04:00
beforeEach ->
editor . attachToDom ( )
editor.vScrollMargin = 3
editor.hScrollMargin = 5
{ charWidth } = editor
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
it " repositions the cursor ' s view on screen " , ->
editor . setCursorScreenPosition ( row: 2 , column: 2 )
expect ( editor . getCursorView ( ) . position ( ) ) . toEqual ( top: 2 * editor . lineHeight , left: 2 * editor . charWidth )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
it " removes the idle class while moving, then adds it back when it stops " , ->
cursorView = editor . getCursorView ( )
advanceClock ( 200 )
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
expect ( cursorView ) . toHaveClass ' idle '
editor . setCursorScreenPosition ( [ 1 , 2 ] )
expect ( cursorView ) . not . toHaveClass ' idle '
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
window . advanceClock ( 200 )
expect ( cursorView ) . toHaveClass ' idle '
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 1 , 3 ] )
advanceClock ( 100 )
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 1 , 4 ] )
advanceClock ( 100 )
expect ( cursorView ) . not . toHaveClass ' idle '
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
advanceClock ( 100 )
expect ( cursorView ) . toHaveClass ' idle '
2012-06-13 01:59:55 +04:00
2012-06-13 21:04:17 +04:00
describe " auto-scrolling " , ->
it " only auto-scrolls when the last cursor is moved " , ->
editor . setCursorBufferPosition ( [ 11 , 0 ] )
editor . addCursorAtBufferPosition ( [ 6 , 50 ] )
[ cursor1 , cursor2 ] = editor . getCursors ( )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
spyOn ( editor , ' scrollTo ' )
cursor1 . setScreenPosition ( [ 10 , 10 ] )
expect ( editor . scrollTo ) . not . toHaveBeenCalled ( )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
cursor2 . setScreenPosition ( [ 11 , 11 ] )
expect ( editor . scrollTo ) . toHaveBeenCalled ( )
2012-06-06 00:26:06 +04:00
2012-06-13 21:04:17 +04:00
describe " when the last cursor exceeds the upper or lower scroll margins " , ->
describe " when the editor is taller than twice the vertical scroll margin " , ->
it " sets the scrollTop so the cursor remains within the scroll margin " , ->
setEditorHeightInLines ( editor , 10 )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
_ . times 6 , -> editor . moveCursorDown ( )
expect ( editor . scrollTop ( ) ) . toBe ( 0 )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
editor . moveCursorDown ( )
expect ( editor . scrollTop ( ) ) . toBe ( editor . lineHeight )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
editor . moveCursorDown ( )
expect ( editor . scrollTop ( ) ) . toBe ( editor . lineHeight * 2 )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
_ . times 3 , -> editor . moveCursorUp ( )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
editor . moveCursorUp ( )
expect ( editor . scrollTop ( ) ) . toBe ( editor . lineHeight )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
editor . moveCursorUp ( )
expect ( editor . scrollTop ( ) ) . toBe ( 0 )
2012-05-24 22:43:09 +04:00
2012-06-13 21:04:17 +04:00
describe " when the editor is shorter than twice the vertical scroll margin " , ->
it " sets the scrollTop based on a reduced scroll margin, which prevents a jerky tug-of-war between upper and lower scroll margins " , ->
setEditorHeightInLines ( editor , 5 )
2012-06-06 00:26:06 +04:00
2012-06-13 21:04:17 +04:00
_ . times 3 , -> editor . moveCursorDown ( )
2012-06-05 06:45:28 +04:00
2012-06-13 21:04:17 +04:00
expect ( editor . scrollTop ( ) ) . toBe ( editor . lineHeight )
2012-06-05 06:45:28 +04:00
2012-06-13 21:04:17 +04:00
editor . moveCursorUp ( )
expect ( editor . renderedLines . css ( ' top ' ) ) . toBe " 0px "
describe " when the last cursor exceeds the right or left scroll margins " , ->
describe " when soft-wrap is disabled " , ->
describe " when the editor is wider than twice the horizontal scroll margin " , ->
it " sets the scrollView ' s scrollLeft so the cursor remains within the scroll margin " , ->
setEditorWidthInChars ( editor , 30 )
2012-06-05 07:11:32 +04:00
2012-06-13 21:04:17 +04:00
# moving right
editor . setCursorScreenPosition ( [ 2 , 24 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
2012-06-05 07:11:32 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 25 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe charWidth
2012-06-05 07:11:32 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 28 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe charWidth * 4
2012-03-03 04:23:57 +04:00
2012-06-13 21:04:17 +04:00
# moving left
editor . setCursorScreenPosition ( [ 2 , 9 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe charWidth * 4
2012-03-03 04:23:57 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 8 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe charWidth * 3
2012-05-29 23:39:13 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 5 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
2012-03-03 04:23:57 +04:00
2012-06-13 21:04:17 +04:00
describe " when the editor is narrower than twice the horizontal scroll margin " , ->
it " sets the scrollView ' s scrollLeft based on a reduced horizontal scroll margin, to prevent a jerky tug-of-war between right and left scroll margins " , ->
editor.hScrollMargin = 6
setEditorWidthInChars ( editor , 7 )
2012-05-17 21:16:20 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 3 ] )
window . advanceClock ( )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe ( 0 )
2012-05-17 21:16:20 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 4 ] )
window . advanceClock ( )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe ( charWidth )
2012-05-30 00:51:19 +04:00
2012-06-13 21:04:17 +04:00
editor . setCursorScreenPosition ( [ 2 , 3 ] )
window . advanceClock ( )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe ( 0 )
2012-05-30 00:51:19 +04:00
2012-06-13 21:04:17 +04:00
describe " when soft-wrap is enabled " , ->
beforeEach ->
editor . setSoftWrap ( true )
2012-05-30 00:51:19 +04:00
2012-06-13 21:04:17 +04:00
it " does not scroll the buffer horizontally " , ->
editor . width ( charWidth * 30 )
# moving right
editor . setCursorScreenPosition ( [ 2 , 24 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
editor . setCursorScreenPosition ( [ 2 , 25 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
editor . setCursorScreenPosition ( [ 2 , 28 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
# moving left
editor . setCursorScreenPosition ( [ 2 , 9 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
editor . setCursorScreenPosition ( [ 2 , 8 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
editor . setCursorScreenPosition ( [ 2 , 5 ] )
expect ( editor . scrollView . scrollLeft ( ) ) . toBe 0
2012-05-17 21:17:05 +04:00
2012-06-13 01:59:55 +04:00
describe " text rendering " , ->
describe " when all lines in the buffer are visible on screen " , ->
beforeEach ->
editor . attachToDom ( )
expect ( editor . height ( ) ) . toBe buffer . getLineCount ( ) * editor . lineHeight
2012-03-07 23:19:30 +04:00
2012-06-13 01:59:55 +04:00
it " creates a line element for each line in the buffer with the html-escaped text of the line " , ->
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toEqual ( buffer . getLineCount ( ) )
expect ( buffer . lineForRow ( 2 ) ) . toContain ( ' < ' )
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . html ( ) ) . toContain ' < '
2012-03-17 02:11:44 +04:00
2012-06-13 01:59:55 +04:00
# renders empty lines with a non breaking space
expect ( buffer . lineForRow ( 10 ) ) . toBe ' '
expect ( editor . renderedLines . find ( ' .line:eq(10) ' ) . html ( ) ) . toBe ' '
2012-05-24 22:17:37 +04:00
2012-06-13 01:59:55 +04:00
it " syntax highlights code based on the file type " , ->
line1 = editor . renderedLines . find ( ' .line:first ' )
expect ( line1 . find ( ' span:eq(0) ' ) ) . toMatchSelector ' .keyword.definition '
expect ( line1 . find ( ' span:eq(0) ' ) . text ( ) ) . toBe ' var '
expect ( line1 . find ( ' span:eq(1) ' ) ) . toMatchSelector ' .text '
expect ( line1 . find ( ' span:eq(1) ' ) . text ( ) ) . toBe ' '
expect ( line1 . find ( ' span:eq(2) ' ) ) . toMatchSelector ' .identifier '
expect ( line1 . find ( ' span:eq(2) ' ) . text ( ) ) . toBe ' quicksort '
expect ( line1 . find ( ' span:eq(4) ' ) ) . toMatchSelector ' .operator '
expect ( line1 . find ( ' span:eq(4) ' ) . text ( ) ) . toBe ' = '
2012-03-17 02:11:44 +04:00
2012-06-13 01:59:55 +04:00
line12 = editor . renderedLines . find ( ' .line:eq(11) ' )
expect ( line12 . find ( ' span:eq(1) ' ) ) . toMatchSelector ' .keyword '
2012-05-31 21:12:59 +04:00
2012-06-13 01:59:55 +04:00
describe " when lines are updated in the buffer " , ->
it " syntax highlights the updated lines " , ->
expect ( editor . renderedLines . find ( ' .line:eq(0) span:eq(0) ' ) ) . toMatchSelector ' .keyword.definition '
buffer . insert ( [ 0 , 4 ] , " g " )
expect ( editor . renderedLines . find ( ' .line:eq(0) span:eq(0) ' ) ) . toMatchSelector ' .keyword.definition '
2012-05-31 21:12:59 +04:00
2012-06-13 01:59:55 +04:00
# verify that re-highlighting can occur below the changed line
buffer . insert ( [ 5 , 0 ] , " /* */ " )
buffer . insert ( [ 1 , 0 ] , " /* " )
expect ( editor . renderedLines . find ( ' .line:eq(2) span:eq(0) ' ) ) . toMatchSelector ' .comment '
2012-03-14 02:09:11 +04:00
2012-06-13 01:59:55 +04:00
describe " when soft-wrap is enabled " , ->
beforeEach ->
setEditorHeightInLines ( editor , 20 )
setEditorWidthInChars ( editor , 50 )
editor . setSoftWrap ( true )
2012-06-14 06:34:13 +04:00
expect ( editor . activeEditSession . softWrapColumn ) . toBe 50
2012-03-14 02:09:11 +04:00
2012-06-13 01:59:55 +04:00
it " wraps lines that are too long to fit within the editor ' s width, adjusting cursor positioning accordingly " , ->
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 16
expect ( editor . renderedLines . find ( ' .line:eq(3) ' ) . text ( ) ) . toBe " var pivot = items.shift(), current, left = [], "
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toBe " right = []; "
2012-03-14 02:09:11 +04:00
2012-06-13 01:59:55 +04:00
editor . setCursorBufferPosition ( [ 3 , 51 ] )
expect ( editor . find ( ' .cursor ' ) . offset ( ) ) . toEqual ( editor . renderedLines . find ( ' .line:eq(4) ' ) . offset ( ) )
2012-03-14 02:09:11 +04:00
2012-06-13 01:59:55 +04:00
editor . setCursorBufferPosition ( [ 4 , 0 ] )
expect ( editor . find ( ' .cursor ' ) . offset ( ) ) . toEqual ( editor . renderedLines . find ( ' .line:eq(5) ' ) . offset ( ) )
editor . getSelection ( ) . setBufferRange ( new Range ( [ 6 , 30 ] , [ 6 , 55 ] ) )
[ region1 , region2 ] = editor . getSelectionView ( ) . regions
expect ( region1 . offset ( ) . top ) . toBe ( editor . renderedLines . find ( ' .line:eq(7) ' ) . offset ( ) . top )
expect ( region2 . offset ( ) . top ) . toBe ( editor . renderedLines . find ( ' .line:eq(8) ' ) . offset ( ) . top )
2012-03-14 02:09:11 +04:00
2012-06-13 01:59:55 +04:00
it " handles changes to wrapped lines correctly " , ->
buffer . insert ( [ 6 , 28 ] , ' 1234567 ' )
expect ( editor . renderedLines . find ( ' .line:eq(7) ' ) . text ( ) ) . toBe ' current < pivot ? left1234567.push(current) '
expect ( editor . renderedLines . find ( ' .line:eq(8) ' ) . text ( ) ) . toBe ' : right.push(current); '
expect ( editor . renderedLines . find ( ' .line:eq(9) ' ) . text ( ) ) . toBe ' } '
2012-03-07 23:19:30 +04:00
2012-06-13 01:59:55 +04:00
it " changes the max line length and repositions the cursor when the window size changes " , ->
editor . setCursorBufferPosition ( [ 3 , 60 ] )
setEditorWidthInChars ( editor , 40 )
$ ( window ) . trigger ' resize '
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 19
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toBe " left = [], right = []; "
expect ( editor . renderedLines . find ( ' .line:eq(5) ' ) . text ( ) ) . toBe " while(items.length > 0) { "
expect ( editor . bufferPositionForScreenPosition ( editor . getCursorScreenPosition ( ) ) ) . toEqual [ 3 , 60 ]
2012-05-16 23:47:59 +04:00
2012-06-20 04:55:51 +04:00
it " does not wrap the lines of any newly assigned buffers " , ->
2012-07-18 22:19:25 +04:00
otherEditSession = rootView . project . buildEditSessionForPath ( )
2012-06-20 04:03:45 +04:00
otherEditSession . buffer . setText ( [ 1 . . 100 ] . join ( ' ' ) )
editor . edit ( otherEditSession )
2012-06-20 04:55:51 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe ( 1 )
2012-05-09 18:34:08 +04:00
2012-06-13 01:59:55 +04:00
it " unwraps lines and cancels window resize listener when softwrap is disabled " , ->
editor . toggleSoftWrap ( )
expect ( editor . renderedLines . find ( ' .line:eq(3) ' ) . text ( ) ) . toBe ' var pivot = items.shift(), current, left = [], right = []; '
2012-05-09 18:34:08 +04:00
2012-06-13 01:59:55 +04:00
spyOn ( editor , ' setSoftWrapColumn ' )
$ ( window ) . trigger ' resize '
expect ( editor . setSoftWrapColumn ) . not . toHaveBeenCalled ( )
2012-05-09 18:34:08 +04:00
2012-06-13 01:59:55 +04:00
it " allows the cursor to move down to the last line " , ->
_ . times editor . getLastScreenRow ( ) , -> editor . moveCursorDown ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ editor . getLastScreenRow ( ) , 0 ]
editor . moveCursorDown ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ editor . getLastScreenRow ( ) , 2 ]
2012-05-09 18:34:08 +04:00
2012-06-13 01:59:55 +04:00
it " allows the cursor to move up to a shorter soft wrapped line " , ->
editor . setCursorScreenPosition ( [ 11 , 15 ] )
editor . moveCursorUp ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 10 , 10 ]
editor . moveCursorUp ( )
editor . moveCursorUp ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 8 , 15 ]
2012-05-16 21:58:19 +04:00
2012-06-13 01:59:55 +04:00
it " it allows the cursor to wrap when moving horizontally past the beginning / end of a wrapped line " , ->
editor . setCursorScreenPosition ( [ 11 , 0 ] )
editor . moveCursorLeft ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 10 , 10 ]
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
editor . moveCursorRight ( )
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 11 , 0 ]
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
it " calls .setSoftWrapColumn() when the editor is attached because now its dimensions are available to calculate it " , ->
2012-07-18 22:19:25 +04:00
otherEditor = new Editor ( editSession: rootView . project . buildEditSessionForPath ( ' sample.js ' ) )
2012-06-13 01:59:55 +04:00
spyOn ( otherEditor , ' setSoftWrapColumn ' )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
otherEditor . setSoftWrap ( true )
expect ( otherEditor . setSoftWrapColumn ) . not . toHaveBeenCalled ( )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
otherEditor . simulateDomAttachment ( )
expect ( otherEditor . setSoftWrapColumn ) . toHaveBeenCalled ( )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when some lines at the end of the buffer are not visible on screen " , ->
beforeEach ->
editor . attachToDom ( heightInLines: 5.5 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
it " only renders the visible lines plus the overdrawn lines, setting the padding-bottom of the lines element to account for the missing lines " , ->
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expectedPaddingBottom = ( buffer . getLineCount ( ) - 8 ) * editor . lineHeight
expect ( editor . renderedLines . css ( ' padding-bottom ' ) ) . toBe " #{ expectedPaddingBottom } px "
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
it " renders additional lines when the editor is resized " , ->
setEditorHeightInLines ( editor , 10 )
$ ( window ) . trigger ' resize '
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 12
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 11 )
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
it " renders correctly when scrolling after text is added to the buffer " , ->
editor . insertText ( " 1 \n " )
_ . times 4 , -> editor . moveCursorDown ( )
2012-07-04 22:47:51 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 2 )
expect ( editor . renderedLines . find ( ' .line:eq(7) ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
it " renders correctly when scrolling after text is removed from buffer " , ->
2012-07-04 22:27:30 +04:00
editor . getBuffer ( ) . delete ( [ [ 0 , 0 ] , [ 1 , 0 ] ] )
2012-07-04 22:47:51 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(0) ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:eq(5) ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 5 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( 3 * editor . lineHeight )
2012-07-04 22:47:51 +04:00
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 1 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe editor . lineForBufferRow ( 10 )
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
describe " when creating and destroying folds that are longer than the visible lines " , ->
describe " when the cursor precedes the fold when it is destroyed " , ->
it " renders lines and line numbers correctly " , ->
scrollHeightBeforeFold = editor . scrollView . prop ( ' scrollHeight ' )
fold = editor . createFold ( 1 , 9 )
fold . destroy ( )
expect ( editor . scrollView . prop ( ' scrollHeight ' ) ) . toBe scrollHeightBeforeFold
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toBe 8
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 8 '
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( 4 * editor . lineHeight )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 11 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when the cursor follows the fold when it is destroyed " , ->
it " renders lines and line numbers correctly " , ->
fold = editor . createFold ( 1 , 9 )
editor . setCursorBufferPosition ( [ 10 , 0 ] )
fold . destroy ( )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toBe 8
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 13 '
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( 4 * editor . lineHeight )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 11 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when scrolling vertically " , ->
describe " when scrolling less than the editor ' s height " , ->
it " draws new lines and removes old lines when the last visible line will exceed the last rendered line " , ->
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( editor . lineHeight * 1.5 )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( editor . lineHeight * 3.5 ) # first visible row will be 3, last will be 8
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 1 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . html ( ) ) . toBe ' ' # line 10 is blank
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe ' 2 '
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 11 '
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
# here we don't scroll far enough to trigger additional rendering
editor . scrollTop ( editor . lineHeight * 5.5 ) # first visible row will be 5, last will be 10
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 1 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . html ( ) ) . toBe ' ' # line 10 is blank
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe ' 2 '
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 11 '
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( editor . lineHeight * 7.5 ) # first visible row is 7, last will be 12
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 5 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( editor . lineHeight * 3.5 ) # first visible row will be 3, last will be 8
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 1 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . html ( ) ) . toBe ' ' # line 10 is blank
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( 0 )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when scrolling more than the editors height " , ->
it " removes lines that are offscreen and not in range of the overdraw and builds lines that become visible " , ->
editor . scrollTop ( editor . scrollView . prop ( ' scrollHeight ' ) - editor . scrollView . height ( ) )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 5 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . verticalScrollbar . scrollBottom ( 0 )
editor . verticalScrollbar . trigger ' scroll '
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . renderedLines . find ( ' .line:first ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( ' .line:last ' ) . text ( ) ) . toBe buffer . lineForRow ( 7 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
it " adjusts the vertical padding of the lines element to account for non-rendered lines " , ->
editor . scrollTop ( editor . lineHeight * 3 )
firstVisibleBufferRow = 3
expectedPaddingTop = ( firstVisibleBufferRow - editor . lineOverdraw ) * editor . lineHeight
expect ( editor . renderedLines . css ( ' padding-top ' ) ) . toBe " #{ expectedPaddingTop } px "
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
lastVisibleBufferRow = Math . ceil ( 3 + 5.5 ) # scroll top in lines + height in lines
lastOverdrawnRow = lastVisibleBufferRow + editor . lineOverdraw
expectedPaddingBottom = ( ( buffer . getLineCount ( ) - lastOverdrawnRow ) * editor . lineHeight )
expect ( editor . renderedLines . css ( ' padding-bottom ' ) ) . toBe " #{ expectedPaddingBottom } px "
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollToBottom ( )
# scrolled to bottom, first visible row is 5 and first rendered row is 3
firstVisibleBufferRow = Math . floor ( buffer . getLineCount ( ) - 5.5 )
firstOverdrawnBufferRow = firstVisibleBufferRow - editor . lineOverdraw
expectedPaddingTop = firstOverdrawnBufferRow * editor . lineHeight
expect ( editor . renderedLines . css ( ' padding-top ' ) ) . toBe " #{ expectedPaddingTop } px "
expect ( editor . renderedLines . css ( ' padding-bottom ' ) ) . toBe " 0px "
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when lines are added " , ->
beforeEach ->
editor . attachToDom ( heightInLines: 5 )
spyOn ( editor , " scrollTo " )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change the precedes the first rendered row " , ->
it " inserts and removes rendered lines to account for upstream change " , ->
editor . scrollToBottom ( )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
buffer . change ( [ [ 1 , 0 ] , [ 3 , 0 ] ] , " 1 \n 2 \n 3 \n " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 8
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 13 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change straddles the first rendered row " , ->
it " doesn ' t render rows that were not previously rendered " , ->
editor . scrollToBottom ( )
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-06-13 01:33:25 +04:00
2012-06-13 01:59:55 +04:00
buffer . change ( [ [ 2 , 0 ] , [ 7 , 0 ] ] , " 2 \n 3 \n 4 \n 5 \n 6 \n 7 \n 8 \n 9 \n " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 9
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 14 )
2012-06-13 00:44:45 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change straddles the last rendered row " , ->
it " doesn ' t render rows that were not previously rendered " , ->
buffer . change ( [ [ 2 , 0 ] , [ 7 , 0 ] ] , " 2 \n 3 \n 4 \n 5 \n 6 \n 7 \n 8 \n " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
2012-03-29 01:22:53 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change the follows the last rendered row " , ->
it " does not change the rendered lines " , ->
buffer . change ( [ [ 12 , 0 ] , [ 12 , 0 ] ] , " 12 \n 13 \n 14 \n " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
2012-03-29 01:22:53 +04:00
2012-07-13 20:05:38 +04:00
it " increases the width of the rendered lines element to be either the width of the longest line or the width of the scrollView (whichever is longer) " , ->
2012-07-16 20:14:33 +04:00
maxLineLength = editor . maxScreenLineLength ( )
setEditorWidthInChars ( editor , maxLineLength )
2012-06-13 01:59:55 +04:00
widthBefore = editor . renderedLines . width ( )
2012-07-13 20:05:38 +04:00
expect ( widthBefore ) . toBe editor . scrollView . width ( )
2012-07-16 20:14:33 +04:00
buffer . change ( [ [ 12 , 0 ] , [ 12 , 0 ] ] , [ 1 . . maxLineLength * 2 ] . join ( ' ' ) )
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . width ( ) ) . toBeGreaterThan widthBefore
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when lines are removed " , ->
beforeEach ->
editor . attachToDom ( heightInLines: 5 )
spyOn ( editor , " scrollTo " )
2012-04-04 03:12:04 +04:00
2012-07-16 20:14:33 +04:00
it " sets the rendered screen line ' s width to either the max line length or the scollView ' s width (whichever is greater) " , ->
maxLineLength = editor . maxScreenLineLength ( )
setEditorWidthInChars ( editor , maxLineLength )
buffer . change ( [ [ 12 , 0 ] , [ 12 , 0 ] ] , [ 1 . . maxLineLength * 2 ] . join ( ' ' ) )
expect ( editor . renderedLines . width ( ) ) . toBeGreaterThan editor . scrollView . width ( )
widthBefore = editor . renderedLines . width ( )
buffer . delete ( [ [ 12 , 0 ] , [ 12 , Infinity ] ] )
expect ( editor . renderedLines . width ( ) ) . toBe editor . scrollView . width ( )
2012-06-13 01:59:55 +04:00
describe " when the change the precedes the first rendered row " , ->
it " removes rendered lines to account for upstream change " , ->
editor . scrollToBottom ( )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
buffer . change ( [ [ 1 , 0 ] , [ 2 , 0 ] ] , " " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 6
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 11 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change straddles the first rendered row " , ->
it " renders the correct rows " , ->
editor . scrollToBottom ( )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 12 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
buffer . change ( [ [ 7 , 0 ] , [ 11 , 0 ] ] , " 1 \n 2 \n " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 5
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 10 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change straddles the last rendered row " , ->
it " renders the correct rows " , ->
buffer . change ( [ [ 2 , 0 ] , [ 7 , 0 ] ] , " " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the change the follows the last rendered row " , ->
it " does not change the rendered lines " , ->
buffer . change ( [ [ 10 , 0 ] , [ 12 , 0 ] ] , " " )
expect ( editor . renderedLines . find ( " .line " ) . length ) . toBe 7
expect ( editor . renderedLines . find ( " .line:first " ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
expect ( editor . renderedLines . find ( " .line:last " ) . text ( ) ) . toBe buffer . lineForRow ( 6 )
2012-04-04 03:12:04 +04:00
2012-07-03 21:12:54 +04:00
describe " when the last line is removed when the editor is scrolled to the bottom " , ->
it " reduces the editor ' s scrollTop (due to the reduced total scroll height) and renders the correct screen lines " , ->
editor . setCursorScreenPosition ( [ Infinity , Infinity ] )
editor . insertText ( ' \n \n \n ' )
editor . scrollToBottom ( )
expect ( buffer . getLineCount ( ) ) . toBe 16
initialScrollTop = editor . scrollTop ( )
expect ( editor . firstRenderedScreenRow ) . toBe 9
expect ( editor . lastRenderedScreenRow ) . toBe 15
editor . backspace ( )
expect ( editor . scrollTop ( ) ) . toBeLessThan initialScrollTop
expect ( editor . firstRenderedScreenRow ) . toBe 9
expect ( editor . lastRenderedScreenRow ) . toBe 14
expect ( editor . find ( ' .line ' ) . length ) . toBe 6
editor . backspace ( )
expect ( editor . firstRenderedScreenRow ) . toBe 9
expect ( editor . lastRenderedScreenRow ) . toBe 13
expect ( editor . find ( ' .line ' ) . length ) . toBe 5
editor . backspace ( )
expect ( editor . firstRenderedScreenRow ) . toBe 6
expect ( editor . lastRenderedScreenRow ) . toBe 12
expect ( editor . find ( ' .line ' ) . length ) . toBe 7
2012-06-13 01:59:55 +04:00
describe " when folding leaves less then a screen worth of text (regression) " , ->
it " renders lines properly " , ->
editor.lineOverdraw = 1
editor . attachToDom ( heightInLines: 5 )
2012-07-30 21:25:53 +04:00
editor . activeEditSession . foldBufferRow ( 4 )
editor . activeEditSession . foldBufferRow ( 0 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 1
expect ( editor . renderedLines . find ( ' .line ' ) . text ( ) ) . toBe buffer . lineForRow ( 0 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when autoscrolling at the end of the document " , ->
it " renders lines properly " , ->
2012-07-18 22:19:25 +04:00
editor . edit ( rootView . project . buildEditSessionForPath ( ' two-hundred.txt ' ) )
2012-06-13 01:59:55 +04:00
editor . attachToDom ( heightInLines: 5.5 )
2012-06-20 04:55:51 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
editor . moveCursorToBottom ( )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
2012-04-04 03:12:04 +04:00
2012-08-02 03:04:33 +04:00
describe " when line has a character that could push it to be too tall (regression) " , ->
it " does renders the line at a consistent height " , ->
rootView . attachToDom ( )
buffer . insert ( [ 0 , 0 ] , " – " )
expect ( editor . find ( ' .line:eq(0) ' ) . outerHeight ( ) ) . toBe editor . find ( ' .line:eq(1) ' ) . outerHeight ( )
2012-06-13 01:59:55 +04:00
describe " .spliceLineElements(startRow, rowCount, lineElements) " , ->
elements = null
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
beforeEach ->
editor . attachToDom ( )
elements = $$ ->
@ div " A " , class : ' line '
@ div " B " , class : ' line '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the start row is 0 " , ->
describe " when the row count is 0 " , ->
it " inserts the given elements before the first row " , ->
editor . spliceLineElements 0 , 0 , elements
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(0) ' ) . text ( ) ) . toBe ' A '
expect ( editor . renderedLines . find ( ' .line:eq(1) ' ) . text ( ) ) . toBe ' B '
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . text ( ) ) . toBe ' var quicksort = function () { '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the row count is > 0 " , ->
it " replaces the initial rows with the given elements " , ->
editor . spliceLineElements 0 , 2 , elements
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(0) ' ) . text ( ) ) . toBe ' A '
expect ( editor . renderedLines . find ( ' .line:eq(1) ' ) . text ( ) ) . toBe ' B '
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . text ( ) ) . toBe ' if (items.length <= 1) return items; '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the start row is less than the last row " , ->
describe " when the row count is 0 " , ->
it " inserts the elements at the specified location " , ->
editor . spliceLineElements 2 , 0 , elements
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . text ( ) ) . toBe ' A '
expect ( editor . renderedLines . find ( ' .line:eq(3) ' ) . text ( ) ) . toBe ' B '
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toBe ' if (items.length <= 1) return items; '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the row count is > 0 " , ->
it " replaces the elements at the specified location " , ->
editor . spliceLineElements 2 , 2 , elements
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(2) ' ) . text ( ) ) . toBe ' A '
expect ( editor . renderedLines . find ( ' .line:eq(3) ' ) . text ( ) ) . toBe ' B '
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toBe ' while(items.length > 0) { '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when the start row is the last row " , ->
it " appends the elements to the end of the lines " , ->
editor . spliceLineElements 13 , 0 , elements
2012-06-13 01:20:15 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(12) ' ) . text ( ) ) . toBe ' }; '
expect ( editor . renderedLines . find ( ' .line:eq(13) ' ) . text ( ) ) . toBe ' A '
expect ( editor . renderedLines . find ( ' .line:eq(14) ' ) . text ( ) ) . toBe ' B '
expect ( editor . renderedLines . find ( ' .line:eq(15) ' ) ) . not . toExist ( )
2012-06-13 01:20:15 +04:00
2012-06-13 01:59:55 +04:00
describe " gutter rendering " , ->
beforeEach ->
editor . attachToDom ( heightInLines: 5.5 )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
it " creates a line number element for each visible line, plus overdraw " , ->
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toBe 8
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe " 1 "
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe " 8 "
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
# here we don't scroll far enough to trigger additional rendering
editor . scrollTop ( editor . lineHeight * 1.5 )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 8
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe " 1 "
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe " 8 "
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollTop ( editor . lineHeight * 3.5 )
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe " 2 "
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe " 11 "
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " width " , ->
it " sets the width based on last line number " , ->
expect ( editor . gutter . lineNumbers . outerWidth ( ) ) . toBe editor . charWidth * 2
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
it " updates the width when total number of lines gains a digit " , ->
oneHundredLines = [ 0 . . 100 ] . join ( " \n " )
editor . insertText ( oneHundredLines )
expect ( editor . gutter . lineNumbers . outerWidth ( ) ) . toBe editor . charWidth * 3
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
describe " when lines are inserted " , ->
it " re-renders the correct line number range in the gutter " , ->
spyOn ( editor , ' scrollTo ' )
editor . scrollTop ( 3 * editor . lineHeight )
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe ' 2 '
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 11 '
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
buffer . insert ( [ 6 , 0 ] , ' \n ' )
2012-04-04 03:12:04 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe ' 2 '
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe ' 11 '
2012-05-10 05:19:54 +04:00
2012-06-13 01:59:55 +04:00
describe " when the insertion of lines causes the editor to scroll " , ->
it " renders line numbers correctly " , ->
oneHundredLines = [ 0 . . 100 ] . join ( " \n " )
editor . insertText ( oneHundredLines )
expect ( editor . gutter . lineNumbers . find ( ' .line-number ' ) . length ) . toBe 6 + editor . lineOverdraw * 2
2012-02-01 06:28:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when wrapping is on " , ->
it " renders a • instead of line number for wrapped portions of lines " , ->
editor . setSoftWrapColumn ( 50 )
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toEqual ( 8 )
expect ( editor . gutter . find ( ' .line-number:eq(3) ' ) . text ( ) ) . toBe ' 4 '
expect ( editor . gutter . find ( ' .line-number:eq(4) ' ) . text ( ) ) . toBe ' • '
expect ( editor . gutter . find ( ' .line-number:eq(5) ' ) . text ( ) ) . toBe ' 5 '
2012-02-01 06:28:25 +04:00
2012-06-13 01:59:55 +04:00
describe " when there are folds " , ->
it " skips line numbers covered by the fold and updates them when the fold changes " , ->
editor . createFold ( 3 , 5 )
expect ( editor . gutter . find ( ' .line-number:eq(3) ' ) . text ( ) ) . toBe ' 4 '
expect ( editor . gutter . find ( ' .line-number:eq(4) ' ) . text ( ) ) . toBe ' 7 '
2012-02-01 06:28:25 +04:00
2012-06-13 01:59:55 +04:00
buffer . insert ( [ 4 , 0 ] , " \n \n " )
expect ( editor . gutter . find ( ' .line-number:eq(3) ' ) . text ( ) ) . toBe ' 4 '
expect ( editor . gutter . find ( ' .line-number:eq(4) ' ) . text ( ) ) . toBe ' 9 '
2012-01-25 03:27:05 +04:00
2012-06-13 01:59:55 +04:00
buffer . delete ( [ [ 3 , 0 ] , [ 6 , 0 ] ] )
expect ( editor . gutter . find ( ' .line-number:eq(3) ' ) . text ( ) ) . toBe ' 4 '
expect ( editor . gutter . find ( ' .line-number:eq(4) ' ) . text ( ) ) . toBe ' 6 '
2012-01-26 01:36:32 +04:00
2012-06-13 01:59:55 +04:00
it " redraws gutter numbers when lines are unfolded " , ->
setEditorHeightInLines ( editor , 20 )
fold = editor . createFold ( 2 , 12 )
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toBe 3
2012-01-26 01:36:32 +04:00
2012-06-13 01:59:55 +04:00
fold . destroy ( )
expect ( editor . gutter . find ( ' .line-number ' ) . length ) . toBe 13
2012-01-26 01:36:32 +04:00
2012-06-13 01:59:55 +04:00
describe " when the scrollView is scrolled to the right " , ->
it " adds a drop shadow to the gutter " , ->
editor . attachToDom ( )
editor . width ( 100 )
2012-03-14 05:20:40 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter ) . not . toHaveClass ( ' drop-shadow ' )
2012-03-14 05:20:40 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollView . scrollLeft ( 10 )
editor . scrollView . trigger ( ' scroll ' )
2012-03-14 05:20:40 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter ) . toHaveClass ( ' drop-shadow ' )
2012-01-26 01:36:32 +04:00
2012-06-13 01:59:55 +04:00
editor . scrollView . scrollLeft ( 0 )
editor . scrollView . trigger ( ' scroll ' )
2012-03-19 19:04:39 +04:00
2012-06-13 01:59:55 +04:00
expect ( editor . gutter ) . not . toHaveClass ( ' drop-shadow ' )
describe " when the editor is scrolled vertically " , ->
it " adjusts the padding-top to account for non-rendered line numbers " , ->
editor . scrollTop ( editor . lineHeight * 3.5 )
expect ( editor . gutter . lineNumbers . css ( ' padding-top ' ) ) . toBe " #{ editor . lineHeight * 1 } px "
expect ( editor . gutter . lineNumbers . css ( ' padding-bottom ' ) ) . toBe " #{ editor . lineHeight * 2 } px "
expect ( editor . renderedLines . find ( ' .line ' ) . length ) . toBe 10
expect ( editor . gutter . find ( ' .line-number:first ' ) . text ( ) ) . toBe " 2 "
expect ( editor . gutter . find ( ' .line-number:last ' ) . text ( ) ) . toBe " 11 "
2012-03-19 19:04:39 +04:00
2012-06-13 01:59:55 +04:00
describe " folding " , ->
2012-05-10 05:19:54 +04:00
beforeEach ->
2012-07-18 22:19:25 +04:00
editSession = rootView . project . buildEditSessionForPath ( ' two-hundred.txt ' )
2012-06-20 04:03:45 +04:00
buffer = editSession . buffer
editor . edit ( editSession )
2012-05-10 05:19:54 +04:00
editor . attachToDom ( )
2012-02-24 22:30:32 +04:00
describe " when a fold-selection event is triggered " , ->
2012-05-19 05:22:56 +04:00
it " folds the lines covered by the selection into a single line with a fold class " , ->
2012-03-23 02:08:20 +04:00
editor . getSelection ( ) . setBufferRange ( new Range ( [ 4 , 29 ] , [ 7 , 4 ] ) )
2012-02-24 22:30:32 +04:00
editor . trigger ' fold-selection '
2012-02-29 06:46:41 +04:00
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) ) . toHaveClass ( ' fold ' )
expect ( editor . renderedLines . find ( ' .line:eq(5) ' ) . text ( ) ) . toBe ' 8 '
2012-02-29 06:46:41 +04:00
2012-03-23 02:08:20 +04:00
expect ( editor . getSelection ( ) . isEmpty ( ) ) . toBeTruthy ( )
2012-05-19 02:15:44 +04:00
expect ( editor . getCursorScreenPosition ( ) ) . toEqual [ 5 , 0 ]
2012-02-24 22:30:32 +04:00
2012-05-22 04:55:58 +04:00
describe " when a fold placeholder line is clicked " , ->
2012-05-22 05:35:51 +04:00
it " removes the associated fold and places the cursor at its beginning " , ->
2012-07-30 20:41:59 +04:00
editor . setCursorBufferPosition ( [ 3 , 0 ] )
editor . trigger ' fold-current-row '
2012-02-25 09:08:34 +04:00
2012-05-22 04:55:58 +04:00
editor . find ( ' .fold.line ' ) . mousedown ( )
2012-02-25 09:08:34 +04:00
2012-05-22 04:55:58 +04:00
expect ( editor . find ( ' .fold ' ) ) . not . toExist ( )
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toMatch / 4 - + /
expect ( editor . renderedLines . find ( ' .line:eq(5) ' ) . text ( ) ) . toMatch / 5 /
2012-03-08 00:43:29 +04:00
2012-05-22 04:55:58 +04:00
expect ( editor . getCursorBufferPosition ( ) ) . toEqual [ 3 , 0 ]
2012-02-27 22:22:20 +04:00
2012-07-30 20:41:59 +04:00
describe " when the unfold-current-row event is triggered when the cursor is on a fold placeholder line " , ->
2012-02-29 06:53:02 +04:00
it " removes the associated fold and places the cursor at its beginning " , ->
2012-07-30 20:41:59 +04:00
editor . setCursorBufferPosition ( [ 3 , 0 ] )
editor . trigger ' fold-current-row '
2012-02-29 06:46:41 +04:00
2012-05-22 20:38:14 +04:00
editor . setCursorBufferPosition ( [ 3 , 0 ] )
2012-07-30 20:41:59 +04:00
editor . trigger ' unfold-current-row '
2012-05-22 20:38:14 +04:00
expect ( editor . find ( ' .fold ' ) ) . not . toExist ( )
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . find ( ' .line:eq(4) ' ) . text ( ) ) . toMatch / 4 - + /
expect ( editor . renderedLines . find ( ' .line:eq(5) ' ) . text ( ) ) . toMatch / 5 /
2012-05-22 20:38:14 +04:00
expect ( editor . getCursorBufferPosition ( ) ) . toEqual [ 3 , 0 ]
2012-05-25 03:39:14 +04:00
describe " when a selection starts/stops intersecting a fold " , ->
2012-05-25 23:35:32 +04:00
it " adds/removes the ' selected ' class to the fold ' s line element and hides the cursor if it is on the fold line " , ->
2012-05-25 03:39:14 +04:00
editor . createFold ( 2 , 4 )
2012-07-13 04:57:12 +04:00
editor . setSelectedBufferRange ( [ [ 1 , 0 ] , [ 2 , 0 ] ] , preserveFolds: true , reverse: true )
2012-05-25 03:39:14 +04:00
expect ( editor . lineElementForScreenRow ( 2 ) ) . toMatchSelector ( ' .fold.selected ' )
2012-07-13 04:57:12 +04:00
editor . setSelectedBufferRange ( [ [ 1 , 0 ] , [ 1 , 1 ] ] , preserveFolds: true )
2012-05-25 03:39:14 +04:00
expect ( editor . lineElementForScreenRow ( 2 ) ) . not . toMatchSelector ( ' .fold.selected ' )
2012-07-13 04:57:12 +04:00
editor . setSelectedBufferRange ( [ [ 1 , 0 ] , [ 5 , 0 ] ] , preserveFolds: true )
2012-05-25 03:39:14 +04:00
expect ( editor . lineElementForScreenRow ( 2 ) ) . toMatchSelector ( ' .fold.selected ' )
editor . setCursorScreenPosition ( [ 3 , 0 ] )
expect ( editor . lineElementForScreenRow ( 2 ) ) . not . toMatchSelector ( ' .fold.selected ' )
editor . setCursorScreenPosition ( [ 2 , 0 ] )
expect ( editor . lineElementForScreenRow ( 2 ) ) . toMatchSelector ( ' .fold.selected ' )
2012-05-25 23:35:32 +04:00
expect ( editor . find ( ' .cursor ' ) . css ( ' display ' ) ) . toBe ' none '
editor . setCursorScreenPosition ( [ 3 , 0 ] )
expect ( editor . find ( ' .cursor ' ) . css ( ' display ' ) ) . toBe ' block '
2012-05-25 03:39:14 +04:00
describe " when a selected fold is scrolled into view (and the fold line was not previously rendered) " , ->
it " renders the fold ' s line element with the ' selected ' class " , ->
setEditorHeightInLines ( editor , 5 )
2012-06-05 21:09:40 +04:00
editor . renderLines ( ) # re-render lines so certain lines are not rendered
2012-02-29 06:46:41 +04:00
2012-05-25 03:39:14 +04:00
editor . createFold ( 2 , 4 )
2012-07-13 04:57:12 +04:00
editor . setSelectedBufferRange ( [ [ 1 , 0 ] , [ 5 , 0 ] ] , preserveFolds: true )
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . find ( ' .fold.selected ' ) ) . toExist ( )
2012-02-29 06:46:41 +04:00
2012-05-25 03:39:14 +04:00
editor . scrollToBottom ( )
2012-06-05 04:53:58 +04:00
expect ( editor . renderedLines . find ( ' .fold.selected ' ) ) . not . toExist ( )
2012-03-08 00:43:29 +04:00
2012-05-25 03:39:14 +04:00
editor . scrollTop ( 0 )
expect ( editor . lineElementForScreenRow ( 2 ) ) . toMatchSelector ( ' .fold.selected ' )
2012-06-28 22:57:52 +04:00
describe " .getOpenBufferPaths() " , ->
it " returns the paths of all non-anonymous buffers with edit sessions on this editor " , ->
2012-07-18 22:19:25 +04:00
editor . edit ( project . buildEditSessionForPath ( ' sample.txt ' ) )
editor . edit ( project . buildEditSessionForPath ( ' two-hundred.txt ' ) )
editor . edit ( project . buildEditSessionForPath ( ) )
2012-06-28 22:57:52 +04:00
paths = editor . getOpenBufferPaths ( ) . map (path) -> project . relativize ( path )
expect ( paths ) . toEqual = [ ' sample.js ' , ' sample.txt ' , ' two-hundred.txt ' ]