• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Criando plugins com o j query ui e testando com o jasmine
 

Criando plugins com o j query ui e testando com o jasmine

on

  • 2,014 views

O jQuery UI é uma evolução do pattern de desenvolvimento de plugins para o jQuery. Com o Widget factory é possível ter plugins mais flexíveis para o jQuery e usando o Jasmine como ferramenta de ...

O jQuery UI é uma evolução do pattern de desenvolvimento de plugins para o jQuery. Com o Widget factory é possível ter plugins mais flexíveis para o jQuery e usando o Jasmine como ferramenta de BDD, é possível desenvolver melhores componentes jQuery com testes automatizados e ter uma aplicação web mais rica com menos bugs.

Statistics

Views

Total Views
2,014
Views on SlideShare
1,102
Embed Views
912

Actions

Likes
3
Downloads
14
Comments
0

3 Embeds 912

http://blog.alexandremagno.net 906
http://us-w1.rockmelt.com 4
http://www.linkedin.com 2

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Criando plugins com o j query ui e testando com o jasmine Criando plugins com o j query ui e testando com o jasmine Presentation Transcript

  • DESENVOLVENDO PLUGINS COM O JQUERY UI E TESTANDO COM JASMINE FISL 13
  • QUEM SOU EU?
  • Alexandre Magno na atualmente no
  • PROJETOSOPEN SOURCE
  • Twitter Bootstrap BR jQuery slidinghttps://github.com/alexanmtz/bootstrap http://www.github.com/alexanmtzjQuery Destaque WP-Agenda https://github.com/alexanmtz/wp-agenda https://github.com/globocom/destaque
  • OUTROS PROJETOS... Blog Webpoint http://blog.alexadremagno.net eutro.co http://eutro.coBalloon3http://balloon3.com Salve a web por favo http://salveaweb.com/
  • NAS HORAS VAGAS...
  • http://www.gandhifica.com
  • VAMOS FALAR DE QUÊ?
  • Jasmine jQuery Plugins design Pattern Widget factory TDD javascript BDDjQuery UI Ajax Refactoring
  • TUDO ISSO NA PRÁTICA?
  • SIM!
  • MAS ANTESVAMOS FALAR DE
  • JAVASCRIPT
  • fonte: http://aaroncrowder.com/
  • POR QUE O JAVASCRIPT FICOU TÃO POPULAR?
  • JQUERY
  • “MEU PRIMEIRO CONTATO COMO JAVASCRIPT FOI COM JQUERY” Beethoven
  • API
  • <script type="text/javascript">! $(function(){! ! $(div).css(color, red).appendTo(body);! });</script>
  • ALGUMA SEMELHANÇACOM O BRANDING DO JQUERY?
  • PLUGINS
  • USE OS PLUGINS JQUERY PARACRIAR COMPONENTES JAVASCRIPT https://moqups.com
  • UM PLUGIN BÁSICO
  • // Create the defaults once    var pluginName = defaultPluginName,        defaults = {            propertyName: "value"        };    // The actual plugin constructor    function Plugin( element, opt ) {        this.element = element;        this.options = $.extend( {}, defaults,opt );        this._defaults = defaults;        this._name = pluginName;        this.init();    }
  • Plugin.prototype = {                init: function() {           this.yourOtherFunction(this.element, this.options);        },                yourOtherFunction: function(el, options) {            // some logic        }    };    $.fn[pluginName] = function ( options ) {        return this.each(function () {            if (!$.data(this, plugin_ + pluginName)) {                $.data(this, plugin_ + pluginName);                new Plugin( this, options ));            }        });    }
  • <script type="text/javascript">! $(function(){! ! console.log($(body).defaultPluginName());! });</script> fonte: https://github.com/addyosmani/jquery-plugin-patterns/
  • EXEMPLO MAIS REAL? JQUERY JFLOW
  • " > sc ript xt/ java JQUERY JFLOW = "t e type (){ ript ction ) .jfl ow() ; PATTERN DE PLUGIN BÁSICO< s c fun nto leme https://github.com/alexanmtz/jflow $( ! ( # e ! ! $ ! }); t> p </ scri ao clicar aqui Os elementos se mo vem e aqui
  • Ô NÓ, Eu quero usar o jflow emmeu projeto, mas a minha listagemvai ser dinâmica, com possibilidadede novos itens serem adicionados, porém não está funcionando!
  • BUG?
  • <scrip t type avasc r i p t" > ! $(fu = "t e x t /javas text/j nction (){ c r i p t" t type=" ! ! $ (#ele ><scrip ction(){ flow({ mento2 $(fun .j ).jfl! e nto1) items: ow({ ( #elem s: 5 4 ! ! $ item ! }); }); }); </scri pt> ! }); t> < /scrip e aquiao clicar aqui
  • <scrip t type avasc r i p t" > ! $(fu = "t e x t /javas text/j nction (){ c r i p t" t type=" ! ! $ (#ele ><scrip ction(){ flow({ mento2 $(fun .j ).jfl! e nto1) items: ow({ ( #elem s: 5 4 ! ! $ item ! }); }); }); </scri pt> ! }); t> < /scrip e aquiao clicar aqui
  • TEMOS UM PROBLEMA
  • Plugins de jQuery são inicializados apenas uma veznão podem sermodificadosOu seja,um pluginjQuery é...
  • que que é isso? STATELESS
  • r"><div i d = "c o n t a i n e! ul> < Métodos de classe li>! < ! li> item 1</ i>! <l i> item 2</l ! > item 3</li > Atributos data ! <li ! /li> !! <li> item 4< ! /ul> < </div> w({ $(#conta iner).jflo ! tens: 3, i , ta i n e r u l l i i t e m : # c o n Como chamar método zon t a l s? ! mode: hori }); preciso executar u ma ação ow_metodo( ); //no! $(#contai n e r ) . j f l $(#container ).jflow.meto do(); //wtf
  • MEUCÓDIGOVIROU UMFRANKSTEIN
  • PATTERNS
  • STATELESS Basic pluginNamespace Prototypal inheritance Widget factory bridgeCustom events Widget factory Highly configurable Best options Extend skeleton “UMA SOLUÇÃO GERAL REUSÁVEL DE UM PROBLEMA RECORRENTE” Wikipedia fonte: https://github.com/addyosmani/jquery-plugin-patterns/
  • JQUERY UI
  • p t" > java s cri ; COM O WIDGET FACTORY t/ ) " tex ete( ype= ){ c ompl pt t ion( auto< scri unct o). ( f e ment ! $ $( # e l ! ! ; ) ! } ipt> < /scr ... ) }) ( ete , { toc ompl $.u i.au p t" > " , cri se arch t/j avas ui. auto " tex h(); " ype= ){ earc get( s id pt t ion( auto $.w < scri unct o). (f e ment ! $ $(#el ! ! ; TEMOS HERANÇA ! }) ipt> < /scr
  • EU QUERY MEU WIDGET
  • EU TAMBÉM!
  • JQUERY UI SLIDING
  • COMO FUNCIONA?
  • O QUE É
  • O QUE É
  • O QUE É
  • O QUE É
  • O QUE É
  • um carrossel? jQuery Cycle Plugin Isto é um carrossel!jQuery Sliding Elementos deslizantes
  • LETS CODE!
  • // widget factory    $.widget( “ui.sliding”, {        options: { items: 5 // mais opcoes }, pages: 0, _create: function() {           this._enclose();        },        _enclose: function() {            // enclose envolve o elemento deslizante // this.options são as opções        }        goToPage: function(page) {            // logica de ir para pagina // this.element é o elemento // this.options são as opções        } });
  • <script type="text/javascript">! $(function(){! ! $(#elemento).sliding(); $(#elemento).sliding(“goToPage”, 2);! });</script>
  • <script type="text/javascript">! $(function(){! ! $(#elemento).sliding(“destroy”); $(#elemento).sliding(“option”, “items”, 3);! });</script>
  • <script type="text/javascript">! $(function(){! ! $(#elemento).sliding(“refresh”); $(#elemento).sliding(“restart”);! });</script>
  • // widget factory    $.widget( “ui.sliding”, { _setOption: function(key, value) {            // alguma logica, depois $.Widget.prototype._setOption.apply( this, arguments );        },        enable: function() {            // logica de habilitar // this.options são as opções        },        disable: function() {            // logica de desabilitar // this.element é o elemento // this.options são as opções        } });
  • E COMO TESTA ISTO?
  • TESTAR MÉTODOS getCurrentPage getTotalPages $.ui.widget setTotalPages goToPage before onAppendnext remote E CALLBACKS
  • USANDO O QUÊ?
  • METODOLOGIA
  • TDD É...FICAR VERMELHO
  • PARA DEPOISFICAR VERDE
  • E SUCESSIVAMENTEFICAR VERMELHO
  • PARA DEPOISFICAR VERDE
  • BDD
  • JASMINE
  • sliding / tests / spec / SlidingSpec.jsdescribe("Sliding", function() {  beforeEach(function(){    jQuery.fx.off = true;  });  it("should load the instance of the plugin",function() {    expect($.ui.sliding).toBeTruthy();  });});
  • JQUERY UI WIDGETsliding / jquery.sliding.js// widget factory    $.widget( “ui.sliding”, { _create: function() {            // codigo da inicializacao        },        options: { // objeto de opções        },        isLastPage: function() {            return this.getCurrentPage() ==this.getTotalPages();        } });
  • SPECsliding / tests / spec / SlidingSpec.jsit("should get the currentPage and check if is last one", function(){ $(container).sliding(goToPage, 2); var currPage = $(container).sliding.(getCurrentPage);  expect(currPage).toBe(2); expect($(container).sliding(‘isLastPage’)).toBeTruthy();});
  • O QUE MAIS A JASMINE TEM DE BOM?
  • JASMINE JQUERYsliding / tests / spec / SlidingSpec.js it("should the first page should have previous button disabled", function(){  expect($(.ui-sliding-prev).get(0)).toHaveClass(disabled);  expect($(.ui-sliding-next).get(0)).not.toHaveClass(disabled); });
  • POSSÍVEIS RESULTADOS
  • AJAX MOCK
  • MOCK DO DATA VINDO DO AJAXsliding / tests / spec / SlidingSpec.js describe("remote sliding", function(){      var newData = ;      beforeEach(function(){        newData = createUnorderedList(30, true);        spyOn($, ajax).andCallFake(function(options){          options.success(newData);        });     });
  • E COM ISSO...sliding / tests / spec / SlidingSpec.jsit("should make a ajax request for second page", function(){        $(container).sliding({          next: .test-next,          prev: .test-prev,          url: foo/test,          items: 15 // one page        });        $(container).sliding(setTotalPages, 3);        $(.test-next).trigger(click);        expect($(container).get(0)).beInRange(15,30); // Next     });
  • MATCHERSsliding / tests / spec / SpecHelper.jsbeforeEach(function() {  this.addMatchers({   beInRange: function(start, end) {       var isIn = 0;        var current_width = $(this.actual).width();        var container_pos = $(this.actual).position();        var final_pos = current_width + container_pos.left;        $(this.actual).find(li).slice(start,end).each(function(i, el){            var el_pos = $(this).position();            if (el_pos.left < final_pos && el_pos.left >=container_pos.left) {                isIn++;            }        });        return isIn == $(this.actual).sliding(option,items);    }  });});
  • MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • MATCHER PARA DETECTAR QUANTOS ELEMENTOS ESTÃO SENDO EXIBIDOS
  • CHAMADAS AJAXsliding / tests / spec / SlidingSpec.jsit("should not make ajax request when is going to previous page",function(){       $(container).sliding({          next: .test-next,          prev: .test-prev,          url: foo/test2,          items: 15        });        $(container).sliding(setTotalPages, 3);        $(container).sliding(goToPage, 2);        $(.test-prev).trigger(click);        expect($.ajax.callCount).toEqual(1);     });
  • CHAMADAS AJAXsliding / tests / spec / SlidingSpec.jsit("should pass extra parameters in the request", function(){       $(container).sliding({         next: .test-next,         prev: .test-prev,         url: foo/test3,         items: 15,         params: {           extra : foo         }       });       $(container).sliding(goToPage, 2);       expect($.ajax.mostRecentCall.args[0]["data"]).toEqual({extra:foo});     });
  • SPIES PARA CALLBACKSsliding / tests / spec / SlidingSpec.jsit("should call loading callback when request starts", function() {     var callback = jasmine.createSpy();     $(container).sliding({       next: .test-next,       prev: .test-prev,       url: foo/test2,       before: callback,       items: 15     });     $(container).sliding(setTotalPages, 3);     $(container).sliding(goToPage, 2);     expect(callback).toHaveBeenCalled();});
  • CLOCK.TICKsliding / tests / spec / SlidingSpec.jsbeforeEach(function() {    jasmine.Clock.useMock();});it("Should set current page just when animation over", function(){ $(‘#container’).sliding({ speed: 200 });   $(‘#container’).sliding(‘goToPage’, 2);   jasmine.Clock.tick(200);   expect($(‘#container’).sliding(‘getCurrentPage’)).toBe(2);});
  • FIXTURESsliding / tests / spec / SlidingSpec.jsbeforeEach(function() {   loadFixtures("list.html");});spec / javascript / fixtures / list.html<ul id=”list”> <li>item 01</li> <li>item 02</li></ul>sliding / tests / spec / SlidingSpec.jsdescribe(“usando fixtures”, function() {   expect($(‘#list’).length).toBe(1);});
  • VOCÊ SÓ VAI APRENDER FAZENDO!
  • OBRIGADO! @alexanmtz