<commit_before>/*
    Version 2.3.4
    The MIT License (MIT)

    Simple jQuery Slider is just what is says it is: a simple but powerfull jQuery slider.
    Copyright (c) 2014 Dirk Groenen - Bitlabs Development

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
*/
(function($){
    var simpleSlider = function(element, useroptions){
        // Set some variables
        var obj = this,
            sliderInterval = null;
        obj.currentSlide = 0;
        obj.totalSlides = 0;

        // Extend default options with user options
        useroptions = (useroptions === undefined) ? {} : useroptions;
        var options = $.extend({
            slidesContainer: element,
            slides: '.slide',
            slideTracker: true,
            slideTrackerID: 'slideposition',
            slideOnInterval: true,
            interval: 5000,
            swipe: true,
            animateDuration: 1000,
            animationEasing: 'ease',
            pauseOnHover: false,
            updateTransit: true // Change this to false is you dont want the slider to update the transit useTransitionEnd to true
        }, useroptions);

        // Init the slider
        obj.init = function(){
            // If transit is included and useTransitionEnd == false we will change this to true (better animation performance).
            // Unless the user changed updateTransit to false
            if(options.updateTransit && $.support.transition && jQuery().transition && !$.transit.useTransitionEnd){
                $.transit.useTransitionEnd = true;
            }

            // Find the slides in the sliderdom and add the index attribute
            $(options.slidesContainer).find(options.slides).each(function(index){
                // Give each slide a data-index so we can control it later on
                $(this).attr('data-index', index);

                 // A fixed width is needed for the IE left animation. Here we give each slide a width
                $(this).css({
                    x: index*100+'%',
                    width: $(this).outerWidth()
                });
            });

            // Count the total slides
            obj.totalSlides = $(options.slidesContainer).find(options.slides).length;

            // Place the slideTracker after the container if enabled in the options
            if(options.slideTracker){
                // Add the slideposition div and add the indicators
                $(options.slidesContainer).after("

");
                for(var x = 0; x < obj.totalSlides;x++){
                    $('#'+ options.slideTrackerID +' ul').append('

');
                }
                $('#'+ options.slideTrackerID +' ul li[data-index="'+obj.currentSlide+'"]').addClass('active');

                // Make the slide indicators clickable
                $("#"+ options.slideTrackerID +" ul li").click(function(){
                    if(!($(this).hasClass("active")))
                        obj.nextSlide($(this).data('index'));
                });
            }

            // Start the slider interval if enabled in options
            if(options.slideOnInterval){
                setSliderInterval();
            }

            // Change the cursor with a grabbing hand that simulates the swiping on desktops
            if(options.swipe && jQuery().swipe){
                $(options.slidesContainer).css('cursor','-webkit-grab');
                $(options.slidesContainer).css('cursor','-moz-grab');
                $(options.slidesContainer).css('cursor','grab');

                $(options.slidesContainer).mousedown(function(){
                    $(options.slidesContainer).css('cursor','-webkit-grabbing');
                    $(options.slidesContainer).css('cursor','-moz-grabbing');
                    $(options.slidesContainer).css('cursor','grabbing');
                });

                $(options.slidesContainer).mouseup(function(){
                    $(options.slidesContainer).css('cursor','-webkit-grab');
                    $(options.slidesContainer).css('cursor','-moz-grab');
                    $(options.slidesContainer).css('cursor','grab');
                });

                // Add the swipe actions to the container
                $(options.slidesContainer).swipe({
                    swipeLeft: function(){
                        obj.nextSlide();
                    },
                    swipeRight: function(){
                        obj.prevSlide();
                    }
                });
            }
            else if(!jQuery().swipe && options.swipe === true){
                console.warn("Duo the missing TouchSwipe.js swipe has been disabled.");
            }
        }();

        // Bind the function that recalculates the width of each slide on a resize.
        $(window).resize(function(){
            $(options.slidesContainer).find(options.slides).each(function(index){
                // Reset width; otherwise it will keep the same width as before
                $(this).css('width','');
                $(this).css({x: index*100+'%',width: $(this).outerWidth()});
            });
        });

        // Controller of the interval
        function setSliderInterval(){
            clearInterval(sliderInterval);
            sliderInterval = setInterval(function(){
                obj.nextSlide();
            },options.interval);
        };

        // Go to a previous slide (calls the nextslide function with the new slide number
        obj.prevSlide = function(){
            var slide = (obj.currentSlide > 0) ? obj.currentSlide -= 1 : (obj.totalSlides - 1);
            obj.nextSlide(slide);
        };

        // Go to a next slide (function is also used for the previous slide and goto slide functions).
        // If a paramater is given it will go to the given slide
        obj.nextSlide = function(slide){
            // Cache the previous slide number and set slided to false
            var prevSlide = obj.currentSlide,
                slided = false;

            if(slide === undefined)
                obj.currentSlide = (obj.currentSlide < (obj.totalSlides-1)) ? obj.currentSlide += 1 : 0 ;
            else
                obj.currentSlide = slide;

            // Create trigger point before a slide slides. Trigger wil return the prev and coming slide number
            $(element).trigger({
                type: "beforeSliding",
                prevSlide: prevSlide,
                newSlide: obj.currentSlide
            });

            // Slide animation, here we determine if we can use CSS transitions (transit.js) or have to use jQuery animate
            $(options.slidesContainer).find(options.slides).each(function(index){
                if ($.support.transition && jQuery().transition)
                    $(this).stop().transition({x: ($(this).data('index')-obj.currentSlide)*100+'%'}, options.animateDuration, options.animationEasing);
                else
                    $(this).stop().animate({left: ($(this).data('index')-obj.currentSlide)*100+'%'}, options.animateDuration, triggerSlideEnd);
            });

            // Somehow the callback from $.transition doesn't work, so we create ow custom bind here
            $(options.slidesContainer).on('oTransitionEnd webkitTransitionEnd oTransitionEnd otransitionend transitionend', triggerSlideEnd);

            // Create trigger point after a slide slides. All the slides return a TransitionEnd; to prevent a repeating trigger we keep a slided var
            function triggerSlideEnd(){
                if(!slided){
                    $(element).trigger({
                        type: "afterSliding",
                        prevSlide: prevSlide,
                        newSlide: obj.currentSlide
                    });
                    slided = true;
                }
            }

            // Show current slide bulb
            $('#'+ options.slideTrackerID +' ul li').removeClass('active');
            $('#'+ options.slideTrackerID +' ul li[data-index="'+obj.currentSlide+'"]').addClass('active');

            // (Re)set the slider interval
            if(options.slideOnInterval){
                setSliderInterval();
            }
        };

        // Function for the pauseOnHover.
        //The function will clear the interval and restart it after the mouse disappears from the container
        if(options.pauseOnHover){
            $(options.slidesContainer).hover(function(){
                clearInterval(sliderInterval);
            }, function(){
                setSliderInterval();
            });
        }
    };

    // Create a plugin
    $.fn.simpleSlider = function(options){
        return this.each(function(){
            var element = $(this);

            // Return early if this element already has a plugin instance
            if (element.data('simpleslider')) return;

            // Pass options and element to the plugin constructer
            var simpleslider = new simpleSlider(this, options);

            // Store the plugin object in this element's data
            element.data('simpleslider', simpleslider);
        });
    }
})(jQuery);
<commit_msg>Added init .css for <IE9<commit_after>/*
    Version 2.3.4
    The MIT License (MIT)

    Simple jQuery Slider is just what is says it is: a simple but powerfull jQuery slider.
    Copyright (c) 2014 Dirk Groenen - Bitlabs Development

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
*/
(function($){
    var simpleSlider = function(element, useroptions){
        // Set some variables
        var obj = this,
            sliderInterval = null;
        obj.currentSlide = 0;
        obj.totalSlides = 0;

        // Extend default options with user options
        useroptions = (useroptions === undefined) ? {} : useroptions;
        var options = $.extend({
            slidesContainer: element,
            slides: '.slide',
            slideTracker: true,
            slideTrackerID: 'slideposition',
            slideOnInterval: true,
            interval: 5000,
            swipe: true,
            animateDuration: 1000,
            animationEasing: 'ease',
            pauseOnHover: false,
            updateTransit: true // Change this to false is you dont want the slider to update the transit useTransitionEnd to true
        }, useroptions);

        // Init the slider
        obj.init = function(){
            // If transit is included and useTransitionEnd == false we will change this to true (better animation performance).
            // Unless the user changed updateTransit to false
            if(options.updateTransit && $.support.transition && jQuery().transition && !$.transit.useTransitionEnd){
                $.transit.useTransitionEnd = true;
            }

            // Find the slides in the sliderdom and add the index attribute
            $(options.slidesContainer).find(options.slides).each(function(index){
                // Give each slide a data-index so we can control it later on
                $(this).attr('data-index', index);

                // A fixed width is needed for the IE left animation. Here we give each slide a width
                if ($.support.transition && jQuery().transition){
                    $(this).css({
                        x: index*100+'%',
                        width: $(this).outerWidth()
                    });
                }
                else{
                    $(this).css({
                        left: index*100+'%',
                        width: $(this).outerWidth()
                    });
                }
            });

            // Count the total slides
            obj.totalSlides = $(options.slidesContainer).find(options.slides).length;

            // Place the slideTracker after the container if enabled in the options
            if(options.slideTracker){
                // Add the slideposition div and add the indicators
                $(options.slidesContainer).after("

");
                for(var x = 0; x < obj.totalSlides;x++){
                    $('#'+ options.slideTrackerID +' ul').append('

');
                }
                $('#'+ options.slideTrackerID +' ul li[data-index="'+obj.currentSlide+'"]').addClass('active');

                // Make the slide indicators clickable
                $("#"+ options.slideTrackerID +" ul li").click(function(){
                    if(!($(this).hasClass("active")))
                        obj.nextSlide($(this).data('index'));
                });
            }

            // Start the slider interval if enabled in options
            if(options.slideOnInterval){
                setSliderInterval();
            }

            // Change the cursor with a grabbing hand that simulates the swiping on desktops
            if(options.swipe && jQuery().swipe){
                $(options.slidesContainer).css('cursor','-webkit-grab');
                $(options.slidesContainer).css('cursor','-moz-grab');
                $(options.slidesContainer).css('cursor','grab');

                $(options.slidesContainer).mousedown(function(){
                    $(options.slidesContainer).css('cursor','-webkit-grabbing');
                    $(options.slidesContainer).css('cursor','-moz-grabbing');
                    $(options.slidesContainer).css('cursor','grabbing');
                });

                $(options.slidesContainer).mouseup(function(){
                    $(options.slidesContainer).css('cursor','-webkit-grab');
                    $(options.slidesContainer).css('cursor','-moz-grab');
                    $(options.slidesContainer).css('cursor','grab');
                });

                // Add the swipe actions to the container
                $(options.slidesContainer).swipe({
                    swipeLeft: function(){
                        obj.nextSlide();
                    },
                    swipeRight: function(){
                        obj.prevSlide();
                    }
                });
            }
            else if(!jQuery().swipe && options.swipe === true){
                console.warn("Duo the missing TouchSwipe.js swipe has been disabled.");
            }
        }();

        // Bind the function that recalculates the width of each slide on a resize.
        $(window).resize(function(){
            $(options.slidesContainer).find(options.slides).each(function(index){
                // Reset width; otherwise it will keep the same width as before
                $(this).css('width','');
                $(this).css({x: index*100+'%',width: $(this).outerWidth()});
            });
        });

        // Controller of the interval
        function setSliderInterval(){
            clearInterval(sliderInterval);
            sliderInterval = setInterval(function(){
                obj.nextSlide();
            },options.interval);
        };

        // Go to a previous slide (calls the nextslide function with the new slide number
        obj.prevSlide = function(){
            var slide = (obj.currentSlide > 0) ? obj.currentSlide -= 1 : (obj.totalSlides - 1);
            obj.nextSlide(slide);
        };

        // Go to a next slide (function is also used for the previous slide and goto slide functions).
        // If a paramater is given it will go to the given slide
        obj.nextSlide = function(slide){
            // Cache the previous slide number and set slided to false
            var prevSlide = obj.currentSlide,
                slided = false;

            if(slide === undefined)
                obj.currentSlide = (obj.currentSlide < (obj.totalSlides-1)) ? obj.currentSlide += 1 : 0 ;
            else
                obj.currentSlide = slide;

            // Create trigger point before a slide slides. Trigger wil return the prev and coming slide number
            $(element).trigger({
                type: "beforeSliding",
                prevSlide: prevSlide,
                newSlide: obj.currentSlide
            });

            // Slide animation, here we determine if we can use CSS transitions (transit.js) or have to use jQuery animate
            $(options.slidesContainer).find(options.slides).each(function(index){
                if ($.support.transition && jQuery().transition)
                    $(this).stop().transition({x: ($(this).data('index')-obj.currentSlide)*100+'%'}, options.animateDuration, options.animationEasing);
                else
                    $(this).stop().animate({left: ($(this).data('index')-obj.currentSlide)*100+'%'}, options.animateDuration, triggerSlideEnd);
            });

            // Somehow the callback from $.transition doesn't work, so we create ow custom bind here
            $(options.slidesContainer).on('oTransitionEnd webkitTransitionEnd oTransitionEnd otransitionend transitionend', triggerSlideEnd);

            // Create trigger point after a slide slides. All the slides return a TransitionEnd; to prevent a repeating trigger we keep a slided var
            function triggerSlideEnd(){
                if(!slided){
                    $(element).trigger({
                        type: "afterSliding",
                        prevSlide: prevSlide,
                        newSlide: obj.currentSlide
                    });
                    slided = true;
                }
            }

            // Show current slide bulb
            $('#'+ options.slideTrackerID +' ul li').removeClass('active');
            $('#'+ options.slideTrackerID +' ul li[data-index="'+obj.currentSlide+'"]').addClass('active');

            // (Re)set the slider interval
            if(options.slideOnInterval){
                setSliderInterval();
            }
        };

        // Function for the pauseOnHover.
        //The function will clear the interval and restart it after the mouse disappears from the container
        if(options.pauseOnHover){
            $(options.slidesContainer).hover(function(){
                clearInterval(sliderInterval);
            }, function(){
                setSliderInterval();
            });
        }
    };

    // Create a plugin
    $.fn.simpleSlider = function(options){
        return this.each(function(){
            var element = $(this);

            // Return early if this element already has a plugin instance
            if (element.data('simpleslider')) return;

            // Pass options and element to the plugin constructer
            var simpleslider = new simpleSlider(this, options);

            // Store the plugin object in this element's data
            element.data('simpleslider', simpleslider);
        });
    }
})(jQuery);
<|endoftext|>


<commit_before>import { app, BrowserWindow } from 'electron' // eslint-disable-line

/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\') // eslint-disable-line
}

let mainWindow;
const winURL = process.env.NODE_ENV === 'development'
  ? 'http://localhost:9080'
  : `file://${__dirname}/index.html`;

function createWindow() {
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    height: 563,
    useContentSize: true,
    width: 1000,
  });

  mainWindow.loadURL(winURL);

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow();
  }
});

/**
 * Auto Updater
 *
 * Uncomment the following code below and install `electron-updater` to
 * support auto updating. Code Signing with a valid certificate is required.
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
 */

/*
import { autoUpdater } from 'electron-updater'

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall()
})

app.on('ready', () => {
  if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
})
 */
<commit_msg>Prettify main/index.js<commit_after>import { app, BrowserWindow } from 'electron'; // eslint-disable-line

/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path')
    .join(__dirname, '/static')
    .replace(/\\/g, '\\\\'); // eslint-disable-line
}

let mainWindow;
const winURL =
  process.env.NODE_ENV === 'development'
    ? 'http://localhost:9080'
    : `file://${__dirname}/index.html`;

function createWindow() {
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    height: 563,
    useContentSize: true,
    width: 1000,
  });

  mainWindow.loadURL(winURL);

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

app.on('ready', createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow();
  }
});

/**
 * Auto Updater
 *
 * Uncomment the following code below and install `electron-updater` to
 * support auto updating. Code Signing with a valid certificate is required.
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
 */

/*
import { autoUpdater } from 'electron-updater'

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall()
})

app.on('ready', () => {
  if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
})
 */
<|endoftext|>


<commit_before>'use strict'

import { app, BrowserWindow } from 'electron'
import OAuthTwitter from 'electron-oauth-twitter'
import storage from 'electron-json-storage-sync'
import { credentials, keys } from '../constants'
import ContextMenu from 'electron-context-menu'

/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}

let mainWindow
const winURL = process.env.NODE_ENV === 'development'
  ? `http://localhost:9080`
  : `file://${__dirname}/index.html`

function createWindow () {
  /**
   * Initial window options
   */
  const oauthInfo = storage.get(keys.OAUTH_TOKEN)

  if (oauthInfo.status && oauthInfo.data.oauth_access_token && oauthInfo.data.oauth_access_token_secret) {
    openWindow()
  } else {
    const twitterAuthWindow = new OAuthTwitter({
      key: credentials.CONSUMER_KEY,
      secret: credentials.CONSUMER_SECRET
    })

    twitterAuthWindow.startRequest()
      .then((res) => {
        const result = storage.set(keys.OAUTH_TOKEN, res)
        if (result.status) {
          openWindow()
        } else {
          console.error('Token save failed!')
        }
      })
      .catch((err) => {
        console.error(err, err.stack)
      })
  }
}

function openWindow () {
  mainWindow = new BrowserWindow({
    height: 700,
    width: 400,
    titleBarStyle: 'hidden',
    useContentSize: true
  })

  mainWindow.loadURL(winURL)
  mainWindow.on('closed', () => {
    mainWindow = null
  })
  mainWindow.on('new-window', (event, url) => {
    mainWindow.webContents.downloadURL(url)
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    // TODO: If windows or linux, after login close...
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

ContextMenu()

/**
 * Auto Updater
 *
 * Uncomment the following code below and install `electron-updater` to
 * support auto updating. Code Signing with a valid certificate is required.
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
 */

/*
import { autoUpdater } from 'electron-updater'

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall()
})

app.on('ready', () => {
  if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
})
 */
<commit_msg>Add open external browser if url is page<commit_after>'use strict'

import { app, shell, BrowserWindow } from 'electron'
import OAuthTwitter from 'electron-oauth-twitter'
import storage from 'electron-json-storage-sync'
import { credentials, keys } from '../constants'
import ContextMenu from 'electron-context-menu'

/**
 * Set `__static` path to static files in production
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html
 */
if (process.env.NODE_ENV !== 'development') {
  global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}

let mainWindow
const winURL = process.env.NODE_ENV === 'development'
  ? `http://localhost:9080`
  : `file://${__dirname}/index.html`

function createWindow () {
  /**
   * Initial window options
   */
  const oauthInfo = storage.get(keys.OAUTH_TOKEN)

  if (oauthInfo.status && oauthInfo.data.oauth_access_token && oauthInfo.data.oauth_access_token_secret) {
    openWindow()
  } else {
    const twitterAuthWindow = new OAuthTwitter({
      key: credentials.CONSUMER_KEY,
      secret: credentials.CONSUMER_SECRET
    })

    twitterAuthWindow.startRequest()
      .then((res) => {
        const result = storage.set(keys.OAUTH_TOKEN, res)
        if (result.status) {
          openWindow()
        } else {
          console.error('Token save failed!')
        }
      })
      .catch((err) => {
        console.error(err, err.stack)
      })
  }
}

function openWindow () {
  mainWindow = new BrowserWindow({
    height: 700,
    width: 400,
    titleBarStyle: 'hidden',
    useContentSize: true
  })

  mainWindow.loadURL(winURL)
  mainWindow.on('closed', () => {
    mainWindow = null
  })
  mainWindow.webContents.on('new-window', (event, url) => {
    if (!url.match(/.*\.(jpg|png|mp4)/)) {
      event.preventDefault()
      shell.openExternal(url)
    }
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    // TODO: If windows or linux, after login close...
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})

ContextMenu()

/**
 * Auto Updater
 *
 * Uncomment the following code below and install `electron-updater` to
 * support auto updating. Code Signing with a valid certificate is required.
 * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating
 */

/*
import { autoUpdater } from 'electron-updater'

autoUpdater.on('update-downloaded', () => {
  autoUpdater.quitAndInstall()
})

app.on('ready', () => {
  if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates()
})
 */
<|endoftext|>


<commit_before>var names = [
  'Aftershock',
  'Armageddon',
  'Assassinate',
  'Blitzkrieg',
  'Cataclizm',
  'Chaos',
  'Cyclone',
  'Deathroar',
  'Demolition',
  'Doom',
  'Dreadnought',
  'Eclipse',
  'Epicenter',
  'Euphoria',
  'Execution',
  'Exorcism',
  'Fireblast',
  'Fury',
  'Headshot',
  'Hurricane',
  'Impact',
  'Madness',
  'Nemesis',
  'Nightmare',
  'Nightwatch',
  'Onlivion',
  'Overcharge',
  'Overpower',
  'Paradox',
  'Rage',
  'Rampage',
  'Ravage',
  'Rupture',
  'Sabotage',
  'Starstorm',
  'Supernova',
  'Thunder',
  'Tornado',
  'Tsunami',
  'Vendetta',
  'Vengeance',
  'Violence',
  'Void',
  'Warpath',
  'Wrath'
]

export default names
<commit_msg>More cool names<commit_after>var names = [
  'Aftershock',
  'Assassinate',
  'Blitzkrieg',
  'Carnage',
  'Cataclizm',
  'Chaos',
  'Cyclone',
  'Deathroar',
  'Demolition',
  'Doom',
  'Eclipse',
  'Epicenter',
  'Euphoria',
  'Execution',
  'Exorcism',
  'Fireblast',
  'Fury',
  'Gambit',
  'Headshot',
  'Hurricane',
  'Impact',
  'Madness',
  'Nemesis',
  'Nightmare',
  'Nightwatch',
  'Onlivion',
  'Overcharge',
  'Overpower',
  'Paradox',
  'Rage',
  'Rampage',
  'Ravage',
  'Rupture',
  'Sabotage',
  'Shellshock',
  'Starstorm',
  'Supernova',
  'Thunder',
  'Tornado',
  'Tsunami',
  'Vendetta',
  'Vengeance',
  'Violence',
  'Void',
  'Warpath',
  'Wildfire',
  'Wrath'
]

export default names
<|endoftext|>


<commit_before>describe('navigation', function() {

    var networkUpdatesSpy;
    var networkErrorSpy;
    var changePathSpy;

    var SEPARATOR = ':';

    beforeEach(function() {
        networkUpdatesSpy = jasmine.createSpy('network-updates');
        Rpd.events.onValue(networkUpdatesSpy);
        //changePathSpy = jasmine.createSpy('change-path', Rpd.navigation.changePath).and.callThrough();
        changePathSpy = spyOn(Rpd.navigation, 'changePath').and.callThrough();
        networkErrorSpy = jasmine.createSpy('network-errors');
        Rpd.events.onError(networkErrorSpy);
        Rpd.navigation.enable();
    });

    afterEach(function() {
        Rpd.navigation.disable();
        Rpd.events.offValue(networkUpdatesSpy);
    });

    describe('handling empty path', function() {

        it('leaves first added patch opened and updates path with it', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
            expect(changePathSpy).toHaveBeenCalledOnce();
        });

        it('opens first added patch if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');
            firstPatch.close();

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
        });

        it('closes other patches except the first one', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
        });

        it('closes all other patches', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);

        });

    });

    describe('when path contains wrong ID or gibberish', function() {

        var GIBBER = 'gibber';

        it('fires an error, but opens first added patch', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error, opens first added patch even if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');
            firstPatch.close();

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error, but yet closes all other patches', function() {
            Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error when path contains only separators', function() {

            Rpd.navigation.handlePath(SEPARATOR + SEPARATOR);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(changePathSpy).toHaveBeenCalledWith('');

        });

    });

    describe('when path contains single patch ID', function() {

        it('leaves specified patch opened', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('opens specified patch if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addClosedPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('closes other patches except the specified one', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('closes all other patches', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('handling same path is not causing changePath to be called next time', function() {
            var firstPatch = Rpd.addPatch('first');
            //Rpd.navigation.handlePath(firstPatch.id);
            changePathSpy.calls.reset();
            Rpd.navigation.handlePath(firstPatch.id);
            Rpd.navigation.handlePath(firstPatch.id);
            expect(changePathSpy).not.toHaveBeenCalled();
        });

    });

    describe('when path contains several patch IDs', function() {

        it('opens all patches specified in the list while they exist', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('opens all patches specified in the list while they exist, even if there\'s a separator in the end', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id + SEPARATOR);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id);
        });

        it('closed patches stay closed if they were not specified in the list', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            expect(changePathSpy).toHaveBeenCalledWith(secondPatch.id);

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + secondPatch.id);

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        })

        it('do not opens patches which don\'t exist, fires an error for them, but fixes path', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addClosedPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            expect(changePathSpy).not.toHaveBeenCalled();

            networkUpdatesSpy.calls.reset();

            var GIBBER = 'gibber';

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + /*!*/GIBBER/*!*/ + SEPARATOR + secondPatch.id + SEPARATOR);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: secondPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + firstPatch.id);
        });

        xit('when parent patch was closed, also closes the child patch', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            secondPatch.open(thirdPatch);
            networkUpdatesSpy.calls.reset();
            thirdPatch.close();
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
        });

        it('handling same path is not causing changePath to be called next time', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var bothPatchesPath = firstPatch.id + SEPARATOR + secondPatch.id;
            //Rpd.navigation.handlePath(bothPatchesPath);
            changePathSpy.calls.reset();
            Rpd.navigation.handlePath(bothPatchesPath);
            Rpd.navigation.handlePath(bothPatchesPath);
            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('changePath is not causing second handlePath call', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            expect(changePathSpy).toHaveBeenCalledOnce();
            changePathSpy.calls.reset();
            var handlePathSpy = spyOn(Rpd.navigation, 'handlePath').and.callThrough();
            Rpd.navigation.handlePath(firstPatch.id);
            expect(changePathSpy).toHaveBeenCalledOnce();
            expect(handlePathSpy).toHaveBeenCalledOnce();
        });

    });

    describe('reaction on patches opened by user', function() {

        it('writes every opened patch to a path', function() {
            var firstPatch = Rpd.addPatch('first');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
            var secondPatch = Rpd.addPatch('second');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id);
            var thirdPatch = Rpd.addPatch('third');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id + SEPARATOR + thirdPatch.id);
        });

        it('if one of the patches is closed, do not writes it to the path', function() {
            var firstPatch = Rpd.addPatch('first');
            changePathSpy.calls.reset();
            var secondPatch = Rpd.addClosedPatch('second');
            expect(changePathSpy).not.toHaveBeenCalled();
            var thirdPatch = Rpd.addPatch('third');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + thirdPatch.id);
        });

        it('follows opening and closing patches', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addClosedPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            changePathSpy.calls.reset();
            secondPatch.open();
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + thirdPatch.id + SEPARATOR + secondPatch.id);
            thirdPatch.close();
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id);
        });

        it('when parent patch was passed to open method, stores it in the path in first position', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            changePathSpy.calls.reset();
            secondPatch.open(thirdPatch);
            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + secondPatch.id);
        });

    });

});
<commit_msg>navigation: one more test<commit_after>describe('navigation', function() {

    var networkUpdatesSpy;
    var networkErrorSpy;
    var changePathSpy;

    var SEPARATOR = ':';

    beforeEach(function() {
        networkUpdatesSpy = jasmine.createSpy('network-updates');
        Rpd.events.onValue(networkUpdatesSpy);
        //changePathSpy = jasmine.createSpy('change-path', Rpd.navigation.changePath).and.callThrough();
        changePathSpy = spyOn(Rpd.navigation, 'changePath').and.callThrough();
        networkErrorSpy = jasmine.createSpy('network-errors');
        Rpd.events.onError(networkErrorSpy);
        Rpd.navigation.enable();
    });

    afterEach(function() {
        Rpd.navigation.disable();
        Rpd.events.offValue(networkUpdatesSpy);
    });

    describe('handling empty path', function() {

        it('leaves first added patch opened and updates path with it', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
            expect(changePathSpy).toHaveBeenCalledOnce();
        });

        it('opens first added patch if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');
            firstPatch.close();

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
        });

        it('closes other patches except the first one', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
        });

        it('closes all other patches', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath('');

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);

        });

    });

    describe('when path contains wrong ID or gibberish', function() {

        var GIBBER = 'gibber';

        it('fires an error, but opens first added patch', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error, opens first added patch even if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');
            firstPatch.close();

            var secondPatch = Rpd.addPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error, but yet closes all other patches', function() {
            Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(GIBBER);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith('');
        });

        it('fires an error when path contains only separators', function() {

            Rpd.navigation.handlePath(SEPARATOR + SEPARATOR);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(changePathSpy).toHaveBeenCalledWith('');

        });

    });

    describe('when path contains single patch ID', function() {

        it('leaves specified patch opened', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('opens specified patch if it was closed before', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addClosedPatch('second');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('closes other patches except the specified one', function() {
            var firstPatch = Rpd.addPatch('first');

            var secondPatch = Rpd.addPatch('second');

            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('closes all other patches', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');
            thirdPatch.open();

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: firstPatch
                }));

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: thirdPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('handling same path is not causing changePath to be called next time', function() {
            var firstPatch = Rpd.addPatch('first');
            //Rpd.navigation.handlePath(firstPatch.id);
            changePathSpy.calls.reset();
            Rpd.navigation.handlePath(firstPatch.id);
            Rpd.navigation.handlePath(firstPatch.id);
            expect(changePathSpy).not.toHaveBeenCalled();
        });

    });

    describe('when path contains several patch IDs', function() {

        it('opens all patches specified in the list while they exist', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('opens all patches specified in the list while they exist, even if there\'s a separator in the end', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id + SEPARATOR);

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + secondPatch.id);
        });

        it('closed patches stay closed if they were not specified in the list', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            networkUpdatesSpy.calls.reset();
            changePathSpy.calls.reset();

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + secondPatch.id);

            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));

            expect(changePathSpy).not.toHaveBeenCalled();
        })

        it('do not opens patches which don\'t exist, fires an error for them, but fixes path', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addClosedPatch('second');
            var thirdPatch = Rpd.addClosedPatch('third');

            expect(changePathSpy).not.toHaveBeenCalled();

            networkUpdatesSpy.calls.reset();

            var GIBBER = 'gibber';

            Rpd.navigation.handlePath(thirdPatch.id + SEPARATOR + firstPatch.id + SEPARATOR + /*!*/GIBBER/*!*/ + SEPARATOR);

            expect(networkErrorSpy).toHaveBeenCalled();

            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: firstPatch
                }));
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: thirdPatch
                }));
            expect(networkUpdatesSpy).not.toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/open',
                    patch: secondPatch
                }));

            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + firstPatch.id);
        });

        xit('when parent patch was closed, also closes the child patch', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            secondPatch.open(thirdPatch);
            networkUpdatesSpy.calls.reset();
            thirdPatch.close();
            expect(networkUpdatesSpy).toHaveBeenCalledWith(
                jasmine.objectContaining({
                    type: 'patch/close',
                    patch: secondPatch
                }));
        });

        it('handling same path is not causing changePath to be called next time', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var bothPatchesPath = firstPatch.id + SEPARATOR + secondPatch.id;
            //Rpd.navigation.handlePath(bothPatchesPath);
            changePathSpy.calls.reset();
            Rpd.navigation.handlePath(bothPatchesPath);
            Rpd.navigation.handlePath(bothPatchesPath);
            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('changePath is not causing second handlePath call', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            expect(changePathSpy).toHaveBeenCalledOnce();
            changePathSpy.calls.reset();
            var handlePathSpy = spyOn(Rpd.navigation, 'handlePath').and.callThrough();
            Rpd.navigation.handlePath(firstPatch.id);
            expect(changePathSpy).toHaveBeenCalledOnce();
            expect(handlePathSpy).toHaveBeenCalledOnce();
        });

    });

    describe('reaction on patches opened by user', function() {

        it('writes every opened patch to a path', function() {
            var firstPatch = Rpd.addPatch('first');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id);
            var secondPatch = Rpd.addPatch('second');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id);
            var thirdPatch = Rpd.addPatch('third');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id + SEPARATOR + thirdPatch.id);
        });

        it('if one of the patches is closed, do not writes it to the path', function() {
            var firstPatch = Rpd.addPatch('first');
            changePathSpy.calls.reset();
            var secondPatch = Rpd.addClosedPatch('second');
            expect(changePathSpy).not.toHaveBeenCalled();
            var thirdPatch = Rpd.addPatch('third');
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + thirdPatch.id);
        });

        it('leaves single opened patch in a path and do not updates it if no patches were opened later', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            expect(changePathSpy).toHaveBeenCalledWith(secondPatch.id);
            changePathSpy.calls.reset();
            var thirdPatch = Rpd.addClosedPatch('third');
            expect(changePathSpy).not.toHaveBeenCalled();
        });

        it('follows opening and closing patches', function() {
            var firstPatch = Rpd.addPatch('first');
            var secondPatch = Rpd.addClosedPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            changePathSpy.calls.reset();
            secondPatch.open();
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + thirdPatch.id + SEPARATOR + secondPatch.id);
            thirdPatch.close();
            expect(changePathSpy).toHaveBeenCalledWith(firstPatch.id + SEPARATOR + secondPatch.id);
        });

        it('when parent patch was passed to open method, stores it in the path in first position', function() {
            var firstPatch = Rpd.addClosedPatch('first');
            var secondPatch = Rpd.addPatch('second');
            var thirdPatch = Rpd.addPatch('third');
            changePathSpy.calls.reset();
            secondPatch.open(thirdPatch);
            expect(changePathSpy).toHaveBeenCalledWith(thirdPatch.id + SEPARATOR + secondPatch.id);
        });

    });

});
<|endoftext|>


<commit_before>define(function() {
    describe('Minionette.View', function() {
        beforeEach(function() {
            this.view = new Minionette.View;
        })
        afterEach(function() {
            this.view.remove();
        });

        describe("constructor", function() {
            it("calls Backbone.View's constructor", function() {
                var spy = this.sinon.spy(Backbone, 'View');

                new Minionette.View;

                expect(spy).to.have.been.called;
            });

            it("initializes _subViews", function() {
                expect(this.view._subViews).to.not.be.undefined;
            });

            xit("listens for model events", function() {});
            xit("listens for collection events", function() {});

        });

        describe("instances", function() {
            it("creates #template function", function() {
                expect(this.view.template).to.be.a.function;
            });

            describe("#delegateEvents", function() {
                it("calls Backbone.View's #delegateEvents", function() {
                    var spy = this.sinon.spy(Backbone.View.prototype, 'delegateEvents');

                    this.view.delegateEvents();

                    expect(spy).to.have.been.called;
                });
            });

            describe("#remove", function() {
                it("triggers remove:before event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove:before', spy);

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });

                it("triggers remove event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove', spy);

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });

                it("removes subViews", function() {
                    var v = new Minionette.View,
                        spy = this.sinon.spy(v, 'remove');
                    this.view._subViews[0] = v;

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });
            });

            describe("#assign", function() {
                beforeEach(function() {
                    this.subView = new Minionette.View({id: 'subView'});
                    this.selector = '.selector';
                    this.spy = this.sinon.spy(this.subView, 'setElement');
                    this.view.$el.append('
');
                });

                it("takes a selector and a subView as arguments", function() {
                    this.view.assign(this.selector, this.subView);

                    expect(this.spy).to.have.been.calledWith(this.view.$(this.selector));
                });

                it("sets the subView's _parentView to this", function() {
                    this.view.assign(this.selector, this.subView);

                    expect(this.subView._parentView).to.equal(this.view);
                });

                it("can optionally take a replace param", function() {
                    this.view.assign(this.selector, this.subView, true);

                    expect(this.spy).to.not.have.been.called;
                    expect(this.view.$(this.subView.el).get(0)).to.not.be.undefined;
                });

                describe("alternate syntax", function() {
                    beforeEach(function() {
                        this.subView2 = new Minionette.View;
                        this.subViews = {'.test': this.subView2};
                        this.subViews[this.selector] = this.subView;
                        this.spy2 = this.sinon.spy(this.subView2, 'setElement');
                        this.view.$el.append('
');
                    });

                    it("takes an object (with keys as selectors and values as subViews) as an argument", function() {
                        this.view.assign(this.subViews);

                        expect(this.spy).to.have.been.calledWith(this.view.$('.selector'));
                        expect(this.spy2).to.have.been.calledWith(this.view.$('.test'));
                    });

                    it("can optionally take a replace param", function() {
                        this.view.assign(this.subViews, true);

                        expect(this.spy).to.not.have.been.calledWith(this.view.$('.selector'));
                        expect(this.spy2).to.not.have.been.calledWith(this.view.$('.test'));
                    });

                });
            });

            describe("#_jqueryRemove", function() {
                it("fires 'remove:jquery' event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove:jquery', spy);

                    this.view._jqueryRemove();

                    expect(spy).to.have.been.called;
                });

                it("is not called on #undelegateEvents", function() {
                    // Why are we testing this?
                    // With the way jQuery defines special events,
                    // the "remove" event will actually fire whenever we
                    // remove the event handler from the DOM element, calling
                    // the callback. We don't want that.
                    var spy = this.sinon.spy(this.view, '_jqueryRemove');

                    this.view.delegateEvents();
                    this.view.undelegateEvents();

                    expect(spy).to.not.have.been.called;
                });

                it("is not called on jQuery #detach", function() {
                    var spy = this.sinon.spy(this.view, '_jqueryRemove');

                    this.view.delegateEvents();
                    this.view.$el.detach();

                    expect(spy).to.not.have.been.called;
                });
            });
        });
    });
});
<commit_msg>Spec out modelEvents and collectionEvents<commit_after>define(function() {
    describe('Minionette.View', function() {
        beforeEach(function() {
            this.view = new Minionette.View;
        })
        afterEach(function() {
            this.view.remove();
        });

        describe("constructor", function() {
            it("calls Backbone.View's constructor", function() {
                var spy = this.sinon.spy(Backbone, 'View');

                new Minionette.View;

                expect(spy).to.have.been.called;
            });

            it("initializes _subViews", function() {
                expect(this.view._subViews).to.not.be.undefined;
            });

            describe("Model Events", function() {
                before(function() {
                    this.spy = this.sinon.spy();
                    this.ModelEventTest = Minionette.View.extend({
                        modelEvents: {
                            'change': this.spy
                        }
                    });
                    this.model = new Backbone.Model;
                });

                it("listens for model events", function() {
                    var view = new this.ModelEventTest({model: this.model});

                    this.model.trigger('change');

                    expect(this.spy).to.have.been.called;
                });
            });

            describe("Collection Events", function() {
                before(function() {
                    this.spy = this.sinon.spy();
                    this.CollectionEventTest = Minionette.View.extend({
                        collectionEvents: {
                            'change': this.spy
                        }
                    });
                    this.collection = new Backbone.Collection;
                });

                it("listens for collection events", function() {
                    var view = new this.CollectionEventTest({collection: this.collection});

                    this.collection.trigger('change');

                    expect(this.spy).to.have.been.called;
                });
            });

        });

        describe("instances", function() {
            it("creates #template function", function() {
                expect(this.view.template).to.be.a.function;
            });

            describe("#delegateEvents", function() {
                it("calls Backbone.View's #delegateEvents", function() {
                    var spy = this.sinon.spy(Backbone.View.prototype, 'delegateEvents');

                    this.view.delegateEvents();

                    expect(spy).to.have.been.called;
                });
            });

            describe("#remove", function() {
                it("triggers remove:before event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove:before', spy);

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });

                it("triggers remove event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove', spy);

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });

                it("removes subViews", function() {
                    var v = new Minionette.View,
                        spy = this.sinon.spy(v, 'remove');
                    this.view._subViews[0] = v;

                    this.view.remove();

                    expect(spy).to.have.been.called;
                });
            });

            describe("#assign", function() {
                beforeEach(function() {
                    this.subView = new Minionette.View({id: 'subView'});
                    this.selector = '.selector';
                    this.spy = this.sinon.spy(this.subView, 'setElement');
                    this.view.$el.append('
');
                });

                it("takes a selector and a subView as arguments", function() {
                    this.view.assign(this.selector, this.subView);

                    expect(this.spy).to.have.been.calledWith(this.view.$(this.selector));
                });

                it("sets the subView's _parentView to this", function() {
                    this.view.assign(this.selector, this.subView);

                    expect(this.subView._parentView).to.equal(this.view);
                });

                it("can optionally take a replace param", function() {
                    this.view.assign(this.selector, this.subView, true);

                    expect(this.spy).to.not.have.been.called;
                    expect(this.view.$(this.subView.el).get(0)).to.not.be.undefined;
                });

                describe("alternate syntax", function() {
                    beforeEach(function() {
                        this.subView2 = new Minionette.View;
                        this.subViews = {'.test': this.subView2};
                        this.subViews[this.selector] = this.subView;
                        this.spy2 = this.sinon.spy(this.subView2, 'setElement');
                        this.view.$el.append('
');
                    });

                    it("takes an object (with keys as selectors and values as subViews) as an argument", function() {
                        this.view.assign(this.subViews);

                        expect(this.spy).to.have.been.calledWith(this.view.$('.selector'));
                        expect(this.spy2).to.have.been.calledWith(this.view.$('.test'));
                    });

                    it("can optionally take a replace param", function() {
                        this.view.assign(this.subViews, true);

                        expect(this.spy).to.not.have.been.calledWith(this.view.$('.selector'));
                        expect(this.spy2).to.not.have.been.calledWith(this.view.$('.test'));
                    });

                });
            });

            describe("#_jqueryRemove", function() {
                it("fires 'remove:jquery' event", function() {
                    var spy = this.sinon.spy();
                    this.view.on('remove:jquery', spy);

                    this.view._jqueryRemove();

                    expect(spy).to.have.been.called;
                });

                it("is not called on #undelegateEvents", function() {
                    // Why are we testing this?
                    // With the way jQuery defines special events,
                    // the "remove" event will actually fire whenever we
                    // remove the event handler from the DOM element, calling
                    // the callback. We don't want that.
                    var spy = this.sinon.spy(this.view, '_jqueryRemove');

                    this.view.delegateEvents();
                    this.view.undelegateEvents();

                    expect(spy).to.not.have.been.called;
                });

                it("is not called on jQuery #detach", function() {
                    var spy = this.sinon.spy(this.view, '_jqueryRemove');

                    this.view.delegateEvents();
                    this.view.$el.detach();

                    expect(spy).to.not.have.been.called;
                });
            });
        });
    });
});
<|endoftext|>