mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Bring React into the tree, and add linting and bundling framework for the JS etc.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -37,3 +37,4 @@ runtime/ui_BrowserWindow.h
|
|||||||
web/config_local.py
|
web/config_local.py
|
||||||
web/regression/test_config.json
|
web/regression/test_config.json
|
||||||
node_modules/
|
node_modules/
|
||||||
|
web/pgAdmin/static/js/generated
|
||||||
|
|||||||
@@ -164,6 +164,12 @@ REM Main function Ends
|
|||||||
CD "%WD%\web"
|
CD "%WD%\web"
|
||||||
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
ECHO Install Javascript dependencies
|
||||||
|
yarn install
|
||||||
|
ECHO Bundle all Javascript
|
||||||
|
yarn run bundle
|
||||||
|
|
||||||
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|||||||
6
Make.bat
6
Make.bat
@@ -238,6 +238,12 @@ REM Main function Ends
|
|||||||
CD "%WD%\web"
|
CD "%WD%\web"
|
||||||
|
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
ECHO Install Javascript dependencies
|
||||||
|
yarn install
|
||||||
|
ECHO Bundle all Javascript
|
||||||
|
yarn run bundle
|
||||||
|
|
||||||
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul
|
||||||
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,11 @@ _complete_bundle() {
|
|||||||
# run complete-bundle to copy the dependent libraries and frameworks and fix the rpaths
|
# run complete-bundle to copy the dependent libraries and frameworks and fix the rpaths
|
||||||
./complete-bundle.sh "$BUILDROOT/$APP_BUNDLE_NAME" || { echo complete-bundle.sh failed; exit 1; }
|
./complete-bundle.sh "$BUILDROOT/$APP_BUNDLE_NAME" || { echo complete-bundle.sh failed; exit 1; }
|
||||||
|
|
||||||
|
pushd $SOURCEDIR/web
|
||||||
|
yarn install
|
||||||
|
yarn run bundle
|
||||||
|
popd
|
||||||
|
|
||||||
# copy the web directory to the bundle as it is required by runtime
|
# copy the web directory to the bundle as it is required by runtime
|
||||||
cp -r $SOURCEDIR/web "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/" || exit 1
|
cp -r $SOURCEDIR/web "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/" || exit 1
|
||||||
cd "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/web"
|
cd "$BUILDROOT/$APP_BUNDLE_NAME/Contents/Resources/web"
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ do
|
|||||||
tar cf - $FILE | (cd ../pip-build/pgadmin4; tar xf -)
|
tar cf - $FILE | (cd ../pip-build/pgadmin4; tar xf -)
|
||||||
done
|
done
|
||||||
|
|
||||||
|
yarn install
|
||||||
|
yarn run bundle
|
||||||
|
|
||||||
|
for FILE in `ls -d pgAdmin/static/js/generated/*`
|
||||||
|
do
|
||||||
|
echo Adding $FILE
|
||||||
|
tar cf - $FILE | (cd ../pip-build/pgadmin4; tar xf -)
|
||||||
|
done
|
||||||
|
|
||||||
cd ../docs
|
cd ../docs
|
||||||
for FILE in `git ls-files`
|
for FILE in `git ls-files`
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -69,6 +69,17 @@ do
|
|||||||
tar cf - $FILE | (cd src-build/$TARBALL_NAME; tar xf -)
|
tar cf - $FILE | (cd src-build/$TARBALL_NAME; tar xf -)
|
||||||
done
|
done
|
||||||
|
|
||||||
|
pushd web
|
||||||
|
yarn install
|
||||||
|
yarn run bundle
|
||||||
|
|
||||||
|
for FILE in `ls -d pgAdmin/static/js/generated/*`
|
||||||
|
do
|
||||||
|
echo Adding $FILE
|
||||||
|
tar cf - $FILE | (cd ../src-build/$TARBALL_NAME/web; tar xf -)
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
|
||||||
# Create the tarball
|
# Create the tarball
|
||||||
echo Creating tarball...
|
echo Creating tarball...
|
||||||
cd src-build
|
cd src-build
|
||||||
|
|||||||
@@ -1,28 +1,23 @@
|
|||||||
// Karma configuration
|
// Karma configuration
|
||||||
// Generated on Wed Mar 01 2017 14:19:28 GMT-0500 (EST)
|
// Generated on Wed Mar 01 2017 14:19:28 GMT-0500 (EST)
|
||||||
|
const webpackConfig = require('./webpack.test.config.js');
|
||||||
|
|
||||||
module.exports = function(config) {
|
module.exports = function (config) {
|
||||||
config.set({
|
config.set({
|
||||||
|
frameworks: ['jasmine'],
|
||||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
plugins: [
|
||||||
basePath: '',
|
'karma-webpack',
|
||||||
|
'karma-phantomjs-launcher',
|
||||||
|
'karma-jasmine',
|
||||||
// frameworks to use
|
'karma-jasmine-html-reporter',
|
||||||
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
],
|
||||||
frameworks: ['jasmine', 'requirejs'],
|
files: [
|
||||||
|
{pattern: 'pgadmin/static/**/*.js', included: false},
|
||||||
|
{pattern: 'pgadmin/static/vendor/**/*.js', included: false},
|
||||||
// list of files / patterns to load in the browser
|
{pattern: 'pgadmin/browser/static/js/**/*.js', included: false},
|
||||||
files: [
|
'regression/javascript/**/*.jsx',
|
||||||
'regression/javascript/test-main.js',
|
'regression/javascript/**/*.js',
|
||||||
{pattern: 'regression/javascript/**/*.js', included: false},
|
|
||||||
{pattern: 'pgadmin/static/vendor/**/*.js', included: false},
|
|
||||||
{pattern: 'pgadmin/static/js/**/*.js', included: false},
|
|
||||||
{pattern: 'pgadmin/browser/static/js/**/*.js', included: false},
|
|
||||||
{pattern: 'pgadmin/static/img/*.png', included: false}
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
// list of files to exclude
|
// list of files to exclude
|
||||||
exclude: [
|
exclude: [
|
||||||
@@ -30,34 +25,30 @@ module.exports = function(config) {
|
|||||||
'pgadmin/static/vendor/**/*[Ss]pec.js'
|
'pgadmin/static/vendor/**/*[Ss]pec.js'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
||||||
// preprocess matching files before serving them to the browser
|
// preprocess matching files before serving them to the browser
|
||||||
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
|
'regression/javascript/**/*.js': ['webpack'],
|
||||||
|
// 'regression/javascript/**/*.jsx': ['webpack'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
webpack: webpackConfig,
|
||||||
|
webpackMiddleware: {
|
||||||
|
stats: 'errors-only',
|
||||||
|
},
|
||||||
|
|
||||||
// test results reporter to use
|
|
||||||
// possible values: 'dots', 'progress'
|
|
||||||
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
|
||||||
reporters: ['progress'],
|
|
||||||
|
|
||||||
|
|
||||||
// web server port
|
|
||||||
port: 9876,
|
port: 9876,
|
||||||
|
|
||||||
|
|
||||||
// enable / disable colors in the output (reporters and logs)
|
// enable / disable colors in the output (reporters and logs)
|
||||||
colors: true,
|
colors: true,
|
||||||
|
|
||||||
|
|
||||||
// level of logging
|
// level of logging
|
||||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||||
logLevel: config.LOG_INFO,
|
logLevel: config.LOG_WARN,
|
||||||
|
|
||||||
|
|
||||||
// enable / disable watching file and executing tests whenever any file changes
|
// enable / disable watching file and executing tests whenever any file changes
|
||||||
autoWatch: false,
|
autoWatch: true,
|
||||||
|
|
||||||
|
|
||||||
// start these browsers
|
// start these browsers
|
||||||
@@ -67,10 +58,10 @@ module.exports = function(config) {
|
|||||||
|
|
||||||
// Continuous Integration mode
|
// Continuous Integration mode
|
||||||
// if true, Karma captures browsers, runs the tests and exits
|
// if true, Karma captures browsers, runs the tests and exits
|
||||||
singleRun: true,
|
singleRun: false,
|
||||||
|
|
||||||
// Concurrency level
|
// Concurrency level
|
||||||
// how many browser should be started simultaneous
|
// how many browser should be started simultaneous
|
||||||
concurrency: Infinity
|
concurrency: Infinity
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,10 +1,43 @@
|
|||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jasmine-core": "^2.5.2",
|
"babel-core": "~6.24.0",
|
||||||
"karma": "^1.5.0",
|
"babel-loader": "~6.4.1",
|
||||||
"karma-jasmine": "^1.1.0",
|
"babel-preset-es2015": "~6.24.0",
|
||||||
"karma-phantomjs-launcher": "^1.0.2",
|
"babel-preset-react": "~6.23.0",
|
||||||
"karma-requirejs": "^1.1.0",
|
"enzyme": "~2.8.2",
|
||||||
"requirejs": "^2.3.3"
|
"jasmine-core": "~2.5.2",
|
||||||
|
"karma": "~1.5.0",
|
||||||
|
"karma-babel-preprocessor": "^6.0.1",
|
||||||
|
"karma-browserify": "~5.1.1",
|
||||||
|
"karma-jasmine": "~1.1.0",
|
||||||
|
"karma-jasmine-html-reporter": "~0.2.2",
|
||||||
|
"karma-phantomjs-launcher": "~1.0.2",
|
||||||
|
"karma-requirejs": "~1.1.0",
|
||||||
|
"karma-sourcemap-loader": "~0.3.7",
|
||||||
|
"karma-webpack": "~2.0.3",
|
||||||
|
"react-addons-test-utils": "~15.4.2",
|
||||||
|
"webpack": "~2.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.16.1",
|
||||||
|
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
|
||||||
|
"babel-polyfill": "^6.23.0",
|
||||||
|
"babel-preset-es2015-without-strict": "~0.0.4",
|
||||||
|
"babelify": "~7.3.0",
|
||||||
|
"browserify": "~14.1.0",
|
||||||
|
"exports-loader": "~0.6.4",
|
||||||
|
"imports-loader": "git+https://github.com/webpack-contrib/imports-loader.git#44d6f48463b256a17c1ba6fd9b5cc1449b4e379d",
|
||||||
|
"react": "~15.4.2",
|
||||||
|
"react-dom": "~15.4.2",
|
||||||
|
"requirejs": "~2.3.3",
|
||||||
|
"underscore": "~1.8.3",
|
||||||
|
"watchify": "~3.9.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"bundle": "yarn run webpack -- --optimize-minimize --config webpack.config.js",
|
||||||
|
"test:karma-once": "yarn run karma start -- --single-run",
|
||||||
|
"test:karma": "yarn run karma start",
|
||||||
|
"test:feature": "yarn run bundle && python regression/runtests.py --pkg feature_tests",
|
||||||
|
"test": "yarn run test:karma-once && yarn run bundle && python regression/runtests.py"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,17 +22,36 @@ if sys.path[0] != root:
|
|||||||
|
|
||||||
import config
|
import config
|
||||||
from pgadmin import create_app
|
from pgadmin import create_app
|
||||||
|
from pgadmin.utils import u, fs_encoding, file_quote
|
||||||
|
|
||||||
|
if config.DEBUG:
|
||||||
|
from pgadmin.utils.javascript.javascript_bundler import JavascriptBundler, JsState
|
||||||
|
|
||||||
# Get the config database schema version. We store this in pgadmin.model
|
# Get the config database schema version. We store this in pgadmin.model
|
||||||
# as it turns out that putting it in the config files isn't a great idea
|
# as it turns out that putting it in the config files isn't a great idea
|
||||||
from pgadmin.model import SCHEMA_VERSION
|
from pgadmin.model import SCHEMA_VERSION
|
||||||
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
config.SETTINGS_SCHEMA_VERSION = SCHEMA_VERSION
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Sanity checks
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
# Check if the database exists. If it does not, create it.
|
||||||
|
if not os.path.isfile(config.SQLITE_PATH):
|
||||||
|
setupfile = os.path.join(
|
||||||
|
os.path.dirname(os.path.realpath(u(__file__, fs_encoding))), u'setup.py'
|
||||||
|
)
|
||||||
|
exec(open(file_quote(setupfile), 'r').read())
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Server starup
|
# Server startup
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
# Build Javascript files
|
||||||
|
if config.DEBUG:
|
||||||
|
javascriptBundler = JavascriptBundler()
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
|
||||||
# Create the app!
|
# Create the app!
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
@@ -41,6 +60,13 @@ if config.DEBUG:
|
|||||||
else:
|
else:
|
||||||
app.debug = False
|
app.debug = False
|
||||||
|
|
||||||
|
# respond to JS
|
||||||
|
if config.DEBUG:
|
||||||
|
if javascriptBundler.report() == JsState.NONE:
|
||||||
|
app.logger.error("Unable to generate javascript")
|
||||||
|
app.logger.error("To run the app ensure that yarn install command runs successfully")
|
||||||
|
raise Exception("No generated javascript, aborting")
|
||||||
|
|
||||||
# Start the web server. The port number should have already been set by the
|
# Start the web server. The port number should have already been set by the
|
||||||
# runtime if we're running in desktop mode, otherwise we'll just use the
|
# runtime if we're running in desktop mode, otherwise we'll just use the
|
||||||
# Flask default.
|
# Flask default.
|
||||||
|
|||||||
8
web/pgadmin/static/jsx/components.jsx
Normal file
8
web/pgadmin/static/jsx/components.jsx
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {render} from 'react-dom';
|
||||||
|
|
||||||
|
export {
|
||||||
|
render,
|
||||||
|
React,
|
||||||
|
};
|
||||||
8
web/pgadmin/utils/javascript/__init__.py
Normal file
8
web/pgadmin/utils/javascript/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
62
web/pgadmin/utils/javascript/javascript_bundler.py
Normal file
62
web/pgadmin/utils/javascript/javascript_bundler.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
import os
|
||||||
|
from contextlib import contextmanager
|
||||||
|
from subprocess import call
|
||||||
|
from pgadmin.utils import u, fs_encoding, file_quote
|
||||||
|
|
||||||
|
|
||||||
|
# enum-like for tracking whether we have
|
||||||
|
class JsState:
|
||||||
|
NONE = 0
|
||||||
|
OLD = 1
|
||||||
|
NEW = 2
|
||||||
|
|
||||||
|
|
||||||
|
class JavascriptBundler:
|
||||||
|
"""Builds Javascript bundle files by delegating to webpack"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.jsState = JsState.NONE
|
||||||
|
|
||||||
|
def bundle(self):
|
||||||
|
try:
|
||||||
|
try_building_js()
|
||||||
|
self.jsState = JsState.NEW
|
||||||
|
except OSError:
|
||||||
|
webdir_path()
|
||||||
|
generatedJavascriptDir = os.path.join(webdir_path(), 'pgadmin', 'static', 'js', 'generated')
|
||||||
|
if os.path.exists(generatedJavascriptDir) and os.listdir(generatedJavascriptDir):
|
||||||
|
self.jsState = JsState.OLD
|
||||||
|
else:
|
||||||
|
self.jsState = JsState.NONE
|
||||||
|
|
||||||
|
def report(self):
|
||||||
|
return self.jsState
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def pushd(new_dir):
|
||||||
|
previous_dir = os.getcwd()
|
||||||
|
os.chdir(new_dir)
|
||||||
|
yield
|
||||||
|
os.chdir(previous_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def webdir_path():
|
||||||
|
dirname = os.path.dirname
|
||||||
|
thisPath = os.path.realpath(u(__file__, fs_encoding))
|
||||||
|
return dirname(dirname(dirname(dirname(thisPath))))
|
||||||
|
|
||||||
|
|
||||||
|
def try_building_js():
|
||||||
|
with pushd(webdir_path()):
|
||||||
|
if call(['yarn', 'run', 'bundle']) != 0:
|
||||||
|
raise OSError('Error executing bundling the application')
|
||||||
8
web/pgadmin/utils/javascript/tests/__init__.py
Normal file
8
web/pgadmin/utils/javascript/tests/__init__.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
###########################################################################
|
||||||
117
web/pgadmin/utils/javascript/tests/test_javascript_bundler.py
Normal file
117
web/pgadmin/utils/javascript/tests/test_javascript_bundler.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
##########################################################################
|
||||||
|
#
|
||||||
|
# pgAdmin 4 - PostgreSQL Tools
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
# This software is released under the PostgreSQL Licence
|
||||||
|
#
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from pgadmin.utils.route import BaseTestGenerator
|
||||||
|
if sys.version_info < (3, 3):
|
||||||
|
import mock
|
||||||
|
else:
|
||||||
|
import unittest.mock as mock
|
||||||
|
|
||||||
|
|
||||||
|
class JavascriptBundlerTestCase(BaseTestGenerator):
|
||||||
|
"""This tests that the javascript bundler tool causes the application to bundle,
|
||||||
|
and can be invoked before and after app start correctly"""
|
||||||
|
|
||||||
|
scenarios = [('scenario name: JavascriptBundlerTestCase', dict())]
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.mockSubprocess = mock.Mock()
|
||||||
|
self.mockOs = mock.Mock()
|
||||||
|
sys.modules['subprocess'] = self.mockSubprocess
|
||||||
|
sys.modules['os'] = self.mockOs
|
||||||
|
|
||||||
|
def runTest(self):
|
||||||
|
from pgadmin.utils.javascript.javascript_bundler import JavascriptBundler
|
||||||
|
from pgadmin.utils.javascript.javascript_bundler import JsState
|
||||||
|
self.JavascriptBundler = JavascriptBundler
|
||||||
|
self.JsState = JsState
|
||||||
|
|
||||||
|
self._bundling_succeeds()
|
||||||
|
self.resetTestState()
|
||||||
|
self._bundling_fails_and_there_is_no_existing_bundle()
|
||||||
|
self.resetTestState()
|
||||||
|
self._bundling_fails_when_bundling_returns_nonzero()
|
||||||
|
self.resetTestState()
|
||||||
|
self._bundling_fails_and_there_is_no_existing_bundle_directory()
|
||||||
|
self.resetTestState()
|
||||||
|
self._bundling_fails_but_there_was_existing_bundle()
|
||||||
|
self.resetTestState()
|
||||||
|
|
||||||
|
def resetTestState(self):
|
||||||
|
self.mockSubprocess.reset_mock()
|
||||||
|
self.mockSubprocess.call.side_effect = None
|
||||||
|
self.mockOs.reset_mock()
|
||||||
|
self.mockOs.listdir.side_effect = None
|
||||||
|
self.mockOs.path.exists.side_effect = None
|
||||||
|
|
||||||
|
def _bundling_succeeds(self):
|
||||||
|
javascriptBundler = self.JavascriptBundler()
|
||||||
|
self.assertEqual(len(self.mockSubprocess.method_calls), 0)
|
||||||
|
self.mockSubprocess.call.return_value = 0
|
||||||
|
|
||||||
|
self.mockOs.listdir.return_value = [u'history.js', u'reactComponents.js']
|
||||||
|
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
self.mockSubprocess.call.assert_called_once_with(['yarn', 'run', 'bundle'])
|
||||||
|
|
||||||
|
reportedState = javascriptBundler.report()
|
||||||
|
expectedState = self.JsState.NEW
|
||||||
|
self.assertEqual(reportedState, expectedState)
|
||||||
|
|
||||||
|
def _bundling_fails_when_bundling_returns_nonzero(self):
|
||||||
|
javascriptBundler = self.JavascriptBundler()
|
||||||
|
self.assertEqual(len(self.mockSubprocess.method_calls), 0)
|
||||||
|
self.mockOs.listdir.return_value = []
|
||||||
|
self.mockSubprocess.call.return_value = 99
|
||||||
|
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
|
||||||
|
reportedState = javascriptBundler.report()
|
||||||
|
expectedState = self.JsState.NONE
|
||||||
|
self.assertEqual(reportedState, expectedState)
|
||||||
|
|
||||||
|
def _bundling_fails_and_there_is_no_existing_bundle(self):
|
||||||
|
javascriptBundler = self.JavascriptBundler()
|
||||||
|
self.mockSubprocess.call.side_effect = OSError("mock exception behavior")
|
||||||
|
self.mockOs.path.exists.return_value = True
|
||||||
|
self.mockOs.listdir.return_value = []
|
||||||
|
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
|
||||||
|
reportedState = javascriptBundler.report()
|
||||||
|
expectedState = self.JsState.NONE
|
||||||
|
self.assertEqual(reportedState, expectedState)
|
||||||
|
|
||||||
|
def _bundling_fails_and_there_is_no_existing_bundle_directory(self):
|
||||||
|
javascriptBundler = self.JavascriptBundler()
|
||||||
|
self.mockSubprocess.call.side_effect = OSError("mock exception behavior")
|
||||||
|
self.mockOs.path.exists.return_value = False
|
||||||
|
self.mockOs.listdir.side_effect = OSError("mock exception behavior")
|
||||||
|
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
|
||||||
|
reportedState = javascriptBundler.report()
|
||||||
|
expectedState = self.JsState.NONE
|
||||||
|
self.assertEqual(reportedState, expectedState)
|
||||||
|
|
||||||
|
def _bundling_fails_but_there_was_existing_bundle(self):
|
||||||
|
javascriptBundler = self.JavascriptBundler()
|
||||||
|
self.mockSubprocess.call.side_effect = OSError("mock exception behavior")
|
||||||
|
self.mockOs.path.exists.return_value = True
|
||||||
|
self.mockOs.listdir.return_value = [u'history.js', u'reactComponents.js']
|
||||||
|
|
||||||
|
javascriptBundler.bundle()
|
||||||
|
self.mockSubprocess.call.assert_called_once_with(['yarn', 'run', 'bundle'])
|
||||||
|
|
||||||
|
reportedState = javascriptBundler.report()
|
||||||
|
expectedState = self.JsState.OLD
|
||||||
|
self.assertEqual(reportedState, expectedState)
|
||||||
@@ -177,16 +177,17 @@ Javascript Tests:
|
|||||||
|
|
||||||
sudo port install nodejs7 yarn
|
sudo port install nodejs7 yarn
|
||||||
|
|
||||||
|
- See also the top-level pgadmin/README : Bundling Javascript
|
||||||
|
|
||||||
- Javascript tests must be run from the web directory (since that is where node_modules and karma.conf reside):
|
- Javascript tests must be run from the web directory (since that is where node_modules and karma.conf reside):
|
||||||
|
|
||||||
cd web/
|
cd web/
|
||||||
|
|
||||||
- Install the JS modules required for testing:
|
- Install the JS modules required for testing:
|
||||||
|
|
||||||
yarn
|
yarn install
|
||||||
|
|
||||||
- Now run the tests:
|
- Now run the tests:
|
||||||
|
|
||||||
yarn run karma start --single-run
|
yarn run test:karma
|
||||||
|
yarn run test:karma-once
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define(["browser/menu"
|
define([
|
||||||
], function () {
|
'pgadmin',
|
||||||
describe("MenuItem", function () {
|
'browser/menu',
|
||||||
|
], function (pgAdmin) {
|
||||||
|
describe('MenuItem', function () {
|
||||||
var MenuItem = pgAdmin.Browser.MenuItem;
|
var MenuItem = pgAdmin.Browser.MenuItem;
|
||||||
var menuItem;
|
var menuItem;
|
||||||
|
|
||||||
|
|||||||
@@ -7,45 +7,46 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define(["sources/gettext", "translations"], function (gettext, translations) {
|
import gettext from 'sources/gettext';
|
||||||
describe("translate", function () {
|
import translations from 'translations';
|
||||||
describe("when there is no translation", function () {
|
|
||||||
it("returns the original string", function () {
|
|
||||||
expect(gettext("something to be translated")).toEqual("something to be translated");
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when there are substitutions", function () {
|
|
||||||
it("interpolates a substitution", function () {
|
|
||||||
expect(gettext("translate text for %(person)s", {"person": "Sarah"})).toEqual("translate text for Sarah")
|
|
||||||
});
|
|
||||||
|
|
||||||
it("interpolates multiple substitutions", function () {
|
|
||||||
expect(gettext("translate '%(text)s' for %(person)s",
|
|
||||||
{
|
|
||||||
"text": "constitution",
|
|
||||||
"person": "Sarah"
|
|
||||||
}
|
|
||||||
)).toEqual("translate 'constitution' for Sarah")
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
describe('translate', function () {
|
||||||
|
describe('when there is no translation', function () {
|
||||||
|
it('returns the original string', function () {
|
||||||
|
expect(gettext('something to be translated')).toEqual('something to be translated');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when there is a translation", function () {
|
describe('when there are substitutions', function () {
|
||||||
beforeEach(function () {
|
it('interpolates a substitution', function () {
|
||||||
translations['something to be translated'] = 'etwas zum uebersetzen';
|
expect(gettext('translate text for %(person)s', {'person': 'Sarah'})).toEqual('translate text for Sarah');
|
||||||
translations['another translation for %(person)s'] = 'eine weitere Uebersetzung fuer %(person)s';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns the translation", function () {
|
it('interpolates multiple substitutions', function () {
|
||||||
expect(gettext("something to be translated")).toEqual("etwas zum uebersetzen");
|
expect(gettext('translate \'%(text)s\' for %(person)s',
|
||||||
|
{
|
||||||
|
'text': 'constitution',
|
||||||
|
'person': 'Sarah',
|
||||||
|
}
|
||||||
|
)).toEqual('translate \'constitution\' for Sarah');
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("when there is a substitution", function () {
|
});
|
||||||
it("interpolates the substitution", function () {
|
|
||||||
expect(gettext("another translation for %(person)s", {"person": "Sarah"}))
|
describe('when there is a translation', function () {
|
||||||
.toEqual("eine weitere Uebersetzung fuer Sarah");
|
beforeEach(function () {
|
||||||
});
|
translations['something to be translated'] = 'etwas zum uebersetzen';
|
||||||
|
translations['another translation for %(person)s'] = 'eine weitere Uebersetzung fuer %(person)s';
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the translation', function () {
|
||||||
|
expect(gettext('something to be translated')).toEqual('etwas zum uebersetzen');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when there is a substitution', function () {
|
||||||
|
it('interpolates the substitution', function () {
|
||||||
|
expect(gettext('another translation for %(person)s', {'person': 'Sarah'}))
|
||||||
|
.toEqual('eine weitere Uebersetzung fuer Sarah');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
beforeAll(function () {
|
||||||
|
spyOn(console, 'warn').and.callThrough();
|
||||||
|
spyOn(console, 'error').and.callThrough();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function (done) {
|
||||||
|
setTimeout(function () {
|
||||||
|
expect(console.warn).not.toHaveBeenCalled();
|
||||||
|
expect(console.error).not.toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
@@ -1,419 +1,423 @@
|
|||||||
define(
|
//////////////////////////////////////////////////////////////////////////
|
||||||
["jquery",
|
//
|
||||||
"underscore",
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
"sources/selection/column_selector",
|
//
|
||||||
"sources/selection/active_cell_capture",
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
"sources/selection/grid_selector",
|
// This software is released under the PostgreSQL Licence
|
||||||
'sources/selection/xcell_selection_model',
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
"slickgrid",
|
import $ from 'jquery';
|
||||||
'sources/slickgrid/pgslick.cellrangedecorator',
|
|
||||||
'sources/slickgrid/pgslick.cellrangeselector',
|
|
||||||
"slickgrid/slick.grid",
|
|
||||||
],
|
|
||||||
function ($, _, ColumnSelector, ActiveCellCapture, GridSelector, XCellSelectionModel) {
|
|
||||||
var KEY_RIGHT = 39;
|
|
||||||
var KEY_LEFT = 37;
|
|
||||||
var KEY_UP = 38;
|
|
||||||
var KEY_DOWN = 40;
|
|
||||||
|
|
||||||
var Slick = window.Slick;
|
import Slick from 'slickgrid';
|
||||||
var SlickGrid = Slick.Grid;
|
import 'slickgrid.grid';
|
||||||
|
|
||||||
describe("ColumnSelector", function () {
|
import ColumnSelector from 'sources/selection/column_selector';
|
||||||
var container, data, columns, options;
|
import ActiveCellCapture from 'sources/selection/active_cell_capture';
|
||||||
|
import 'sources/selection/grid_selector';
|
||||||
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
|
import 'sources/slickgrid/pgslick.cellrangedecorator';
|
||||||
|
import 'sources/slickgrid/pgslick.cellrangeselector';
|
||||||
|
|
||||||
|
describe('ColumnSelector', function () {
|
||||||
|
var container, data, columns, options;
|
||||||
|
var SlickGrid = Slick.Grid;
|
||||||
|
var KEY_RIGHT = 39;
|
||||||
|
var KEY_LEFT = 37;
|
||||||
|
var KEY_UP = 38;
|
||||||
|
var KEY_DOWN = 40;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
container = $('<div></div>');
|
||||||
|
container.height(9999);
|
||||||
|
container.width(9999);
|
||||||
|
|
||||||
|
data = [{
|
||||||
|
'some-column-name': 'first value',
|
||||||
|
'second column': 'second value',
|
||||||
|
'third column': 'nonselectable value'
|
||||||
|
}, {
|
||||||
|
'some-column-name': 'row 1 - first value',
|
||||||
|
'second column': 'row 1 - second value',
|
||||||
|
'third column': 'row 1 - nonselectable value'
|
||||||
|
}];
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
{
|
||||||
|
id: 'row-header-column',
|
||||||
|
name: 'row header column name',
|
||||||
|
selectable: false,
|
||||||
|
display_name: 'row header column name',
|
||||||
|
column_type: 'text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
name: 'some-column-name',
|
||||||
|
pos: 0,
|
||||||
|
display_name: 'some-column-name',
|
||||||
|
column_type: 'text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
name: 'second column',
|
||||||
|
pos: 1,
|
||||||
|
display_name: 'second column',
|
||||||
|
column_type: 'json'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'third-column-id',
|
||||||
|
name: 'third column',
|
||||||
|
pos: 2,
|
||||||
|
display_name: 'third column',
|
||||||
|
column_type: 'text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'some-non-selectable-column',
|
||||||
|
selectable: false,
|
||||||
|
pos: 3,
|
||||||
|
display_name: 'some-non-selectable-column',
|
||||||
|
column_type: 'numeric'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays the name of the column', function () {
|
||||||
|
setupGrid(columns);
|
||||||
|
|
||||||
|
expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
|
||||||
|
.toContain('some-column-name');
|
||||||
|
expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
|
||||||
|
.toContain('text');
|
||||||
|
expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
|
||||||
|
.toContain('second column');
|
||||||
|
expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
|
||||||
|
.toContain('json');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves the other attributes of column definitions', function () {
|
||||||
|
var columnSelector = new ColumnSelector();
|
||||||
|
var selectableColumns = columnSelector.getColumnDefinitions(columns);
|
||||||
|
|
||||||
|
expect(selectableColumns[1].id).toBe('1');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with ActiveCellCapture, CellSelectionModel, and GridSelector: selecting columns', function () {
|
||||||
|
var grid, cellSelectionModel;
|
||||||
|
beforeEach(function () {
|
||||||
|
var columnSelector = new ColumnSelector();
|
||||||
|
columns = columnSelector.getColumnDefinitions(columns);
|
||||||
|
data = [];
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
data.push({
|
||||||
|
'some-column-name': 'some-value-' + i,
|
||||||
|
'second column': 'second value ' + i,
|
||||||
|
'third column': 'third value ' + i,
|
||||||
|
'fourth column': 'fourth value ' + i,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
grid = new SlickGrid(container, data, columns);
|
||||||
|
|
||||||
|
grid.registerPlugin(new ActiveCellCapture());
|
||||||
|
cellSelectionModel = new XCellSelectionModel();
|
||||||
|
grid.setSelectionModel(cellSelectionModel);
|
||||||
|
|
||||||
|
grid.registerPlugin(columnSelector);
|
||||||
|
grid.invalidate();
|
||||||
|
$('body').append(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
$('body').find(container).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks a column header', function () {
|
||||||
|
it('selects the column', function () {
|
||||||
|
container.find('.slick-header-column:contains(some-column-name)').click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles a selected class to the header cell', function () {
|
||||||
|
container.find('.slick-header-column:contains(second column)').click();
|
||||||
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
|
.toBe(true);
|
||||||
|
|
||||||
|
container.find('.slick-header-column:contains(second column)').click();
|
||||||
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
|
.toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks an additional column header', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
container = $("<div></div>");
|
container.find('.slick-header-column:contains(some-column-name)').click();
|
||||||
container.height(9999);
|
container.find('.slick-header-column:contains(second column)').click();
|
||||||
container.width(9999);
|
|
||||||
|
|
||||||
data = [{
|
|
||||||
'some-column-name': 'first value',
|
|
||||||
'second column': 'second value',
|
|
||||||
'third column': 'nonselectable value'
|
|
||||||
}, {
|
|
||||||
'some-column-name': 'row 1 - first value',
|
|
||||||
'second column': 'row 1 - second value',
|
|
||||||
'third column': 'row 1 - nonselectable value'
|
|
||||||
}];
|
|
||||||
|
|
||||||
columns = [
|
|
||||||
{
|
|
||||||
id: 'row-header-column',
|
|
||||||
name: 'row header column name',
|
|
||||||
selectable: false,
|
|
||||||
display_name: 'row header column name',
|
|
||||||
column_type: 'text'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
name: 'some-column-name',
|
|
||||||
pos: 0,
|
|
||||||
display_name: 'some-column-name',
|
|
||||||
column_type: 'text'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
name: 'second column',
|
|
||||||
pos: 1,
|
|
||||||
display_name: 'second column',
|
|
||||||
column_type: 'json'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'third-column-id',
|
|
||||||
name: 'third column',
|
|
||||||
pos: 2,
|
|
||||||
display_name: 'third column',
|
|
||||||
column_type: 'text'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'some-non-selectable-column',
|
|
||||||
selectable: false,
|
|
||||||
pos: 3,
|
|
||||||
display_name: 'some-non-selectable-column',
|
|
||||||
column_type: 'numeric'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("displays the name of the column", function () {
|
it('selects additional columns', function () {
|
||||||
setupGrid(columns);
|
|
||||||
|
|
||||||
expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
.toContain('some-column-name');
|
|
||||||
expect($(container.find('.slick-header-columns .slick-column-name')[1]).text())
|
expect(selectedRanges.length).toBe(2);
|
||||||
.toContain('text');
|
var column1 = selectedRanges[0];
|
||||||
expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
|
expect(column1.fromCell).toBe(1);
|
||||||
.toContain('second column');
|
expect(column1.toCell).toBe(1);
|
||||||
expect($(container.find('.slick-header-columns .slick-column-name')[2]).text())
|
|
||||||
.toContain('json');
|
var column2 = selectedRanges[1];
|
||||||
|
expect(column2.fromCell).toBe(2);
|
||||||
|
expect(column2.toCell).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("preserves the other attributes of column definitions", function () {
|
describe('and presses shift + right-arrow', function () {
|
||||||
var columnSelector = new ColumnSelector();
|
|
||||||
var selectableColumns = columnSelector.getColumnDefinitions(columns);
|
|
||||||
|
|
||||||
expect(selectableColumns[1].id).toBe('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("with ActiveCellCapture, CellSelectionModel, and GridSelector: selecting columns", function () {
|
|
||||||
var grid, cellSelectionModel;
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var columnSelector = new ColumnSelector();
|
pressShiftArrow(KEY_RIGHT);
|
||||||
columns = columnSelector.getColumnDefinitions(columns);
|
|
||||||
data = [];
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
data.push({
|
|
||||||
'some-column-name': 'some-value-' + i,
|
|
||||||
'second column': 'second value ' + i,
|
|
||||||
'third column': 'third value ' + i,
|
|
||||||
'fourth column': 'fourth value ' + i,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
grid = new SlickGrid(container, data, columns);
|
|
||||||
|
|
||||||
grid.registerPlugin(new ActiveCellCapture());
|
|
||||||
cellSelectionModel = new XCellSelectionModel();
|
|
||||||
grid.setSelectionModel(cellSelectionModel);
|
|
||||||
|
|
||||||
grid.registerPlugin(columnSelector);
|
|
||||||
grid.invalidate();
|
|
||||||
$("body").append(container);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
it('keeps the last column selected', function () {
|
||||||
$("body").find(container).remove();
|
expect(cellSelectionModel.getSelectedRanges().length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when the user clicks a column header", function () {
|
it('grows the selection to the right', function () {
|
||||||
it("selects the column", function () {
|
var selectedRange = cellSelectionModel.getSelectedRanges()[0];
|
||||||
container.find('.slick-header-column:contains(some-column-name)').click();
|
expect(selectedRange.fromCell).toBe(2);
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
expect(selectedRange.toCell).toBe(3);
|
||||||
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
expect(selectedRange.fromRow).toBe(0);
|
||||||
});
|
expect(selectedRange.toRow).toBe(9);
|
||||||
|
|
||||||
it("toggles a selected class to the header cell", function () {
|
|
||||||
container.find('.slick-header-column:contains(second column)').click();
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBe(true);
|
|
||||||
|
|
||||||
container.find('.slick-header-column:contains(second column)').click();
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBe(false);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when the user clicks an additional column header", function () {
|
it('keeps selected class on columns 2 and 3', function () {
|
||||||
beforeEach(function () {
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
container.find('.slick-header-column:contains(some-column-name)').click();
|
.toBe(true);
|
||||||
container.find('.slick-header-column:contains(second column)').click();
|
expect($(container.find('.slick-header-column:contains(third column)')).hasClass('selected'))
|
||||||
});
|
.toBe(true);
|
||||||
|
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
||||||
|
.toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("selects additional columns", function () {
|
describe('when the user deselects the last selected column header', function () {
|
||||||
|
beforeEach(function () {
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
container.find('.slick-header-column:contains(second column)').click();
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(2);
|
|
||||||
var column1 = selectedRanges[0];
|
|
||||||
expect(column1.fromCell).toBe(1);
|
|
||||||
expect(column1.toCell).toBe(1);
|
|
||||||
|
|
||||||
var column2 = selectedRanges[1];
|
|
||||||
expect(column2.fromCell).toBe(2);
|
|
||||||
expect(column2.toCell).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("and presses shift + right-arrow", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
pressShiftArrow(KEY_RIGHT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps the last column selected", function () {
|
|
||||||
expect(cellSelectionModel.getSelectedRanges().length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("grows the selection to the right", function () {
|
|
||||||
var selectedRange = cellSelectionModel.getSelectedRanges()[0];
|
|
||||||
expect(selectedRange.fromCell).toBe(2);
|
|
||||||
expect(selectedRange.toCell).toBe(3);
|
|
||||||
expect(selectedRange.fromRow).toBe(0);
|
|
||||||
expect(selectedRange.toRow).toBe(9);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps selected class on columns 2 and 3", function () {
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBe(true);
|
|
||||||
expect($(container.find('.slick-header-column:contains(third column)')).hasClass('selected'))
|
|
||||||
.toBe(true);
|
|
||||||
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
|
||||||
.toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user deselects the last selected column header", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-header-column:contains(second column)').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("and presses shift + right-arrow", function () {
|
|
||||||
it("first and second columns are selected", function () {
|
|
||||||
pressShiftArrow(KEY_RIGHT);
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
expect(selectedRanges[0].fromCell).toBe(1);
|
|
||||||
expect(selectedRanges[0].toCell).toBe(2);
|
|
||||||
expect(selectedRanges[0].fromRow).toBe(0);
|
|
||||||
expect(selectedRanges[0].toRow).toBe(9);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when the user clicks a column header description", function () {
|
describe('and presses shift + right-arrow', function () {
|
||||||
it("selects the column", function () {
|
it('first and second columns are selected', function () {
|
||||||
container.find('.slick-header-columns span.column-description:contains(some-column-name)').click();
|
pressShiftArrow(KEY_RIGHT);
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("toggles a selected class to the header cell", function () {
|
|
||||||
container.find('.slick-header-column span.column-description:contains(second column)').click();
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBe(true);
|
|
||||||
|
|
||||||
container.find('.slick-header-column span.column-description:contains(second column)').click();
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when a row is selected", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
|
|
||||||
cellSelectionModel.setSelectedRanges(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects the row", function () {
|
|
||||||
container.find('.slick-header-column')[1].click();
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
expect(selectedRanges[0].fromCell).toBe(1);
|
||||||
var column = selectedRanges[0];
|
expect(selectedRanges[0].toCell).toBe(2);
|
||||||
|
expect(selectedRanges[0].fromRow).toBe(0);
|
||||||
expect(column.fromCell).toBe(1);
|
expect(selectedRanges[0].toRow).toBe(9);
|
||||||
expect(column.toCell).toBe(1);
|
|
||||||
expect(column.fromRow).toBe(0);
|
|
||||||
expect(column.toRow).toBe(9);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("clicking a second time", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-header-column')[1].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects the column", function () {
|
|
||||||
container.find('.slick-header-column')[1].click();
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(0);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the column is not selectable", function () {
|
|
||||||
it("does not select the column", function () {
|
|
||||||
$(container.find('.slick-header-column:contains(some-non-selectable-column)')).click();
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the column is deselected through setSelectedRanges", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-header-column')[1].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("removes selected class from header", function () {
|
|
||||||
cellSelectionModel.setSelectedRanges([]);
|
|
||||||
|
|
||||||
expect($(container.find('.slick-header-column')[1]).hasClass('selected'))
|
|
||||||
.toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when a non-column range was already selected", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var selectedRanges = [new Slick.Range(0, 0, 2, 0)];
|
|
||||||
cellSelectionModel.setSelectedRanges(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects the non-column range", function () {
|
|
||||||
container.find('.slick-header-column:contains(some-column-name)').click();
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when a column is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-header-column:contains(some-column-name)').click();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user click a cell on the current range', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-cell.l1.r1')[1].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('column is deselected', function () {
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
|
|
||||||
var column = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(column.fromCell).toBe(1);
|
|
||||||
expect(column.toCell).toBe(1);
|
|
||||||
expect(column.fromRow).toBe(1);
|
|
||||||
expect(column.toRow).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('keep select class on column header', function () {
|
|
||||||
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user click a cell outside the current range', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-cell.l2.r2')[2].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('column is deselected', function () {
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
|
|
||||||
var column = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(column.fromCell).toBe(2);
|
|
||||||
expect(column.toCell).toBe(2);
|
|
||||||
expect(column.fromRow).toBe(2);
|
|
||||||
expect(column.toRow).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('remove select class on "some-column-name" column header', function () {
|
|
||||||
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user click in a row header', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var selectedRanges = [new Slick.Range(1, 1, 1, 3)];
|
|
||||||
cellSelectionModel.setSelectedRanges(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('column is deselected', function () {
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
|
|
||||||
var column = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(column.fromCell).toBe(1);
|
|
||||||
expect(column.toCell).toBe(3);
|
|
||||||
expect(column.fromRow).toBe(1);
|
|
||||||
expect(column.toRow).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no column should have the class "selected"', function () {
|
|
||||||
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupGrid(columns) {
|
|
||||||
var columnSelector = new ColumnSelector();
|
|
||||||
columns = columnSelector.getColumnDefinitions(columns);
|
|
||||||
var grid = new SlickGrid(container, data, columns, options);
|
|
||||||
|
|
||||||
var cellSelectionModel = new XCellSelectionModel();
|
|
||||||
grid.setSelectionModel(cellSelectionModel);
|
|
||||||
|
|
||||||
grid.registerPlugin(columnSelector);
|
|
||||||
grid.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectOnlyTheFirstColumnToBeSelected(selectedRanges) {
|
|
||||||
var row = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(1);
|
|
||||||
expect(row.fromCell).toBe(1);
|
|
||||||
expect(row.toCell).toBe(1);
|
|
||||||
expect(row.fromRow).toBe(0);
|
|
||||||
expect(row.toRow).toBe(9);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pressShiftArrow(keyCode) {
|
|
||||||
var pressEvent = new $.Event("keydown");
|
|
||||||
pressEvent.shiftKey = true;
|
|
||||||
pressEvent.ctrlKey = false;
|
|
||||||
pressEvent.altKey = false;
|
|
||||||
pressEvent.which = keyCode;
|
|
||||||
|
|
||||||
$(container.find('.grid-canvas')).trigger(pressEvent);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
describe('when the user clicks a column header description', function () {
|
||||||
|
it('selects the column', function () {
|
||||||
|
container.find('.slick-header-columns span.column-description:contains(some-column-name)').click();
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('toggles a selected class to the header cell', function () {
|
||||||
|
container.find('.slick-header-column span.column-description:contains(second column)').click();
|
||||||
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
|
.toBe(true);
|
||||||
|
|
||||||
|
container.find('.slick-header-column span.column-description:contains(second column)').click();
|
||||||
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
|
.toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a row is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
|
||||||
|
cellSelectionModel.setSelectedRanges(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deselects the row', function () {
|
||||||
|
container.find('.slick-header-column')[1].click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var column = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(column.fromCell).toBe(1);
|
||||||
|
expect(column.toCell).toBe(1);
|
||||||
|
expect(column.fromRow).toBe(0);
|
||||||
|
expect(column.toRow).toBe(9);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clicking a second time', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-header-column')[1].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deselects the column', function () {
|
||||||
|
container.find('.slick-header-column')[1].click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(0);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the column is not selectable', function () {
|
||||||
|
it('does not select the column', function () {
|
||||||
|
$(container.find('.slick-header-column:contains(some-non-selectable-column)')).click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the column is deselected through setSelectedRanges', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-header-column')[1].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removes selected class from header', function () {
|
||||||
|
cellSelectionModel.setSelectedRanges([]);
|
||||||
|
|
||||||
|
expect($(container.find('.slick-header-column')[1]).hasClass('selected'))
|
||||||
|
.toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a non-column range was already selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var selectedRanges = [new Slick.Range(0, 0, 2, 0)];
|
||||||
|
cellSelectionModel.setSelectedRanges(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deselects the non-column range', function () {
|
||||||
|
container.find('.slick-header-column:contains(some-column-name)').click();
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
expectOnlyTheFirstColumnToBeSelected(selectedRanges);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a column is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-header-column:contains(some-column-name)').click();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user click a cell on the current range', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-cell.l1.r1')[1].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('column is deselected', function () {
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var column = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(column.fromCell).toBe(1);
|
||||||
|
expect(column.toCell).toBe(1);
|
||||||
|
expect(column.fromRow).toBe(1);
|
||||||
|
expect(column.toRow).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keep select class on column header', function () {
|
||||||
|
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
||||||
|
.toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user click a cell outside the current range', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-cell.l2.r2')[2].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('column is deselected', function () {
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var column = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(column.fromCell).toBe(2);
|
||||||
|
expect(column.toCell).toBe(2);
|
||||||
|
expect(column.fromRow).toBe(2);
|
||||||
|
expect(column.toRow).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove select class on \'some-column-name\' column header', function () {
|
||||||
|
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-header-column:contains(second column)')).hasClass('selected'))
|
||||||
|
.toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user click in a row header', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var selectedRanges = [new Slick.Range(1, 1, 1, 3)];
|
||||||
|
cellSelectionModel.setSelectedRanges(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('column is deselected', function () {
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var column = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(column.fromCell).toBe(1);
|
||||||
|
expect(column.toCell).toBe(3);
|
||||||
|
expect(column.fromRow).toBe(1);
|
||||||
|
expect(column.toRow).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no column should have the class \'selected\'', function () {
|
||||||
|
expect($(container.find('.slick-header-column:contains(some-column-name)')).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function setupGrid(columns) {
|
||||||
|
var columnSelector = new ColumnSelector();
|
||||||
|
columns = columnSelector.getColumnDefinitions(columns);
|
||||||
|
var grid = new SlickGrid(container, data, columns, options);
|
||||||
|
|
||||||
|
var cellSelectionModel = new XCellSelectionModel();
|
||||||
|
grid.setSelectionModel(cellSelectionModel);
|
||||||
|
|
||||||
|
grid.registerPlugin(columnSelector);
|
||||||
|
grid.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectOnlyTheFirstColumnToBeSelected(selectedRanges) {
|
||||||
|
var row = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(1);
|
||||||
|
expect(row.fromCell).toBe(1);
|
||||||
|
expect(row.toCell).toBe(1);
|
||||||
|
expect(row.fromRow).toBe(0);
|
||||||
|
expect(row.toRow).toBe(9);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pressShiftArrow(keyCode) {
|
||||||
|
var pressEvent = new $.Event('keydown');
|
||||||
|
pressEvent.shiftKey = true;
|
||||||
|
pressEvent.ctrlKey = false;
|
||||||
|
pressEvent.altKey = false;
|
||||||
|
pressEvent.which = keyCode;
|
||||||
|
|
||||||
|
$(container.find('.grid-canvas')).trigger(pressEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,139 +1,142 @@
|
|||||||
/////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
//
|
//
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
// This software is released under the PostgreSQL Licence
|
// This software is released under the PostgreSQL Licence
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define(
|
import $ from 'jquery';
|
||||||
["jquery",
|
|
||||||
"slickgrid/slick.grid",
|
|
||||||
"sources/selection/xcell_selection_model",
|
|
||||||
"sources/selection/copy_data",
|
|
||||||
"sources/selection/clipboard",
|
|
||||||
"sources/selection/range_selection_helper"
|
|
||||||
],
|
|
||||||
function ($, SlickGrid, XCellSelectionModel, copyData, clipboard, RangeSelectionHelper) {
|
|
||||||
describe('copyData', function () {
|
|
||||||
var grid, sqlEditor, gridContainer, buttonPasteRow;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
import Slick from 'slickgrid';
|
||||||
var data = [[1, "leopord", "12"],
|
import 'slickgrid.grid';
|
||||||
[2, "lion", "13"],
|
|
||||||
[3, "puma", "9"]];
|
|
||||||
|
|
||||||
var columns = [
|
import clipboard from '../../../pgadmin/static/js/selection/clipboard';
|
||||||
{
|
import copyData from '../../../pgadmin/static/js/selection/copy_data';
|
||||||
id: 'row-header-column',
|
import RangeSelectionHelper from 'sources/selection/range_selection_helper';
|
||||||
name: 'row header column name',
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
selectable: false,
|
|
||||||
display_name: 'row header column name',
|
|
||||||
column_type: 'text'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "id",
|
|
||||||
pos: 0,
|
|
||||||
label: "id<br> numeric",
|
|
||||||
cell: "number",
|
|
||||||
can_edit: false,
|
|
||||||
type: "numeric"
|
|
||||||
}, {
|
|
||||||
name: "brand",
|
|
||||||
pos: 1,
|
|
||||||
label: "flavor<br> character varying",
|
|
||||||
cell: "string",
|
|
||||||
can_edit: false,
|
|
||||||
type: "character varying"
|
|
||||||
}, {
|
|
||||||
name: "size",
|
|
||||||
pos: 2,
|
|
||||||
label: "size<br> numeric",
|
|
||||||
cell: "number",
|
|
||||||
can_edit: false,
|
|
||||||
type: "numeric"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
;
|
|
||||||
gridContainer = $("<div id='grid'></div>");
|
|
||||||
$("body").append(gridContainer);
|
|
||||||
buttonPasteRow = $("<button id='btn-paste-row' disabled></button>");
|
|
||||||
$("body").append(buttonPasteRow);
|
|
||||||
grid = new Slick.Grid("#grid", data, columns, {});
|
|
||||||
grid.setSelectionModel(new XCellSelectionModel());
|
|
||||||
sqlEditor = {slickgrid: grid};
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(function() {
|
describe('copyData', function () {
|
||||||
gridContainer.remove();
|
var grid, sqlEditor, gridContainer, buttonPasteRow;
|
||||||
buttonPasteRow.remove();
|
var Slick, SlickGrid;
|
||||||
});
|
|
||||||
|
|
||||||
describe("when rows are selected", function () {
|
beforeEach(function () {
|
||||||
beforeEach(function () {
|
Slick = window.Slick;
|
||||||
grid.getSelectionModel().setSelectedRanges([
|
SlickGrid = Slick.Grid;
|
||||||
RangeSelectionHelper.rangeForRow(grid, 0),
|
var data = [[1, 'leopord', '12'],
|
||||||
RangeSelectionHelper.rangeForRow(grid, 2)]
|
[2, 'lion', '13'],
|
||||||
);
|
[3, 'puma', '9']];
|
||||||
});
|
|
||||||
|
|
||||||
it("copies them", function () {
|
var columns = [
|
||||||
spyOn(clipboard, 'copyTextToClipboard');
|
{
|
||||||
|
id: 'row-header-column',
|
||||||
|
name: 'row header column name',
|
||||||
|
selectable: false,
|
||||||
|
display_name: 'row header column name',
|
||||||
|
column_type: 'text'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'id',
|
||||||
|
pos: 0,
|
||||||
|
label: 'id<br> numeric',
|
||||||
|
cell: 'number',
|
||||||
|
can_edit: false,
|
||||||
|
type: 'numeric'
|
||||||
|
}, {
|
||||||
|
name: 'brand',
|
||||||
|
pos: 1,
|
||||||
|
label: 'flavor<br> character varying',
|
||||||
|
cell: 'string',
|
||||||
|
can_edit: false,
|
||||||
|
type: 'character varying'
|
||||||
|
}, {
|
||||||
|
name: 'size',
|
||||||
|
pos: 2,
|
||||||
|
label: 'size<br> numeric',
|
||||||
|
cell: 'number',
|
||||||
|
can_edit: false,
|
||||||
|
type: 'numeric'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
;
|
||||||
|
gridContainer = $('<div id=\'grid\'></div>');
|
||||||
|
$('body').append(gridContainer);
|
||||||
|
buttonPasteRow = $('<button id=\'btn-paste-row\' disabled></button>');
|
||||||
|
$('body').append(buttonPasteRow);
|
||||||
|
grid = new Slick.Grid('#grid', data, columns, {});
|
||||||
|
grid.setSelectionModel(new XCellSelectionModel());
|
||||||
|
sqlEditor = {slickgrid: grid};
|
||||||
|
});
|
||||||
|
|
||||||
copyData.apply(sqlEditor);
|
afterEach(function () {
|
||||||
|
gridContainer.remove();
|
||||||
|
buttonPasteRow.remove();
|
||||||
|
});
|
||||||
|
|
||||||
expect(sqlEditor.copied_rows.length).toBe(2);
|
describe('when rows are selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
grid.getSelectionModel().setSelectedRanges([
|
||||||
|
RangeSelectionHelper.rangeForRow(grid, 0),
|
||||||
|
RangeSelectionHelper.rangeForRow(grid, 2)]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
|
it('copies them', function () {
|
||||||
expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain("1,'leopord','12'");
|
spyOn(clipboard, 'copyTextToClipboard');
|
||||||
expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain("3,'puma','9'");
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user can edit the grid", function () {
|
copyData.apply(sqlEditor);
|
||||||
it("enables the paste row button", function () {
|
|
||||||
copyData.apply(_.extend({can_edit: true}, sqlEditor));
|
|
||||||
|
|
||||||
expect($("#btn-paste-row").prop('disabled')).toBe(false);
|
expect(sqlEditor.copied_rows.length).toBe(2);
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when a column is selected", function () {
|
expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
|
||||||
beforeEach(function () {
|
expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain('1,\'leopord\',\'12\'');
|
||||||
var firstDataColumn = RangeSelectionHelper.rangeForColumn(grid, 1);
|
expect(clipboard.copyTextToClipboard.calls.mostRecent().args[0]).toContain('3,\'puma\',\'9\'');
|
||||||
grid.getSelectionModel().setSelectedRanges([firstDataColumn])
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it("copies text to the clipboard", function () {
|
describe('when the user can edit the grid', function () {
|
||||||
spyOn(clipboard, 'copyTextToClipboard');
|
it('enables the paste row button', function () {
|
||||||
|
copyData.apply(_.extend({can_edit: true}, sqlEditor));
|
||||||
|
|
||||||
copyData.apply(sqlEditor);
|
expect($('#btn-paste-row').prop('disabled')).toBe(false);
|
||||||
|
|
||||||
expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
|
|
||||||
|
|
||||||
var copyArg = clipboard.copyTextToClipboard.calls.mostRecent().args[0];
|
|
||||||
var rowStrings = copyArg.split('\n');
|
|
||||||
expect(rowStrings[0]).toBe("1");
|
|
||||||
expect(rowStrings[1]).toBe("2");
|
|
||||||
expect(rowStrings[2]).toBe("3");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("sets copied_rows to empty", function () {
|
|
||||||
copyData.apply(sqlEditor);
|
|
||||||
|
|
||||||
expect(sqlEditor.copied_rows.length).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user can edit the grid", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
copyData.apply(_.extend({can_edit: true}, sqlEditor));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disables the paste row button", function () {
|
|
||||||
expect($("#btn-paste-row").prop('disabled')).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when a column is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var firstDataColumn = RangeSelectionHelper.rangeForColumn(grid, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([firstDataColumn]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('copies text to the clipboard', function () {
|
||||||
|
spyOn(clipboard, 'copyTextToClipboard');
|
||||||
|
|
||||||
|
copyData.apply(sqlEditor);
|
||||||
|
|
||||||
|
expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
|
||||||
|
|
||||||
|
var copyArg = clipboard.copyTextToClipboard.calls.mostRecent().args[0];
|
||||||
|
var rowStrings = copyArg.split('\n');
|
||||||
|
expect(rowStrings[0]).toBe('1');
|
||||||
|
expect(rowStrings[1]).toBe('2');
|
||||||
|
expect(rowStrings[2]).toBe('3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets copied_rows to empty', function () {
|
||||||
|
copyData.apply(sqlEditor);
|
||||||
|
|
||||||
|
expect(sqlEditor.copied_rows.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user can edit the grid', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
copyData.apply(_.extend({can_edit: true}, sqlEditor));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('disables the paste row button', function () {
|
||||||
|
expect($('#btn-paste-row').prop('disabled')).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,117 +1,130 @@
|
|||||||
define(["jquery",
|
//////////////////////////////////////////////////////////////////////////
|
||||||
"underscore",
|
//
|
||||||
"slickgrid/slick.grid",
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
"sources/selection/xcell_selection_model",
|
//
|
||||||
"sources/selection/grid_selector"
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
],
|
// This software is released under the PostgreSQL Licence
|
||||||
function ($, _, SlickGrid, XCellSelectionModel, GridSelector) {
|
//
|
||||||
describe("GridSelector", function () {
|
//////////////////////////////////////////////////////////////////////////
|
||||||
var container, data, columns, gridSelector, xCellSelectionModel;
|
|
||||||
|
|
||||||
|
import $ from 'jquery';
|
||||||
|
import _ from 'underscore';
|
||||||
|
|
||||||
|
import Slick from 'slickgrid';
|
||||||
|
import 'slickgrid.grid';
|
||||||
|
|
||||||
|
import GridSelector from 'sources/selection/grid_selector';
|
||||||
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
|
|
||||||
|
describe('GridSelector', function () {
|
||||||
|
var container, data, columns, gridSelector, xCellSelectionModel;
|
||||||
|
var Slick, SlickGrid;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
Slick = window.Slick;
|
||||||
|
SlickGrid = Slick.Grid;
|
||||||
|
container = $('<div></div>');
|
||||||
|
container.height(9999);
|
||||||
|
columns = [{
|
||||||
|
id: '1',
|
||||||
|
name: 'some-column-name',
|
||||||
|
pos: 0
|
||||||
|
}, {
|
||||||
|
id: '2',
|
||||||
|
name: 'second column',
|
||||||
|
pos: 1
|
||||||
|
}];
|
||||||
|
|
||||||
|
gridSelector = new GridSelector();
|
||||||
|
columns = gridSelector.getColumnDefinitions(columns);
|
||||||
|
|
||||||
|
data = [];
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
||||||
|
}
|
||||||
|
var grid = new Slick.Grid(container, data, columns);
|
||||||
|
|
||||||
|
xCellSelectionModel = new XCellSelectionModel();
|
||||||
|
grid.setSelectionModel(xCellSelectionModel);
|
||||||
|
|
||||||
|
grid.registerPlugin(gridSelector);
|
||||||
|
grid.invalidate();
|
||||||
|
|
||||||
|
$('body').append(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
$('body').find(container).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders an additional column on the left for selecting rows', function () {
|
||||||
|
expect(columns.length).toBe(3);
|
||||||
|
|
||||||
|
var leftmostColumn = columns[0];
|
||||||
|
expect(leftmostColumn.id).toBe('row-header-column');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders a button for selecting all the cells', function () {
|
||||||
|
expect(container.find('[title=\'Select/Deselect All\']').length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the cell for the select/deselect all is clicked', function () {
|
||||||
|
it('selects the whole grid', function () {
|
||||||
|
container.find('[title=\'Select/Deselect All\']').parent().click();
|
||||||
|
|
||||||
|
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
var selectedRange = selectedRanges[0];
|
||||||
|
expect(selectedRange.fromCell).toBe(1);
|
||||||
|
expect(selectedRange.toCell).toBe(2);
|
||||||
|
expect(selectedRange.fromRow).toBe(0);
|
||||||
|
expect(selectedRange.toRow).toBe(9);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds selected class', function () {
|
||||||
|
container.find('[title=\'Select/Deselect All\']').parent().click();
|
||||||
|
|
||||||
|
expect($(container.find('[data-id=\'select-all\']')).hasClass('selected')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the select all button in the corner gets selected', function () {
|
||||||
|
|
||||||
|
it('selects all the cells', function () {
|
||||||
|
container.find('[title=\'Select/Deselect All\']').click();
|
||||||
|
|
||||||
|
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
var selectedRange = selectedRanges[0];
|
||||||
|
expect(selectedRange.fromCell).toBe(1);
|
||||||
|
expect(selectedRange.toCell).toBe(2);
|
||||||
|
expect(selectedRange.fromRow).toBe(0);
|
||||||
|
expect(selectedRange.toRow).toBe(9);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the select all button in the corner gets deselected', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
container = $("<div></div>");
|
container.find('[title=\'Select/Deselect All\']').click();
|
||||||
container.height(9999);
|
|
||||||
columns = [{
|
|
||||||
id: '1',
|
|
||||||
name: 'some-column-name',
|
|
||||||
pos: 0
|
|
||||||
}, {
|
|
||||||
id: '2',
|
|
||||||
name: 'second column',
|
|
||||||
pos: 1
|
|
||||||
}];
|
|
||||||
|
|
||||||
gridSelector = new GridSelector();
|
|
||||||
columns = gridSelector.getColumnDefinitions(columns);
|
|
||||||
|
|
||||||
data = [];
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
|
||||||
}
|
|
||||||
var grid = new SlickGrid(container, data, columns);
|
|
||||||
|
|
||||||
xCellSelectionModel = new XCellSelectionModel();
|
|
||||||
grid.setSelectionModel(xCellSelectionModel);
|
|
||||||
|
|
||||||
grid.registerPlugin(gridSelector);
|
|
||||||
grid.invalidate();
|
|
||||||
|
|
||||||
$("body").append(container);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
it('deselects all the cells', function () {
|
||||||
$("body").find(container).remove();
|
container.find('[title=\'Select/Deselect All\']').click();
|
||||||
|
|
||||||
|
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
||||||
|
expect(selectedRanges.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and then the underlying selection changes', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('[title=\'Select/Deselect All\']').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders an additional column on the left for selecting rows", function () {
|
it('removes the selected class', function () {
|
||||||
expect(columns.length).toBe(3);
|
container.find('[title=\'Select/Deselect All\']').parent().click();
|
||||||
|
|
||||||
var leftmostColumn = columns[0];
|
expect($(container.find('[data-id=\'select-all\']')).hasClass('selected')).toBeFalsy();
|
||||||
expect(leftmostColumn.id).toBe('row-header-column');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("renders a button for selecting all the cells", function () {
|
|
||||||
expect(container.find("[title='Select/Deselect All']").length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the cell for the select/deselect all is clicked", function () {
|
|
||||||
it("selects the whole grid", function () {
|
|
||||||
container.find("[title='Select/Deselect All']").parent().click();
|
|
||||||
|
|
||||||
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
var selectedRange = selectedRanges[0];
|
|
||||||
expect(selectedRange.fromCell).toBe(1);
|
|
||||||
expect(selectedRange.toCell).toBe(2);
|
|
||||||
expect(selectedRange.fromRow).toBe(0);
|
|
||||||
expect(selectedRange.toRow).toBe(9);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adds selected class", function () {
|
|
||||||
container.find("[title='Select/Deselect All']").parent().click();
|
|
||||||
|
|
||||||
expect($(container.find("[data-id='select-all']")).hasClass('selected')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the select all button in the corner gets selected", function () {
|
|
||||||
|
|
||||||
it("selects all the cells", function () {
|
|
||||||
container.find("[title='Select/Deselect All']").click();
|
|
||||||
|
|
||||||
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
var selectedRange = selectedRanges[0];
|
|
||||||
expect(selectedRange.fromCell).toBe(1);
|
|
||||||
expect(selectedRange.toCell).toBe(2);
|
|
||||||
expect(selectedRange.fromRow).toBe(0);
|
|
||||||
expect(selectedRange.toRow).toBe(9);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the select all button in the corner gets deselected", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find("[title='Select/Deselect All']").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects all the cells", function () {
|
|
||||||
container.find("[title='Select/Deselect All']").click();
|
|
||||||
|
|
||||||
var selectedRanges = xCellSelectionModel.getSelectedRanges();
|
|
||||||
expect(selectedRanges.length).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("and then the underlying selection changes", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find("[title='Select/Deselect All']").click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("removes the selected class", function () {
|
|
||||||
container.find("[title='Select/Deselect All']").parent().click();
|
|
||||||
|
|
||||||
expect($(container.find("[data-id='select-all']")).hasClass('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,8 +1,20 @@
|
|||||||
define(['sources/selection/range_boundary_navigator'], function (rangeBoundaryNavigator) {
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
|
//
|
||||||
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
|
// This software is released under the PostgreSQL Licence
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
describe("#getUnion", function () {
|
import rangeBoundaryNavigator from 'sources/selection/range_boundary_navigator';
|
||||||
describe("when the ranges completely overlap", function () {
|
import Slick from 'slickgrid';
|
||||||
it("returns a list with that range", function () {
|
|
||||||
|
describe('RangeBoundaryNavigator', function () {
|
||||||
|
|
||||||
|
describe('#getUnion', function () {
|
||||||
|
describe('when the ranges completely overlap', function () {
|
||||||
|
it('returns a list with that range', function () {
|
||||||
var ranges = [[1, 4], [1, 4], [1, 4]];
|
var ranges = [[1, 4], [1, 4], [1, 4]];
|
||||||
|
|
||||||
var union = rangeBoundaryNavigator.getUnion(ranges);
|
var union = rangeBoundaryNavigator.getUnion(ranges);
|
||||||
|
|||||||
@@ -1,70 +1,82 @@
|
|||||||
define([
|
import $ from 'jquery';
|
||||||
'jquery',
|
import Slick from 'slickgrid';
|
||||||
'slickgrid/slick.grid',
|
import 'slickgrid.grid';
|
||||||
'sources/selection/range_selection_helper'
|
import RangeSelectionHelper from 'sources/selection/range_selection_helper';
|
||||||
], function ($, SlickGrid, RangeSelectionHelper) {
|
|
||||||
describe("RangeSelectionHelper utility functions", function () {
|
|
||||||
var grid;
|
|
||||||
beforeEach(function () {
|
|
||||||
var container, data, columns, options;
|
|
||||||
container = $("<div></div>");
|
|
||||||
container.height(9999);
|
|
||||||
|
|
||||||
columns = [{
|
describe("RangeSelectionHelper utility functions", function () {
|
||||||
id: '1',
|
var grid;
|
||||||
name: 'some-column-name',
|
beforeEach(function () {
|
||||||
pos: 0
|
var container, data, columns, options;
|
||||||
}, {
|
container = $("<div></div>");
|
||||||
id: 'second-column-id',
|
container.height(9999);
|
||||||
name: 'second column',
|
|
||||||
pos: 1
|
|
||||||
}];
|
|
||||||
|
|
||||||
data = [];
|
columns = [{
|
||||||
for (var i = 0; i < 10; i++) {
|
id: '1',
|
||||||
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
name: 'some-column-name',
|
||||||
}
|
pos: 0
|
||||||
|
}, {
|
||||||
|
id: 'second-column-id',
|
||||||
|
name: 'second column',
|
||||||
|
pos: 1
|
||||||
|
}];
|
||||||
|
|
||||||
grid = new SlickGrid(container, data, columns, options);
|
data = [];
|
||||||
grid.invalidate();
|
for (var i = 0; i < 10; i++) {
|
||||||
|
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
||||||
|
}
|
||||||
|
|
||||||
|
grid = new Slick.Grid(container, data, columns, options);
|
||||||
|
grid.invalidate();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#getIndexesOfCompleteRows", function () {
|
||||||
|
describe("when selected ranges are not rows", function () {
|
||||||
|
it("returns an empty array", function () {
|
||||||
|
var rowlessRanges = [RangeSelectionHelper.rangeForColumn(grid, 1)];
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, rowlessRanges))
|
||||||
|
.toEqual([]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
describe("when selected range", function () {
|
||||||
|
describe("is a single row", function () {
|
||||||
|
it("returns an array with one index", function () {
|
||||||
|
var singleRowRange = [RangeSelectionHelper.rangeForRow(grid, 1)];
|
||||||
|
|
||||||
describe("#getIndexesOfCompleteRows", function () {
|
expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, singleRowRange))
|
||||||
describe("when selected ranges are not rows", function () {
|
.toEqual([1]);
|
||||||
it("returns an empty array", function () {
|
|
||||||
var rowlessRanges = [RangeSelectionHelper.rangeForColumn(grid, 1)];
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, rowlessRanges))
|
|
||||||
.toEqual([]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe("when selected range", function () {
|
|
||||||
describe("is a single row", function () {
|
|
||||||
it("returns an array with one index", function () {
|
|
||||||
var singleRowRange = [RangeSelectionHelper.rangeForRow(grid, 1)];
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.getIndexesOfCompleteRows(grid, singleRowRange))
|
describe("is multiple rows", function () {
|
||||||
.toEqual([1]);
|
it("returns an array of each row's index", function () {
|
||||||
});
|
var multipleRowRange = [
|
||||||
|
RangeSelectionHelper.rangeForRow(grid, 0),
|
||||||
|
RangeSelectionHelper.rangeForRow(grid, 3),
|
||||||
|
RangeSelectionHelper.rangeForRow(grid, 2),
|
||||||
|
];
|
||||||
|
|
||||||
|
var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
|
||||||
|
indexesOfCompleteRows.sort();
|
||||||
|
expect(indexesOfCompleteRows).toEqual([0, 2, 3]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("contains a multi row selection", function () {
|
||||||
|
it("returns an array of each individual row's index", function () {
|
||||||
|
var multipleRowRange = [
|
||||||
|
new Slick.Range(3, 0, 5, 1)
|
||||||
|
];
|
||||||
|
|
||||||
|
var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
|
||||||
|
indexesOfCompleteRows.sort();
|
||||||
|
expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("is multiple rows", function () {
|
describe("and also contains a selection that is not a row", function () {
|
||||||
it("returns an array of each row's index", function () {
|
it("returns an array of only the complete rows' indexes", function () {
|
||||||
var multipleRowRange = [
|
|
||||||
RangeSelectionHelper.rangeForRow(grid, 0),
|
|
||||||
RangeSelectionHelper.rangeForRow(grid, 3),
|
|
||||||
RangeSelectionHelper.rangeForRow(grid, 2),
|
|
||||||
];
|
|
||||||
|
|
||||||
var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
|
|
||||||
indexesOfCompleteRows.sort();
|
|
||||||
expect(indexesOfCompleteRows).toEqual([0, 2, 3]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("contains a multi row selection", function () {
|
|
||||||
it("returns an array of each individual row's index", function () {
|
|
||||||
var multipleRowRange = [
|
var multipleRowRange = [
|
||||||
|
new Slick.Range(8, 1, 9, 1),
|
||||||
new Slick.Range(3, 0, 5, 1)
|
new Slick.Range(3, 0, 5, 1)
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -72,22 +84,8 @@ define([
|
|||||||
indexesOfCompleteRows.sort();
|
indexesOfCompleteRows.sort();
|
||||||
expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
|
expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("and also contains a selection that is not a row", function () {
|
|
||||||
it("returns an array of only the complete rows' indexes", function () {
|
|
||||||
var multipleRowRange = [
|
|
||||||
new Slick.Range(8, 1, 9, 1),
|
|
||||||
new Slick.Range(3, 0, 5, 1)
|
|
||||||
];
|
|
||||||
|
|
||||||
var indexesOfCompleteRows = RangeSelectionHelper.getIndexesOfCompleteRows(grid, multipleRowRange);
|
|
||||||
indexesOfCompleteRows.sort();
|
|
||||||
expect(indexesOfCompleteRows).toEqual([3, 4, 5]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,321 +1,327 @@
|
|||||||
define(
|
//////////////////////////////////////////////////////////////////////////
|
||||||
["jquery",
|
//
|
||||||
"underscore",
|
// pgAdmin 4 - PostgreSQL Tools
|
||||||
"slickgrid/slick.grid",
|
//
|
||||||
"sources/selection/active_cell_capture",
|
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||||
"sources/selection/row_selector",
|
// This software is released under the PostgreSQL Licence
|
||||||
'sources/selection/xcell_selection_model',
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
"slickgrid",
|
import $ from 'jquery';
|
||||||
'sources/slickgrid/pgslick.cellrangedecorator',
|
import _ from 'underscore';
|
||||||
'sources/slickgrid/pgslick.cellrangeselector',
|
|
||||||
],
|
|
||||||
function ($, _, SlickGrid, ActiveCellCapture, RowSelector, XCellSelectionModel, Slick) {
|
|
||||||
var KEY_RIGHT = 39;
|
|
||||||
var KEY_LEFT = 37;
|
|
||||||
var KEY_UP = 38;
|
|
||||||
var KEY_DOWN = 40;
|
|
||||||
describe("RowSelector", function () {
|
|
||||||
var container, data, columnDefinitions, grid, cellSelectionModel;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
import Slick from 'slickgrid';
|
||||||
container = $("<div></div>");
|
import 'slickgrid.grid';
|
||||||
container.height(9999);
|
|
||||||
container.width(9999);
|
|
||||||
|
|
||||||
columnDefinitions = [{
|
import RowSelector from 'sources/selection/row_selector';
|
||||||
id: '1',
|
import ActiveCellCapture from 'sources/selection/active_cell_capture';
|
||||||
name: 'some-column-name',
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
selectable: true,
|
|
||||||
pos: 0
|
|
||||||
}, {
|
|
||||||
id: '2',
|
|
||||||
name: 'second column',
|
|
||||||
selectable: true,
|
|
||||||
pos: 1
|
|
||||||
}];
|
|
||||||
|
|
||||||
var rowSelector = new RowSelector();
|
describe('RowSelector', function () {
|
||||||
data = [];
|
var KEY_RIGHT = 39;
|
||||||
for (var i = 0; i < 10; i++) {
|
var KEY_LEFT = 37;
|
||||||
data.push(['some-value-' + i, 'second value ' + i]);
|
var KEY_UP = 38;
|
||||||
}
|
var KEY_DOWN = 40;
|
||||||
columnDefinitions = rowSelector.getColumnDefinitions(columnDefinitions);
|
var container, data, columnDefinitions, grid, cellSelectionModel;
|
||||||
grid = new SlickGrid(container, data, columnDefinitions);
|
var SlickGrid = Slick.Grid;
|
||||||
|
|
||||||
grid.registerPlugin(new ActiveCellCapture());
|
beforeEach(function () {
|
||||||
cellSelectionModel = new XCellSelectionModel();
|
container = $('<div></div>');
|
||||||
grid.setSelectionModel(cellSelectionModel);
|
container.height(9999);
|
||||||
|
container.width(9999);
|
||||||
|
|
||||||
grid.registerPlugin(rowSelector);
|
columnDefinitions = [{
|
||||||
grid.invalidate();
|
id: '1',
|
||||||
|
name: 'some-column-name',
|
||||||
|
selectable: true,
|
||||||
|
pos: 0
|
||||||
|
}, {
|
||||||
|
id: '2',
|
||||||
|
name: 'second column',
|
||||||
|
selectable: true,
|
||||||
|
pos: 1
|
||||||
|
}];
|
||||||
|
|
||||||
$("body").append(container);
|
var rowSelector = new RowSelector();
|
||||||
|
data = [];
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
data.push(['some-value-' + i, 'second value ' + i]);
|
||||||
|
}
|
||||||
|
columnDefinitions = rowSelector.getColumnDefinitions(columnDefinitions);
|
||||||
|
grid = new SlickGrid(container, data, columnDefinitions);
|
||||||
|
|
||||||
|
grid.registerPlugin(new ActiveCellCapture());
|
||||||
|
cellSelectionModel = new XCellSelectionModel();
|
||||||
|
grid.setSelectionModel(cellSelectionModel);
|
||||||
|
|
||||||
|
grid.registerPlugin(rowSelector);
|
||||||
|
grid.invalidate();
|
||||||
|
|
||||||
|
$('body').append(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
$('body').find(container).remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders an additional column on the left', function () {
|
||||||
|
expect(columnDefinitions.length).toBe(3);
|
||||||
|
|
||||||
|
var leftmostColumn = columnDefinitions[0];
|
||||||
|
expect(leftmostColumn.id).toBe('row-header-column');
|
||||||
|
expect(leftmostColumn.name).toBe('');
|
||||||
|
expect(leftmostColumn.selectable).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders a span on the leftmost column', function () {
|
||||||
|
expect(container.find('.slick-row').length).toBe(10);
|
||||||
|
expect(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]').length).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('preserves the other attributes of column definitions', function () {
|
||||||
|
expect(columnDefinitions[1].id).toBe('1');
|
||||||
|
expect(columnDefinitions[1].selectable).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('selecting rows', function () {
|
||||||
|
describe('when the user clicks a row header span', function () {
|
||||||
|
it('selects the row', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[0].click();
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
expectOnlyTheFirstRowToBeSelected(selectedRanges);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
it('add selected class to parent of the span', function () {
|
||||||
$("body").find(container).remove();
|
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[5].click();
|
||||||
|
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[5])
|
||||||
|
.hasClass('selected')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders an additional column on the left", function () {
|
|
||||||
expect(columnDefinitions.length).toBe(3);
|
|
||||||
|
|
||||||
var leftmostColumn = columnDefinitions[0];
|
|
||||||
expect(leftmostColumn.id).toBe('row-header-column');
|
|
||||||
expect(leftmostColumn.name).toBe('');
|
|
||||||
expect(leftmostColumn.selectable).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("renders a span on the leftmost column", function () {
|
|
||||||
expect(container.find('.slick-row').length).toBe(10);
|
|
||||||
expect(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]').length).toBe(10);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("preserves the other attributes of column definitions", function () {
|
|
||||||
expect(columnDefinitions[1].id).toBe('1');
|
|
||||||
expect(columnDefinitions[1].selectable).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("selecting rows", function () {
|
|
||||||
describe("when the user clicks a row header span", function () {
|
|
||||||
it("selects the row", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[0].click();
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
expectOnlyTheFirstRowToBeSelected(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("add selected class to parent of the span", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[5].click();
|
|
||||||
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[5])
|
|
||||||
.hasClass('selected')).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user clicks a row header", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[1].click();
|
|
||||||
|
|
||||||
});
|
|
||||||
it("selects the row", function () {
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
var row = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(1);
|
|
||||||
expect(row.fromCell).toBe(1);
|
|
||||||
expect(row.toCell).toBe(2);
|
|
||||||
expect(row.fromRow).toBe(1);
|
|
||||||
expect(row.toRow).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("add selected class to parent of the span", function () {
|
|
||||||
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
|
||||||
.hasClass('selected')).toBeTruthy();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user clicks again the same row header", function () {
|
|
||||||
it("add selected class to parent of the span", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1].click();
|
|
||||||
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
|
||||||
.hasClass('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("and presses shift + down-arrow", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
pressShiftArrow(KEY_DOWN);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps the last row selected", function () {
|
|
||||||
expect(cellSelectionModel.getSelectedRanges().length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("grows the selection down", function () {
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
var row = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(1);
|
|
||||||
expect(row.fromCell).toBe(1);
|
|
||||||
expect(row.toCell).toBe(2);
|
|
||||||
expect(row.fromRow).toBe(1);
|
|
||||||
expect(row.toRow).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("keeps selected class on rows 1 and 2", function () {
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[0])
|
|
||||||
.hasClass('selected')).toBeFalsy();
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
|
||||||
.hasClass('selected')).toBeTruthy();
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[2])
|
|
||||||
.hasClass('selected')).toBeTruthy();
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child ')[3])
|
|
||||||
.hasClass('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user clicks a cell on the current range', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-cell.l1.r1')[5].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('row gets deselected', function () {
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
|
|
||||||
var newSelection = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(newSelection.fromCell).toBe(1);
|
|
||||||
expect(newSelection.fromRow).toBe(5);
|
|
||||||
expect(newSelection.toCell).toBe(1);
|
|
||||||
expect(newSelection.toRow).toBe(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('keep select class on row header', function () {
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user clicks a cell outside the current range', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-cell.l2.r2')[2].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('row gets deselected', function () {
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
|
|
||||||
var newSelection = selectedRanges[0];
|
|
||||||
|
|
||||||
expect(newSelection.fromCell).toBe(2);
|
|
||||||
expect(newSelection.fromRow).toBe(2);
|
|
||||||
expect(newSelection.toCell).toBe(2);
|
|
||||||
expect(newSelection.toRow).toBe(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('remove select class on "some-column-name" column header', function () {
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
|
|
||||||
.toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the user has a column selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var selectedRanges = [new Slick.Range(0, 1, 9, 1)];
|
|
||||||
cellSelectionModel.setSelectedRanges(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('no row should have the class "selected"', function () {
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[0]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[1]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[3]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[4]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
|
||||||
.toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user clicks multiple row headers", function () {
|
|
||||||
it("selects another row", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[4].click();
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[0].click();
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
expect(selectedRanges.length).toEqual(2);
|
|
||||||
|
|
||||||
var row1 = selectedRanges[0];
|
|
||||||
expect(row1.fromRow).toBe(4);
|
|
||||||
expect(row1.toRow).toBe(4);
|
|
||||||
|
|
||||||
var row2 = selectedRanges[1];
|
|
||||||
expect(row2.fromRow).toBe(0);
|
|
||||||
expect(row2.toRow).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when a column was already selected", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
|
|
||||||
cellSelectionModel.setSelectedRanges(selectedRanges);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects the column", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[0].click();
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expectOnlyTheFirstRowToBeSelected(selectedRanges);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the row is deselected through setSelectedRanges", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[4].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should remove the selected class", function () {
|
|
||||||
cellSelectionModel.setSelectedRanges([]);
|
|
||||||
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[4])
|
|
||||||
.hasClass('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("click a second time", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[1].click();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("removes the selected class", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[1].click();
|
|
||||||
expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1])
|
|
||||||
.hasClass('selected')).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("unselects the row", function () {
|
|
||||||
container.find('.slick-row .slick-cell:first-child')[1].click();
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(0);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function pressShiftArrow(keyCode) {
|
|
||||||
var pressEvent = new $.Event("keydown");
|
|
||||||
pressEvent.shiftKey = true;
|
|
||||||
pressEvent.ctrlKey = false;
|
|
||||||
pressEvent.altKey = false;
|
|
||||||
pressEvent.which = keyCode;
|
|
||||||
|
|
||||||
$(container.find('.grid-canvas')).trigger(pressEvent);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function expectOnlyTheFirstRowToBeSelected(selectedRanges) {
|
describe('when the user clicks a row header', function () {
|
||||||
var row = selectedRanges[0];
|
beforeEach(function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[1].click();
|
||||||
|
|
||||||
expect(selectedRanges.length).toEqual(1);
|
});
|
||||||
expect(row.fromCell).toBe(1);
|
it('selects the row', function () {
|
||||||
expect(row.toCell).toBe(2);
|
|
||||||
expect(row.fromRow).toBe(0);
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
expect(row.toRow).toBe(0);
|
var row = selectedRanges[0];
|
||||||
}
|
|
||||||
});
|
expect(selectedRanges.length).toEqual(1);
|
||||||
|
expect(row.fromCell).toBe(1);
|
||||||
|
expect(row.toCell).toBe(2);
|
||||||
|
expect(row.fromRow).toBe(1);
|
||||||
|
expect(row.toRow).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add selected class to parent of the span', function () {
|
||||||
|
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
||||||
|
.hasClass('selected')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks again the same row header', function () {
|
||||||
|
it('add selected class to parent of the span', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1].click();
|
||||||
|
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
||||||
|
.hasClass('selected')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and presses shift + down-arrow', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
pressShiftArrow(KEY_DOWN);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps the last row selected', function () {
|
||||||
|
expect(cellSelectionModel.getSelectedRanges().length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('grows the selection down', function () {
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
var row = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(1);
|
||||||
|
expect(row.fromCell).toBe(1);
|
||||||
|
expect(row.toCell).toBe(2);
|
||||||
|
expect(row.fromRow).toBe(1);
|
||||||
|
expect(row.toRow).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps selected class on rows 1 and 2', function () {
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[0])
|
||||||
|
.hasClass('selected')).toBeFalsy();
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[1])
|
||||||
|
.hasClass('selected')).toBeTruthy();
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[2])
|
||||||
|
.hasClass('selected')).toBeTruthy();
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child ')[3])
|
||||||
|
.hasClass('selected')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks a cell on the current range', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-cell.l1.r1')[5].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('row gets deselected', function () {
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var newSelection = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(newSelection.fromCell).toBe(1);
|
||||||
|
expect(newSelection.fromRow).toBe(5);
|
||||||
|
expect(newSelection.toCell).toBe(1);
|
||||||
|
expect(newSelection.toRow).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keep select class on row header', function () {
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
||||||
|
.toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks a cell outside the current range', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-cell.l2.r2')[2].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('row gets deselected', function () {
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
|
||||||
|
var newSelection = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(newSelection.fromCell).toBe(2);
|
||||||
|
expect(newSelection.fromRow).toBe(2);
|
||||||
|
expect(newSelection.toCell).toBe(2);
|
||||||
|
expect(newSelection.toRow).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove select class on "some-column-name" column header', function () {
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
|
||||||
|
.toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user has a column selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var selectedRanges = [new Slick.Range(0, 1, 9, 1)];
|
||||||
|
cellSelectionModel.setSelectedRanges(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no row should have the class "selected"', function () {
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[0]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[1]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[2]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[3]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[4]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
expect($(container.find('.slick-cell.l0.r0')[5]).hasClass('selected'))
|
||||||
|
.toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the user clicks multiple row headers', function () {
|
||||||
|
it('selects another row', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[4].click();
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[0].click();
|
||||||
|
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
expect(selectedRanges.length).toEqual(2);
|
||||||
|
|
||||||
|
var row1 = selectedRanges[0];
|
||||||
|
expect(row1.fromRow).toBe(4);
|
||||||
|
expect(row1.toRow).toBe(4);
|
||||||
|
|
||||||
|
var row2 = selectedRanges[1];
|
||||||
|
expect(row2.fromRow).toBe(0);
|
||||||
|
expect(row2.toRow).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a column was already selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var selectedRanges = [new Slick.Range(0, 0, 0, 1)];
|
||||||
|
cellSelectionModel.setSelectedRanges(selectedRanges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deselects the column', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[0].click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expectOnlyTheFirstRowToBeSelected(selectedRanges);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the row is deselected through setSelectedRanges', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[4].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove the selected class', function () {
|
||||||
|
cellSelectionModel.setSelectedRanges([]);
|
||||||
|
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[4])
|
||||||
|
.hasClass('selected')).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('click a second time', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[1].click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('removes the selected class', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[1].click();
|
||||||
|
expect($(container.find('.slick-row .slick-cell:first-child span[data-cell-type="row-header-selector"]')[1])
|
||||||
|
.hasClass('selected')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('unselects the row', function () {
|
||||||
|
container.find('.slick-row .slick-cell:first-child')[1].click();
|
||||||
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(0);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function pressShiftArrow(keyCode) {
|
||||||
|
var pressEvent = new $.Event('keydown');
|
||||||
|
pressEvent.shiftKey = true;
|
||||||
|
pressEvent.ctrlKey = false;
|
||||||
|
pressEvent.altKey = false;
|
||||||
|
pressEvent.which = keyCode;
|
||||||
|
|
||||||
|
$(container.find('.grid-canvas')).trigger(pressEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectOnlyTheFirstRowToBeSelected(selectedRanges) {
|
||||||
|
var row = selectedRanges[0];
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toEqual(1);
|
||||||
|
expect(row.fromCell).toBe(1);
|
||||||
|
expect(row.toCell).toBe(2);
|
||||||
|
expect(row.fromRow).toBe(0);
|
||||||
|
expect(row.toRow).toBe(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,507 +7,505 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define([
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
'sources/selection/xcell_selection_model',
|
import 'slickgrid.grid';
|
||||||
"slickgrid/slick.grid",
|
import Slick from 'slickgrid';
|
||||||
'slickgrid',
|
|
||||||
], function (XCellSelectionModel, SlickGrid, Slick) {
|
|
||||||
describe('XCellSelectionModel', function () {
|
|
||||||
var KEY_RIGHT = 39;
|
|
||||||
var KEY_LEFT = 37;
|
|
||||||
var KEY_UP = 38;
|
|
||||||
var KEY_DOWN = 40;
|
|
||||||
|
|
||||||
var container, grid;
|
describe('XCellSelectionModel', function () {
|
||||||
var oldWindowParent = window.parent;
|
var KEY_RIGHT = 39;
|
||||||
|
var KEY_LEFT = 37;
|
||||||
|
var KEY_UP = 38;
|
||||||
|
var KEY_DOWN = 40;
|
||||||
|
|
||||||
beforeEach(function () {
|
var container, grid;
|
||||||
window.parent = window;
|
var SlickGrid = Slick.Grid;
|
||||||
|
var oldWindowParent = window.parent;
|
||||||
|
|
||||||
var columns = [{
|
beforeEach(function () {
|
||||||
id: 'row-header-column',
|
window.parent = window;
|
||||||
name: 'row header column name',
|
|
||||||
selectable: false,
|
|
||||||
}, {
|
|
||||||
id: '1',
|
|
||||||
name: 'some-column-name',
|
|
||||||
pos: 0
|
|
||||||
}, {
|
|
||||||
id: 'second-column-id',
|
|
||||||
name: 'second column',
|
|
||||||
pos: 1
|
|
||||||
}, {
|
|
||||||
id: 'third-column-id',
|
|
||||||
name: 'third column',
|
|
||||||
pos: 2
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
var data = [];
|
var columns = [{
|
||||||
for (var i = 0; i < 10; i++) {
|
id: 'row-header-column',
|
||||||
data.push({
|
name: 'row header column name',
|
||||||
'some-column-name': 'some-value-' + i,
|
selectable: false,
|
||||||
'second column': 'second value ' + i,
|
}, {
|
||||||
'third column': 'third value ' + i,
|
id: '1',
|
||||||
'fourth column': 'fourth value ' + i,
|
name: 'some-column-name',
|
||||||
});
|
pos: 0
|
||||||
}
|
}, {
|
||||||
container = $("<div></div>");
|
id: 'second-column-id',
|
||||||
container.height(9999);
|
name: 'second column',
|
||||||
container.width(9999);
|
pos: 1
|
||||||
|
}, {
|
||||||
|
id: 'third-column-id',
|
||||||
|
name: 'third column',
|
||||||
|
pos: 2
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
grid = new SlickGrid(container, data, columns);
|
var data = [];
|
||||||
grid.setSelectionModel(new XCellSelectionModel());
|
for (var i = 0; i < 10; i++) {
|
||||||
$("body").append(container);
|
data.push({
|
||||||
|
'some-column-name': 'some-value-' + i,
|
||||||
|
'second column': 'second value ' + i,
|
||||||
|
'third column': 'third value ' + i,
|
||||||
|
'fourth column': 'fourth value ' + i,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
container = $("<div></div>");
|
||||||
|
container.height(9999);
|
||||||
|
container.width(9999);
|
||||||
|
|
||||||
|
grid = new SlickGrid(container, data, columns);
|
||||||
|
grid.setSelectionModel(new XCellSelectionModel());
|
||||||
|
$("body").append(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
grid.destroy();
|
||||||
|
container.remove();
|
||||||
|
window.parent = oldWindowParent;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('handleKeyDown', function () {
|
||||||
|
describe('when we press a random key', function () {
|
||||||
|
it('should not change the range', function () {
|
||||||
|
var range = new Slick.Range(1, 2);
|
||||||
|
grid.setActiveCell(1, 2);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressKey(72);
|
||||||
|
|
||||||
|
expect(grid.getSelectionModel().getSelectedRanges()[0]).toEqual(range);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
describe('when we press an arrow key ', function () {
|
||||||
grid.destroy();
|
it('should select the cell to the right', function () {
|
||||||
container.remove();
|
var range = new Slick.Range(1, 2);
|
||||||
window.parent = oldWindowParent;
|
grid.setActiveCell(1, 2);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressKey(KEY_RIGHT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 3, 1, 3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleKeyDown', function () {
|
describe('when we press shift', function () {
|
||||||
describe('when we press a random key', function () {
|
describe('and we press an arrow key', function () {
|
||||||
it('should not change the range', function () {
|
var scrollColumnIntoViewSpy, scrollRowIntoViewSpy;
|
||||||
var range = new Slick.Range(1, 2);
|
|
||||||
grid.setActiveCell(1, 2);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressKey(72);
|
|
||||||
|
|
||||||
expect(grid.getSelectionModel().getSelectedRanges()[0]).toEqual(range);
|
beforeEach(function () {
|
||||||
|
scrollColumnIntoViewSpy = spyOn(grid, 'scrollColumnIntoView');
|
||||||
|
scrollRowIntoViewSpy = spyOn(grid, 'scrollRowIntoView');
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('when we press an arrow key ', function () {
|
describe('the right arrow', function () {
|
||||||
it('should select the cell to the right', function () {
|
describe('when a cell is selected', function () {
|
||||||
var range = new Slick.Range(1, 2);
|
beforeEach(function () {
|
||||||
grid.setActiveCell(1, 2);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressKey(KEY_RIGHT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 3, 1, 3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when we press shift', function () {
|
|
||||||
describe('and we press an arrow key', function () {
|
|
||||||
var scrollColumnIntoViewSpy, scrollRowIntoViewSpy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
scrollColumnIntoViewSpy = spyOn(grid, 'scrollColumnIntoView');
|
|
||||||
scrollRowIntoViewSpy = spyOn(grid, 'scrollRowIntoView');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the right arrow', function () {
|
|
||||||
describe('when a cell is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(1, 1);
|
|
||||||
grid.setActiveCell(1, 1);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one to the right', function () {
|
|
||||||
expectOneSelectedRange(1, 1, 1, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the next column into view', function () {
|
|
||||||
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
|
||||||
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('pressing right again grows the range right', function () {
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 1, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('then pressing left keeps the original selection', function () {
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 1, 1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when a column is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(0, 1, 9, 1);
|
|
||||||
grid.setActiveCell(0, 1);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one column to the right', function () {
|
|
||||||
expectOneSelectedRange(0, 1, 9, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the next column into view', function () {
|
|
||||||
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
|
||||||
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the left arrow', function () {
|
|
||||||
describe('when a cell is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(1, 3);
|
|
||||||
grid.setActiveCell(1, 3);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one to the left', function () {
|
|
||||||
expectOneSelectedRange(1, 2, 1, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll previous column into view', function () {
|
|
||||||
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
|
||||||
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('pressing left again grows the range the left', function () {
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 1, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('then pressing right keeps the original selection', function () {
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 3, 1, 3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when a column is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(0, 2, 9, 2);
|
|
||||||
grid.setActiveCell(0, 2);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one column to the left', function () {
|
|
||||||
expectOneSelectedRange(0, 1, 9, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll previous column into view', function () {
|
|
||||||
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(1);
|
|
||||||
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the up arrow', function () {
|
|
||||||
describe('when a cell is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(2, 2);
|
|
||||||
grid.setActiveCell(2, 2);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one up', function () {
|
|
||||||
expectOneSelectedRange(1, 2, 2, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the row above into view', function () {
|
|
||||||
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
|
|
||||||
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('pressing up again grows the range up', function () {
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
|
|
||||||
expectOneSelectedRange(0, 2, 2, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('then pressing down keeps the original selection', function () {
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
|
|
||||||
expectOneSelectedRange(2, 2, 2, 2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when a row is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(2, 1, 2, 3);
|
|
||||||
grid.setActiveCell(2, 1);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one row up', function () {
|
|
||||||
expectOneSelectedRange(1, 1, 2, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the row above into view', function () {
|
|
||||||
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
|
|
||||||
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('the down arrow', function () {
|
|
||||||
describe('when a cell is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(2, 2);
|
|
||||||
grid.setActiveCell(2, 2);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one down', function () {
|
|
||||||
expectOneSelectedRange(2, 2, 3, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the row below into view', function () {
|
|
||||||
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
|
|
||||||
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('pressing down again grows the range down', function () {
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
|
|
||||||
expectOneSelectedRange(2, 2, 4, 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('then pressing up keeps the original selection', function () {
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
|
|
||||||
expectOneSelectedRange(2, 2, 2, 2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when a row is selected', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var range = new Slick.Range(2, 1, 2, 3);
|
|
||||||
grid.setActiveCell(2, 1);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('increases the range by one row down', function () {
|
|
||||||
expectOneSelectedRange(2, 1, 3, 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll the row below into view', function () {
|
|
||||||
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
|
|
||||||
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('rectangular selection works', function () {
|
|
||||||
|
|
||||||
it('in the down-and-rightward direction', function () {
|
|
||||||
var range = new Slick.Range(1, 1);
|
var range = new Slick.Range(1, 1);
|
||||||
grid.setActiveCell(1, 1);
|
grid.setActiveCell(1, 1);
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 4, 3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('in the up-and-leftward direction', function () {
|
it('increases the range by one to the right', function () {
|
||||||
var range = new Slick.Range(4, 3);
|
expectOneSelectedRange(1, 1, 1, 2);
|
||||||
grid.setActiveCell(4, 3);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 4, 3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('in the up-and-rightward direction', function () {
|
it('should scroll the next column into view', function () {
|
||||||
var range = new Slick.Range(4, 1);
|
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
||||||
grid.setActiveCell(4, 1);
|
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_UP);
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
pressShiftPlusKey(KEY_RIGHT);
|
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 4, 3);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('in the down-and-leftward direction', function () {
|
it('pressing right again grows the range right', function () {
|
||||||
var range = new Slick.Range(1, 3);
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
grid.setActiveCell(1, 3);
|
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
|
||||||
|
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
expectOneSelectedRange(1, 1, 1, 3);
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
});
|
||||||
pressShiftPlusKey(KEY_DOWN);
|
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
it('then pressing left keeps the original selection', function () {
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
|
||||||
expectOneSelectedRange(1, 1, 4, 3);
|
expectOneSelectedRange(1, 1, 1, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and we are on an edge', function () {
|
describe('when a column is selected', function () {
|
||||||
var range;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
range = new Slick.Range(2, 1);
|
var range = new Slick.Range(0, 1, 9, 1);
|
||||||
|
grid.setActiveCell(0, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one column to the right', function () {
|
||||||
|
expectOneSelectedRange(0, 1, 9, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll the next column into view', function () {
|
||||||
|
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
||||||
|
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('the left arrow', function () {
|
||||||
|
describe('when a cell is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(1, 3);
|
||||||
|
grid.setActiveCell(1, 3);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one to the left', function () {
|
||||||
|
expectOneSelectedRange(1, 2, 1, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll previous column into view', function () {
|
||||||
|
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(2);
|
||||||
|
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pressing left again grows the range the left', function () {
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 1, 1, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('then pressing right keeps the original selection', function () {
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 3, 1, 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a column is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(0, 2, 9, 2);
|
||||||
|
grid.setActiveCell(0, 2);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one column to the left', function () {
|
||||||
|
expectOneSelectedRange(0, 1, 9, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll previous column into view', function () {
|
||||||
|
expect(scrollColumnIntoViewSpy).toHaveBeenCalledWith(1);
|
||||||
|
expect(scrollRowIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('the up arrow', function () {
|
||||||
|
describe('when a cell is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(2, 2);
|
||||||
|
grid.setActiveCell(2, 2);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one up', function () {
|
||||||
|
expectOneSelectedRange(1, 2, 2, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll the row above into view', function () {
|
||||||
|
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
|
||||||
|
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pressing up again grows the range up', function () {
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
|
||||||
|
expectOneSelectedRange(0, 2, 2, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('then pressing down keeps the original selection', function () {
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
|
||||||
|
expectOneSelectedRange(2, 2, 2, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a row is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(2, 1, 2, 3);
|
||||||
grid.setActiveCell(2, 1);
|
grid.setActiveCell(2, 1);
|
||||||
grid.getSelectionModel().setSelectedRanges([range]);
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('we still have the selected range before we arrowed', function () {
|
it('increases the range by one row up', function () {
|
||||||
pressShiftPlusKey(KEY_LEFT);
|
expectOneSelectedRange(1, 1, 2, 3);
|
||||||
expectOneSelectedRange(2, 1, 2, 1);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should scroll the row above into view', function () {
|
||||||
|
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(1);
|
||||||
|
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('the down arrow', function () {
|
||||||
|
describe('when a cell is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(2, 2);
|
||||||
|
grid.setActiveCell(2, 2);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one down', function () {
|
||||||
|
expectOneSelectedRange(2, 2, 3, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll the row below into view', function () {
|
||||||
|
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
|
||||||
|
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('pressing down again grows the range down', function () {
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
|
||||||
|
expectOneSelectedRange(2, 2, 4, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('then pressing up keeps the original selection', function () {
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
|
||||||
|
expectOneSelectedRange(2, 2, 2, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a row is selected', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
var range = new Slick.Range(2, 1, 2, 3);
|
||||||
|
grid.setActiveCell(2, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increases the range by one row down', function () {
|
||||||
|
expectOneSelectedRange(2, 1, 3, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll the row below into view', function () {
|
||||||
|
expect(scrollRowIntoViewSpy).toHaveBeenCalledWith(3);
|
||||||
|
expect(scrollColumnIntoViewSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('rectangular selection works', function () {
|
||||||
|
|
||||||
|
it('in the down-and-rightward direction', function () {
|
||||||
|
var range = new Slick.Range(1, 1);
|
||||||
|
grid.setActiveCell(1, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 1, 4, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('in the up-and-leftward direction', function () {
|
||||||
|
var range = new Slick.Range(4, 3);
|
||||||
|
grid.setActiveCell(4, 3);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 1, 4, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('in the up-and-rightward direction', function () {
|
||||||
|
var range = new Slick.Range(4, 1);
|
||||||
|
grid.setActiveCell(4, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_UP);
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
pressShiftPlusKey(KEY_RIGHT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 1, 4, 3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('in the down-and-leftward direction', function () {
|
||||||
|
var range = new Slick.Range(1, 3);
|
||||||
|
grid.setActiveCell(1, 3);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_DOWN);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
|
||||||
|
expectOneSelectedRange(1, 1, 4, 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and we are on an edge', function () {
|
||||||
|
var range;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
range = new Slick.Range(2, 1);
|
||||||
|
grid.setActiveCell(2, 1);
|
||||||
|
grid.getSelectionModel().setSelectedRanges([range]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('we still have the selected range before we arrowed', function () {
|
||||||
|
pressShiftPlusKey(KEY_LEFT);
|
||||||
|
expectOneSelectedRange(2, 1, 2, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when we drag and drop', function () {
|
describe('when we drag and drop', function () {
|
||||||
var dd;
|
var dd;
|
||||||
// We could not find an elegant way to calculate this value
|
// We could not find an elegant way to calculate this value
|
||||||
// after changing window size we saw this was a constant value
|
// after changing window size we saw this was a constant value
|
||||||
var offsetLeftColumns = 100;
|
var offsetLeftColumns = 100;
|
||||||
|
|
||||||
function cellTopPosition($cell, rowNumber) {
|
function cellTopPosition($cell, rowNumber) {
|
||||||
return $(grid.getCanvasNode()).offset().top + $cell[0].scrollHeight * rowNumber;
|
return $(grid.getCanvasNode()).offset().top + $cell[0].scrollHeight * rowNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cellLeftPosition(columnNumber) {
|
function cellLeftPosition(columnNumber) {
|
||||||
return $(grid.getCanvasNode()).offset().left + offsetLeftColumns * columnNumber;
|
return $(grid.getCanvasNode()).offset().left + offsetLeftColumns * columnNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
var initialPosition = {cell: 3, row: 4};
|
||||||
|
var $cell = $($('.slick-cell.l3')[initialPosition.row]);
|
||||||
|
var event = {
|
||||||
|
target: $cell,
|
||||||
|
isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
|
||||||
|
isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
|
||||||
|
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation')
|
||||||
|
};
|
||||||
|
|
||||||
|
dd = {
|
||||||
|
grid: grid,
|
||||||
|
startX: cellLeftPosition(initialPosition.cell),
|
||||||
|
startY: cellTopPosition($cell, initialPosition.row)
|
||||||
|
};
|
||||||
|
|
||||||
|
grid.onDragStart.notify(dd, event, grid);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the drop happens outside of the grid', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var initialPosition = {cell: 3, row: 4};
|
var $cell = $($('.slick-cell.l1')[1]);
|
||||||
var $cell = $($('.slick-cell.l3')[initialPosition.row]);
|
var finalPosition = {cell: 1, row: 1};
|
||||||
|
|
||||||
var event = {
|
var event = {
|
||||||
target: $cell,
|
target: $cell,
|
||||||
isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
|
isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
|
||||||
isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
|
isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
|
||||||
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation')
|
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
|
||||||
|
|
||||||
|
pageX: cellLeftPosition(finalPosition.cell),
|
||||||
|
pageY: cellTopPosition($cell, finalPosition.row)
|
||||||
};
|
};
|
||||||
|
|
||||||
dd = {
|
grid.onDrag.notify(dd, event, grid);
|
||||||
grid: grid,
|
|
||||||
startX: cellLeftPosition(initialPosition.cell),
|
|
||||||
startY: cellTopPosition($cell, initialPosition.row)
|
|
||||||
};
|
|
||||||
|
|
||||||
grid.onDragStart.notify(dd, event, grid);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when the drop happens outside of the grid', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
var $cell = $($('.slick-cell.l1')[1]);
|
|
||||||
var finalPosition = {cell: 1, row: 1};
|
|
||||||
|
|
||||||
var event = {
|
|
||||||
target: $cell,
|
|
||||||
isPropagationStopped: jasmine.createSpy('isPropagationStopped').and.returnValue(false),
|
|
||||||
isImmediatePropagationStopped: jasmine.createSpy('isImmediatePropagationStopped').and.returnValue(false),
|
|
||||||
stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
|
|
||||||
|
|
||||||
pageX: cellLeftPosition(finalPosition.cell),
|
|
||||||
pageY: cellTopPosition($cell, finalPosition.row)
|
|
||||||
};
|
|
||||||
|
|
||||||
grid.onDrag.notify(dd, event, grid);
|
|
||||||
$(window).mouseup();
|
|
||||||
});
|
|
||||||
it('should call handleDragEnd from CellRangeSelector', function () {
|
|
||||||
var newRange = grid.getSelectionModel().getSelectedRanges();
|
|
||||||
|
|
||||||
expect(newRange.length).toBe(1);
|
|
||||||
|
|
||||||
expect(newRange[0].fromCell).toBe(1);
|
|
||||||
expect(newRange[0].toCell).toBe(3);
|
|
||||||
expect(newRange[0].fromRow).toBe(1);
|
|
||||||
expect(newRange[0].toRow).toBe(4);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when we mouse up and no drag and drop occured', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
grid.onDragEnd.notify = jasmine.createSpy('notify');
|
|
||||||
grid.onDragEnd.notify.calls.reset();
|
|
||||||
$(window).mouseup();
|
$(window).mouseup();
|
||||||
});
|
});
|
||||||
|
it('should call handleDragEnd from CellRangeSelector', function () {
|
||||||
|
var newRange = grid.getSelectionModel().getSelectedRanges();
|
||||||
|
|
||||||
it('do not notify onDragEnd', function () {
|
expect(newRange.length).toBe(1);
|
||||||
expect(grid.onDragEnd.notify).not.toHaveBeenCalled()
|
|
||||||
|
expect(newRange[0].fromCell).toBe(1);
|
||||||
|
expect(newRange[0].toCell).toBe(3);
|
||||||
|
expect(newRange[0].fromRow).toBe(1);
|
||||||
|
expect(newRange[0].toRow).toBe(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setSelectedRows', function () {
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
grid.getSelectionModel().setSelectedRanges(
|
|
||||||
[new Slick.Range(1, 1, 1, 1)]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when passed an empty array', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
grid.getSelectionModel().setSelectedRows([]);
|
|
||||||
});
|
|
||||||
it('clears ranges', function () {
|
|
||||||
var newRanges = grid.getSelectionModel().getSelectedRanges();
|
|
||||||
expect(newRanges.length).toEqual(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sets ranges corresponding to rows', function () {
|
|
||||||
grid.getSelectionModel().setSelectedRows([0, 2]);
|
|
||||||
|
|
||||||
var selectedRanges = grid.getSelectionModel().getSelectedRanges();
|
|
||||||
|
|
||||||
expect(selectedRanges.length).toBe(2);
|
|
||||||
expectRangeToMatch(selectedRanges[0], 0, 1, 0, 3);
|
|
||||||
expectRangeToMatch(selectedRanges[1], 2, 1, 2, 3);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function pressKey(keyCode) {
|
|
||||||
var pressEvent = new $.Event("keydown");
|
|
||||||
pressEvent.which = keyCode;
|
|
||||||
|
|
||||||
$(container.find('.grid-canvas')).trigger(pressEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function pressShiftPlusKey(keyCode) {
|
|
||||||
var pressEvent = new $.Event("keydown");
|
|
||||||
pressEvent.shiftKey = true;
|
|
||||||
pressEvent.which = keyCode;
|
|
||||||
|
|
||||||
$(container.find('.grid-canvas')).trigger(pressEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectOneSelectedRange(fromRow, fromCell, toRow, toCell) {
|
|
||||||
var selectedRanges = grid.getSelectionModel().getSelectedRanges();
|
|
||||||
expect(selectedRanges.length).toBe(1);
|
|
||||||
expectRangeToMatch(selectedRanges[0], fromRow, fromCell, toRow, toCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
function expectRangeToMatch(range, fromRow, fromCell, toRow, toCell) {
|
|
||||||
expect(range.fromRow).toBe(fromRow);
|
|
||||||
expect(range.toRow).toBe(toRow);
|
|
||||||
expect(range.fromCell).toBe(fromCell);
|
|
||||||
expect(range.toCell).toBe(toCell);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})
|
|
||||||
;
|
describe('when we mouse up and no drag and drop occured', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
grid.onDragEnd.notify = jasmine.createSpy('notify');
|
||||||
|
grid.onDragEnd.notify.calls.reset();
|
||||||
|
$(window).mouseup();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('do not notify onDragEnd', function () {
|
||||||
|
expect(grid.onDragEnd.notify).not.toHaveBeenCalled()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setSelectedRows', function () {
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
grid.getSelectionModel().setSelectedRanges(
|
||||||
|
[new Slick.Range(1, 1, 1, 1)]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when passed an empty array', function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
grid.getSelectionModel().setSelectedRows([]);
|
||||||
|
});
|
||||||
|
it('clears ranges', function () {
|
||||||
|
var newRanges = grid.getSelectionModel().getSelectedRanges();
|
||||||
|
expect(newRanges.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sets ranges corresponding to rows', function () {
|
||||||
|
grid.getSelectionModel().setSelectedRows([0, 2]);
|
||||||
|
|
||||||
|
var selectedRanges = grid.getSelectionModel().getSelectedRanges();
|
||||||
|
|
||||||
|
expect(selectedRanges.length).toBe(2);
|
||||||
|
expectRangeToMatch(selectedRanges[0], 0, 1, 0, 3);
|
||||||
|
expectRangeToMatch(selectedRanges[1], 2, 1, 2, 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function pressKey(keyCode) {
|
||||||
|
var pressEvent = new $.Event("keydown");
|
||||||
|
pressEvent.which = keyCode;
|
||||||
|
|
||||||
|
$(container.find('.grid-canvas')).trigger(pressEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pressShiftPlusKey(keyCode) {
|
||||||
|
var pressEvent = new $.Event("keydown");
|
||||||
|
pressEvent.shiftKey = true;
|
||||||
|
pressEvent.which = keyCode;
|
||||||
|
|
||||||
|
$(container.find('.grid-canvas')).trigger(pressEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectOneSelectedRange(fromRow, fromCell, toRow, toCell) {
|
||||||
|
var selectedRanges = grid.getSelectionModel().getSelectedRanges();
|
||||||
|
expect(selectedRanges.length).toBe(1);
|
||||||
|
expectRangeToMatch(selectedRanges[0], fromRow, fromCell, toRow, toCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
function expectRangeToMatch(range, fromRow, fromCell, toRow, toCell) {
|
||||||
|
expect(range.fromRow).toBe(fromRow);
|
||||||
|
expect(range.toRow).toBe(toRow);
|
||||||
|
expect(range.fromCell).toBe(fromCell);
|
||||||
|
expect(range.toCell).toBe(toCell);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,71 +7,69 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define(["jquery",
|
import $ from "jquery";
|
||||||
"slickgrid/slick.grid",
|
import SlickGrid from "slickgrid.grid";
|
||||||
"sources/selection/xcell_selection_model",
|
import XCellSelectionModel from "sources/selection/xcell_selection_model";
|
||||||
"sources/slickgrid/cell_selector",
|
import CellSelector from "sources/slickgrid/cell_selector";
|
||||||
"sources/selection/range_selection_helper"
|
import RangeSelectionHelper from "sources/selection/range_selection_helper";
|
||||||
],
|
|
||||||
function ($, SlickGrid, XCellSelectionModel, CellSelector, RangeSelectionHelper) {
|
|
||||||
describe("CellSelector", function () {
|
|
||||||
var container, columns, cellSelector, data, cellSelectionModel, grid;
|
|
||||||
beforeEach(function () {
|
|
||||||
container = $("<div></div>");
|
|
||||||
container.height(9999);
|
|
||||||
container.width(9999);
|
|
||||||
columns = [{
|
|
||||||
name: 'some-column-name',
|
|
||||||
}, {
|
|
||||||
name: 'second column',
|
|
||||||
}];
|
|
||||||
|
|
||||||
cellSelector = new CellSelector();
|
describe("CellSelector", function () {
|
||||||
|
var container, columns, cellSelector, data, cellSelectionModel, grid;
|
||||||
|
beforeEach(function () {
|
||||||
|
container = $("<div></div>");
|
||||||
|
container.height(9999);
|
||||||
|
container.width(9999);
|
||||||
|
columns = [{
|
||||||
|
name: 'some-column-name',
|
||||||
|
}, {
|
||||||
|
name: 'second column',
|
||||||
|
}];
|
||||||
|
|
||||||
data = [];
|
cellSelector = new CellSelector();
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
|
||||||
}
|
|
||||||
grid = new SlickGrid(container, data, columns);
|
|
||||||
|
|
||||||
cellSelectionModel = new XCellSelectionModel();
|
data = [];
|
||||||
grid.setSelectionModel(cellSelectionModel);
|
for (var i = 0; i < 10; i++) {
|
||||||
|
data.push({'some-column-name': 'some-value-' + i, 'second column': 'second value ' + i});
|
||||||
|
}
|
||||||
|
grid = new Slick.Grid(container, data, columns);
|
||||||
|
|
||||||
grid.registerPlugin(cellSelector);
|
cellSelectionModel = new XCellSelectionModel();
|
||||||
grid.invalidate();
|
grid.setSelectionModel(cellSelectionModel);
|
||||||
|
|
||||||
$("body").append(container);
|
grid.registerPlugin(cellSelector);
|
||||||
});
|
grid.invalidate();
|
||||||
|
|
||||||
afterEach(function () {
|
$("body").append(container);
|
||||||
$("body").find(container).remove();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("when the user clicks or tabs to a cell", function () {
|
afterEach(function () {
|
||||||
it("sets the selected range to that cell", function () {
|
$("body").find(container).remove();
|
||||||
var row = 1, column = 0;
|
});
|
||||||
$(container.find(".slick-row .slick-cell.l" + column)[row]).click();
|
|
||||||
|
|
||||||
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
describe("when the user clicks or tabs to a cell", function () {
|
||||||
expect(selectedRanges.length).toBe(1);
|
it("sets the selected range to that cell", function () {
|
||||||
expect(selectedRanges[0].fromCell).toBe(0);
|
var row = 1, column = 0;
|
||||||
expect(selectedRanges[0].toCell).toBe(0);
|
$(container.find(".slick-row .slick-cell.l" + column)[row]).click();
|
||||||
expect(selectedRanges[0].fromRow).toBe(1);
|
|
||||||
expect(selectedRanges[0].toRow).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("deselects previously selected ranges", function () {
|
var selectedRanges = cellSelectionModel.getSelectedRanges();
|
||||||
var row2Range = RangeSelectionHelper.rangeForRow(grid, 2);
|
expect(selectedRanges.length).toBe(1);
|
||||||
var ranges = RangeSelectionHelper.addRange(cellSelectionModel.getSelectedRanges(),
|
expect(selectedRanges[0].fromCell).toBe(0);
|
||||||
row2Range);
|
expect(selectedRanges[0].toCell).toBe(0);
|
||||||
cellSelectionModel.setSelectedRanges(ranges);
|
expect(selectedRanges[0].fromRow).toBe(1);
|
||||||
|
expect(selectedRanges[0].toRow).toBe(1);
|
||||||
var row = 4, column = 1;
|
|
||||||
$(container.find(".slick-row .slick-cell.l" + column)[row]).click();
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.isRangeSelected(cellSelectionModel.getSelectedRanges(), row2Range))
|
|
||||||
.toBe(false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
it("deselects previously selected ranges", function () {
|
||||||
|
var row2Range = RangeSelectionHelper.rangeForRow(grid, 2);
|
||||||
|
var ranges = RangeSelectionHelper.addRange(cellSelectionModel.getSelectedRanges(),
|
||||||
|
row2Range);
|
||||||
|
cellSelectionModel.setSelectedRanges(ranges);
|
||||||
|
|
||||||
|
var row = 4, column = 1;
|
||||||
|
$(container.find(".slick-row .slick-cell.l" + column)[row]).click();
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.isRangeSelected(cellSelectionModel.getSelectedRanges(), row2Range))
|
||||||
|
.toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -7,137 +7,139 @@
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
define([
|
import HandleQueryOutputKeyboardEvent from 'sources/slickgrid/event_handlers/handle_query_output_keyboard_event';
|
||||||
'sources/slickgrid/event_handlers/handle_query_output_keyboard_event',
|
import clipboard from 'sources/selection/clipboard';
|
||||||
'sources/selection/clipboard',
|
import RangeSelectionHelper from 'sources/selection/range_selection_helper';
|
||||||
'sources/selection/range_selection_helper',
|
import XCellSelectionModel from 'sources/selection/xcell_selection_model';
|
||||||
'sources/selection/xcell_selection_model',
|
import Slick from 'slickgrid';
|
||||||
'slickgrid'
|
import 'slickgrid.grid';
|
||||||
],
|
|
||||||
function (handleQueryOutputKeyboardEvent, clipboard, RangeSelectionHelper, XCellSelectionModel) {
|
|
||||||
var Slick = window.Slick;
|
|
||||||
|
|
||||||
describe('#handleQueryOutputKeyboardEvent', function () {
|
|
||||||
var event, view, grid, slickEvent;
|
describe('#handleQueryOutputKeyboardEvent', function () {
|
||||||
|
var event, view, grid, slickEvent;
|
||||||
|
var SlickGrid = Slick.Grid;
|
||||||
|
var handleQueryOutputKeyboardEvent;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
event = {
|
||||||
|
shiftKey: false,
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
which: -1,
|
||||||
|
keyCode: -1,
|
||||||
|
preventDefault: jasmine.createSpy('preventDefault')
|
||||||
|
};
|
||||||
|
|
||||||
|
var data = [['', '0,0-cell-content', '0,1-cell-content'],
|
||||||
|
['', '1,0-cell-content', '1,1-cell-content'],
|
||||||
|
['', '2,0-cell-content', '2,1-cell-content']];
|
||||||
|
var columnDefinitions = [{name: 'checkboxColumn'}, {pos: 1, name: 'firstColumn'}, {
|
||||||
|
pos: 2,
|
||||||
|
name: 'secondColumn'
|
||||||
|
}];
|
||||||
|
grid = new SlickGrid($('<div></div>'), data, columnDefinitions);
|
||||||
|
grid.setSelectionModel(new XCellSelectionModel());
|
||||||
|
|
||||||
|
slickEvent = {
|
||||||
|
grid: grid
|
||||||
|
};
|
||||||
|
|
||||||
|
view = {};
|
||||||
|
spyOn(clipboard, 'copyTextToClipboard');
|
||||||
|
handleQueryOutputKeyboardEvent = HandleQueryOutputKeyboardEvent.bind(window);
|
||||||
|
debugger
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when a range is selected", function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
event = {
|
grid.getSelectionModel().setSelectedRanges([
|
||||||
shiftKey: false,
|
RangeSelectionHelper.rangeForRow(grid, 0),
|
||||||
ctrlKey: false,
|
RangeSelectionHelper.rangeForRow(grid, 2),
|
||||||
metaKey: false,
|
]);
|
||||||
which: -1,
|
|
||||||
keyCode: -1,
|
|
||||||
preventDefault: jasmine.createSpy('preventDefault')
|
|
||||||
};
|
|
||||||
|
|
||||||
var data = [['', '0,0-cell-content', '0,1-cell-content'],
|
|
||||||
['', '1,0-cell-content', '1,1-cell-content'],
|
|
||||||
['', '2,0-cell-content', '2,1-cell-content']];
|
|
||||||
var columnDefinitions = [{name: 'checkboxColumn'}, {pos: 1, name: 'firstColumn'}, {
|
|
||||||
pos: 2,
|
|
||||||
name: 'secondColumn'
|
|
||||||
}];
|
|
||||||
grid = new Slick.Grid($('<div></div>'), data, columnDefinitions);
|
|
||||||
grid.setSelectionModel(new XCellSelectionModel());
|
|
||||||
|
|
||||||
slickEvent = {
|
|
||||||
grid: grid
|
|
||||||
};
|
|
||||||
|
|
||||||
view = {};
|
|
||||||
spyOn(clipboard, 'copyTextToClipboard');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when a range is selected", function () {
|
describe("pressing Command + C", function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
grid.getSelectionModel().setSelectedRanges([
|
event.metaKey = true;
|
||||||
RangeSelectionHelper.rangeForRow(grid, 0),
|
event.keyCode = 67;
|
||||||
RangeSelectionHelper.rangeForRow(grid, 2),
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("pressing Command + C", function () {
|
it("copies the cell content to the clipboard", function () {
|
||||||
beforeEach(function () {
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
event.metaKey = true;
|
|
||||||
event.keyCode = 67;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("copies the cell content to the clipboard", function () {
|
expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith("'0,0-cell-content','0,1-cell-content'\n'2,0-cell-content','2,1-cell-content'");
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
|
||||||
|
|
||||||
expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith("'0,0-cell-content','0,1-cell-content'\n'2,0-cell-content','2,1-cell-content'");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("pressing Ctrl + C", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
event.ctrlKey = true;
|
|
||||||
event.keyCode = 67;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("copies the cell content to the clipboard", function () {
|
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
|
||||||
|
|
||||||
expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith("'0,0-cell-content','0,1-cell-content'\n'2,0-cell-content','2,1-cell-content'");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("pressing Command + A", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
event.metaKey = true;
|
|
||||||
event.keyCode = 65;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the entire grid to ranges", function () {
|
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
|
||||||
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("pressing Ctrl + A", function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
event.ctrlKey = true;
|
|
||||||
event.keyCode = 65;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the entire grid to ranges", function () {
|
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
|
||||||
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when no ranges are selected", function () {
|
describe("pressing Ctrl + C", function () {
|
||||||
describe("pressing Command + A", function () {
|
beforeEach(function () {
|
||||||
beforeEach(function () {
|
event.ctrlKey = true;
|
||||||
event.metaKey = true;
|
event.keyCode = 67;
|
||||||
event.keyCode = 65;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the entire grid to ranges", function () {
|
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
|
||||||
|
|
||||||
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
|
||||||
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("pressing Ctrl + A", function () {
|
it("copies the cell content to the clipboard", function () {
|
||||||
beforeEach(function () {
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
event.ctrlKey = true;
|
|
||||||
event.keyCode = 65;
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the entire grid to ranges", function () {
|
expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith("'0,0-cell-content','0,1-cell-content'\n'2,0-cell-content','2,1-cell-content'");
|
||||||
handleQueryOutputKeyboardEvent(event, slickEvent);
|
});
|
||||||
|
});
|
||||||
|
|
||||||
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
describe("pressing Command + A", function () {
|
||||||
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
beforeEach(function () {
|
||||||
});
|
event.metaKey = true;
|
||||||
|
event.keyCode = 65;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("selects the entire grid to ranges", function () {
|
||||||
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
||||||
|
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pressing Ctrl + A", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
event.ctrlKey = true;
|
||||||
|
event.keyCode = 65;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("selects the entire grid to ranges", function () {
|
||||||
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
||||||
|
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
describe("when no ranges are selected", function () {
|
||||||
|
describe("pressing Command + A", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
event.metaKey = true;
|
||||||
|
event.keyCode = 65;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("selects the entire grid to ranges", function () {
|
||||||
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
||||||
|
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pressing Ctrl + A", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
event.ctrlKey = true;
|
||||||
|
event.keyCode = 65;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("selects the entire grid to ranges", function () {
|
||||||
|
handleQueryOutputKeyboardEvent(event, slickEvent);
|
||||||
|
|
||||||
|
expect(RangeSelectionHelper.isEntireGridSelected(grid)).toBeTruthy();
|
||||||
|
expect(grid.getSelectionModel().getSelectedRanges().length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// pgAdmin 4 - PostgreSQL Tools
|
|
||||||
//
|
|
||||||
// Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
|
||||||
// This software is released under the PostgreSQL Licence
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
var allTestFiles = [];
|
|
||||||
var TEST_REGEXP = /(spec|test)\.js$/i;
|
|
||||||
|
|
||||||
// Get a list of all the test files to include
|
|
||||||
Object.keys(window.__karma__.files).forEach(function (file) {
|
|
||||||
if (TEST_REGEXP.test(file)) {
|
|
||||||
// Normalize paths to RequireJS module names.
|
|
||||||
// If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
|
|
||||||
// then do not normalize the paths
|
|
||||||
var normalizedTestModule = file.replace(/^\/base\/|\.js$/g, '');
|
|
||||||
allTestFiles.push(normalizedTestModule)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var sourcesDir = '/base/pgadmin/static/';
|
|
||||||
require.config({
|
|
||||||
// Karma serves files under /base, which is the basePath from your config file
|
|
||||||
baseUrl: '/base',
|
|
||||||
|
|
||||||
paths: {
|
|
||||||
'pgadmin': sourcesDir + 'js/pgadmin',
|
|
||||||
'alertify': sourcesDir + 'vendor/alertifyjs/alertify',
|
|
||||||
'jquery': sourcesDir + 'vendor/jquery/jquery-1.11.2',
|
|
||||||
'jquery.ui': sourcesDir + 'vendor/jquery-ui/jquery-ui-1.11.3',
|
|
||||||
'jquery.event.drag': sourcesDir + 'vendor/jquery-ui/jquery.event.drag-2.2',
|
|
||||||
'underscore': sourcesDir + 'vendor/underscore/underscore',
|
|
||||||
'underscore.string': sourcesDir + 'vendor/underscore/underscore.string',
|
|
||||||
'slickgrid': sourcesDir + 'vendor/slickgrid/slick.core',
|
|
||||||
'slickgrid/slick.grid': sourcesDir + 'vendor/slickgrid/slick.grid',
|
|
||||||
'translations': '/base/regression/javascript/fake_translations',
|
|
||||||
'pgadmin.browser.endpoints': '/base/regression/javascript/fake_endpoints',
|
|
||||||
'sources': sourcesDir + 'js',
|
|
||||||
'browser': '/base/pgadmin/browser/static/js'
|
|
||||||
},
|
|
||||||
|
|
||||||
shim: {
|
|
||||||
'underscore': {
|
|
||||||
exports: '_'
|
|
||||||
},
|
|
||||||
"slickgrid": {
|
|
||||||
"deps": [
|
|
||||||
'jquery', "jquery.ui", "jquery.event.drag"
|
|
||||||
],
|
|
||||||
"exports": 'window.Slick'
|
|
||||||
},
|
|
||||||
"slickgrid/slick.grid": {
|
|
||||||
"deps": [
|
|
||||||
'jquery', "jquery.ui", "jquery.event.drag", "slickgrid"
|
|
||||||
],
|
|
||||||
"exports": 'window.Slick.Grid'
|
|
||||||
},
|
|
||||||
"sources/slickgrid/pgslick.cellrangedecorator": {
|
|
||||||
"deps": [
|
|
||||||
"jquery"
|
|
||||||
],
|
|
||||||
"exports": 'PGRowRangeDecorator'
|
|
||||||
},
|
|
||||||
"sources/slickgrid/pgslick.cellrangeselector": {
|
|
||||||
"deps": [
|
|
||||||
"jquery", "sources/slickgrid/pgslick.cellrangedecorator"
|
|
||||||
],
|
|
||||||
"exports": 'PGCellRangeSelector'
|
|
||||||
},
|
|
||||||
"sources/selection/xcell_selection_model": {
|
|
||||||
"deps": [
|
|
||||||
"jquery", "sources/slickgrid/pgslick.cellrangeselector"
|
|
||||||
],
|
|
||||||
"exports": 'XCellSelectionModel'
|
|
||||||
},
|
|
||||||
"backbone": {
|
|
||||||
"deps": ['underscore', 'jquery'],
|
|
||||||
"exports": 'Backbone'
|
|
||||||
},
|
|
||||||
"backbone.paginator": {
|
|
||||||
"deps": ['underscore', 'jquery', 'backbone']
|
|
||||||
},
|
|
||||||
"bootstrap": {
|
|
||||||
"deps": ['jquery'],
|
|
||||||
},
|
|
||||||
"backgrid": {
|
|
||||||
"deps": ['backform'],
|
|
||||||
"exports": 'Backgrid',
|
|
||||||
},
|
|
||||||
"backgrid.select.all": {
|
|
||||||
"deps": ['backgrid']
|
|
||||||
},
|
|
||||||
"backgrid.paginator": {
|
|
||||||
"deps": ['backgrid', 'backbone.paginator']
|
|
||||||
},
|
|
||||||
"backgrid.filter": {
|
|
||||||
"deps": ['backgrid']
|
|
||||||
},
|
|
||||||
"backgrid.sizeable.columns": {
|
|
||||||
"deps": ['backgrid']
|
|
||||||
},
|
|
||||||
"bootstrap.switch": {
|
|
||||||
"deps": ['jquery', 'bootstrap'],
|
|
||||||
"exports": 'jQuery.fn.bootstrapSwitch'
|
|
||||||
},
|
|
||||||
"select2": {
|
|
||||||
"deps": ['jquery'],
|
|
||||||
"exports": 'jQuery.fn.select2'
|
|
||||||
},
|
|
||||||
"bootstrap.datepicker": {
|
|
||||||
"deps": ['jquery', 'bootstrap'],
|
|
||||||
"exports": 'jQuery.fn.datepicker'
|
|
||||||
},
|
|
||||||
"bootstrap.datetimepicker": {
|
|
||||||
"deps": ['jquery', 'bootstrap', 'moment'],
|
|
||||||
"exports": 'jQuery.fn.datetimepicker'
|
|
||||||
},
|
|
||||||
"pgadmin.backgrid": {
|
|
||||||
"deps": ["backgrid", "bootstrap.datetimepicker", "bootstrap.switch"],
|
|
||||||
},
|
|
||||||
"pgadmin.backform": {
|
|
||||||
"deps": ['backform', "pgadmin.backgrid", "select2"],
|
|
||||||
},
|
|
||||||
"jquery.event.drag": {
|
|
||||||
"deps": ['jquery'], "exports": 'jQuery.fn.drag'
|
|
||||||
},
|
|
||||||
"jquery.ui": {"deps": ['jquery']}
|
|
||||||
},
|
|
||||||
|
|
||||||
// dynamically load all test files
|
|
||||||
deps: allTestFiles,
|
|
||||||
|
|
||||||
// we have to kickoff jasmine, as it is asynchronous
|
|
||||||
callback: window.__karma__.start
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -4,6 +4,7 @@ testscenarios==0.5.0
|
|||||||
testtools==2.0.0
|
testtools==2.0.0
|
||||||
traceback2==1.4.0
|
traceback2==1.4.0
|
||||||
unittest2==1.1.0
|
unittest2==1.1.0
|
||||||
|
mock~=2.0.0
|
||||||
|
|
||||||
# Leave this at the end because there is a bug where the '--install-option' is applied to all subsequent requirements
|
# Leave this at the end because there is a bug where the '--install-option' is applied to all subsequent requirements
|
||||||
chromedriver_installer==0.0.6 --install-option='--chromedriver-version=2.29'
|
chromedriver_installer==0.0.6 --install-option='--chromedriver-version=2.29'
|
||||||
|
|||||||
29
web/webpack.config.js
Normal file
29
web/webpack.config.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
context: __dirname + '/pgadmin/static/jsx',
|
||||||
|
entry: './components.jsx',
|
||||||
|
output: {
|
||||||
|
libraryTarget: 'amd',
|
||||||
|
path: __dirname + '/pgadmin/static/js/generated',
|
||||||
|
filename: 'reactComponents.js',
|
||||||
|
},
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [{
|
||||||
|
test: /\.jsx?$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: ['es2015', 'react'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.js', '.jsx'],
|
||||||
|
},
|
||||||
|
};
|
||||||
71
web/webpack.test.config.js
Normal file
71
web/webpack.test.config.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
const sourcesDir = path.resolve(__dirname, 'pgadmin/static');
|
||||||
|
const regressionDir = path.resolve(__dirname, 'regression');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: [
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
$: 'jquery',
|
||||||
|
jQuery: 'jquery',
|
||||||
|
_: 'underscore',
|
||||||
|
'underscore.string': 'underscore.string',
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.jsx?$/,
|
||||||
|
exclude: [/node_modules/, /vendor/],
|
||||||
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: ['es2015'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /.*slickgrid\/slick\.(?!core)*/,
|
||||||
|
loader: 'imports-loader?' +
|
||||||
|
'jquery.ui' +
|
||||||
|
',jquery.event.drag' +
|
||||||
|
',slickgrid',
|
||||||
|
}, {
|
||||||
|
test: /.*slickgrid\/plugins\/slick\.rowselectionmodel/,
|
||||||
|
loader: 'imports-loader?' +
|
||||||
|
'jquery.ui' +
|
||||||
|
',jquery.event.drag' +
|
||||||
|
',slickgrid' +
|
||||||
|
'!exports-loader?' +
|
||||||
|
'Slick.RowSelectionModel',
|
||||||
|
}, {
|
||||||
|
test: /.*slickgrid\/slick\.core.*/,
|
||||||
|
loader: 'imports-loader?' +
|
||||||
|
'jquery.ui' +
|
||||||
|
',jquery.event.drag' +
|
||||||
|
'!exports-loader?' +
|
||||||
|
'Slick',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'alertify': sourcesDir + '/vendor/alertifyjs/alertify',
|
||||||
|
'jquery': sourcesDir + '/vendor/jquery/jquery-1.11.2',
|
||||||
|
'jquery.ui': sourcesDir + '/vendor/jquery-ui/jquery-ui-1.11.3',
|
||||||
|
'jquery.event.drag': sourcesDir + '/vendor/jquery-ui/jquery.event.drag-2.2',
|
||||||
|
'sources': sourcesDir + '/js',
|
||||||
|
'underscore.string': sourcesDir + '/vendor/underscore/underscore.string',
|
||||||
|
'translations': regressionDir + '/javascript/fake_translations',
|
||||||
|
'pgadmin.browser.endpoints': regressionDir + '/javascript/fake_endpoints',
|
||||||
|
'slickgrid': sourcesDir + '/vendor/slickgrid/slick.core',
|
||||||
|
'slickgrid.grid': sourcesDir + '/vendor/slickgrid/slick.grid',
|
||||||
|
'slickgrid.rowselectionmodel': sourcesDir + '/vendor/slickgrid/plugins/slick.rowselectionmodel',
|
||||||
|
'browser': path.resolve(__dirname, 'pgadmin/browser/static/js'),
|
||||||
|
'pgadmin': sourcesDir + '/js/pgadmin',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
4526
web/yarn.lock
4526
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user