├── public ├── favicon.ico ├── images │ ├── play.png │ └── rails.png ├── javascripts │ └── application.js ├── robots.txt ├── 422.html ├── 404.html └── 500.html ├── db ├── development.sqlite3 ├── production.sqlite3 └── seeds.rb ├── CHANGELOG ├── .ruby-version ├── vendor └── plugins │ └── cucumber_fm │ ├── tmp │ └── .gitignore │ ├── spec │ ├── data │ │ ├── feature_manager │ │ │ ├── some_ruby_file.rb │ │ │ ├── subdir │ │ │ │ ├── subdir │ │ │ │ │ └── fifth.feature │ │ │ │ ├── third.feature │ │ │ │ └── second.feature │ │ │ ├── subdir_2 │ │ │ │ └── forth.feature │ │ │ └── one_feature.feature │ │ └── cucumber_f_m │ │ │ └── feature │ │ │ └── first.feature │ ├── spec_helper.rb │ ├── spec.opts │ ├── cucumber_f_m │ │ ├── comment_module │ │ │ └── comment_spec.rb │ │ ├── feature_module │ │ │ ├── example_spec.rb │ │ │ ├── narrative_spec.rb │ │ │ ├── step_spec.rb │ │ │ ├── comment_spec.rb │ │ │ ├── info_spec.rb │ │ │ ├── background_spec.rb │ │ │ ├── scenario_spec.rb │ │ │ ├── scenario_outline_spec.rb │ │ │ └── tag_spec.rb │ │ ├── feature_all_tags_to_scenario_spec.rb │ │ ├── feature_file_manipulation_spec.rb │ │ ├── config_spec.rb │ │ └── cvs │ │ │ └── git_spec.rb │ └── cucumber_feature_manager_spec.rb │ ├── rails │ └── init.rb │ ├── README_DEV.rdoc │ ├── .gitignore │ ├── lib │ ├── cucumber_f_m │ │ ├── cvs │ │ │ └── git.rb │ │ ├── feature_element │ │ │ ├── step.rb │ │ │ ├── example.rb │ │ │ ├── narrative.rb │ │ │ ├── comment.rb │ │ │ ├── background.rb │ │ │ ├── component │ │ │ │ ├── information │ │ │ │ │ └── component.rb │ │ │ │ ├── comments.rb │ │ │ │ ├── title.rb │ │ │ │ ├── total_estimation.rb │ │ │ │ └── tags.rb │ │ │ ├── info.rb │ │ │ ├── scenario.rb │ │ │ └── scenario_outline.rb │ │ ├── comment_module │ │ │ └── comment.rb │ │ ├── statistic.rb │ │ ├── config.rb │ │ ├── parser │ │ │ └── feature.tt │ │ ├── aggregator.rb │ │ ├── tag_filter.rb │ │ └── feature.rb │ ├── grit │ │ ├── lib │ │ │ ├── grit │ │ │ │ ├── errors.rb │ │ │ │ ├── ruby1.9.rb │ │ │ │ ├── tag.rb │ │ │ │ ├── lazy.rb │ │ │ │ ├── actor.rb │ │ │ │ ├── config.rb │ │ │ │ ├── git-ruby │ │ │ │ │ ├── internal │ │ │ │ │ │ ├── raw_object.rb │ │ │ │ │ │ ├── file_window.rb │ │ │ │ │ │ └── loose.rb │ │ │ │ │ └── commit_db.rb │ │ │ │ ├── merge.rb │ │ │ │ ├── blame.rb │ │ │ │ ├── ref.rb │ │ │ │ ├── diff.rb │ │ │ │ ├── submodule.rb │ │ │ │ ├── tree.rb │ │ │ │ ├── commit_stats.rb │ │ │ │ ├── index.rb │ │ │ │ ├── blob.rb │ │ │ │ └── status.rb │ │ │ ├── open3_detach.rb │ │ │ └── grit.rb │ │ └── LICENSE │ └── cucumber_feature_manager.rb │ ├── public │ ├── images │ │ ├── icons │ │ │ └── shared.png │ │ ├── layout │ │ │ ├── bg_body.png │ │ │ ├── bt_green.png │ │ │ ├── magnify.png │ │ │ ├── toggler.png │ │ │ ├── frame_head.png │ │ │ ├── table_thead.png │ │ │ ├── menu_business.png │ │ │ ├── menu_results.png │ │ │ ├── menu_development.png │ │ │ ├── menu_statistic.png │ │ │ ├── frame_head_actions.png │ │ │ ├── frame_head_actions_lb.png │ │ │ ├── frame_content_twocolumns.png │ │ │ └── frame_content_twocolumns_wider.png │ │ └── sproutcore-logo.png │ ├── stylesheets │ │ ├── fonts │ │ │ ├── Titillium_600.otf │ │ │ └── Titillium_800.otf │ │ ├── reset.css │ │ └── device_width.css │ ├── bespin │ │ ├── resources │ │ │ ├── screen_theme │ │ │ │ └── images │ │ │ │ │ ├── lines.png │ │ │ │ │ ├── bespin-s.png │ │ │ │ │ ├── scroll-up.png │ │ │ │ │ ├── scroll-down.png │ │ │ │ │ ├── scroll-left.png │ │ │ │ │ ├── scroll-right.png │ │ │ │ │ ├── check-selected.png │ │ │ │ │ ├── radio-selected.png │ │ │ │ │ ├── check-unselected.png │ │ │ │ │ └── radio-unselected.png │ │ │ └── whitetheme │ │ │ │ └── theme.less │ │ └── BespinEmbedded.css │ └── javascripts │ │ └── BespinSyntaxGherkin.js │ ├── features │ ├── editor │ │ ├── comments_clickable_links.feature │ │ ├── comments_notation.feature │ │ ├── basics.feature │ │ ├── advance.feature │ │ └── settings_cvs.feature │ ├── support │ │ ├── changelog.feature │ │ ├── filter_storage.feature │ │ └── filter_basics.feature │ ├── business_overview │ │ ├── burndown_graph.feature │ │ ├── create_new_feature.feature │ │ └── dashboard.feature │ ├── cvs_integration │ │ └── pushing_date_to_git_remote_branch.feature │ ├── statistics │ │ └── dashboard.feature │ └── kanban │ │ └── dashboard.feature │ ├── app │ ├── views │ │ └── documentation │ │ │ ├── layouts │ │ │ ├── mini.html.erb │ │ │ └── cucumber_fm.html.erb │ │ │ ├── watircuke │ │ │ ├── runme.html.erb │ │ │ └── results.html.erb │ │ │ └── features │ │ │ ├── _run_feature.html.erb │ │ │ ├── statistic.html.erb │ │ │ └── index.html.erb │ ├── controllers │ │ └── documentation │ │ │ ├── assets_controller.rb │ │ │ ├── application_controller.rb │ │ │ ├── watircuke_controller.rb │ │ │ └── features_controller.rb │ └── models │ │ └── watircuke.rb │ ├── LICENCE │ ├── config │ └── routes.rb │ ├── README.rdoc │ └── CHANGELOG ├── features ├── fixtures │ └── test_data.yml ├── support │ ├── create_screenshot_folder.rb │ ├── read_config.rb │ ├── paths.rb_example │ ├── check_for_images.rb │ ├── check_missing_translations.rb │ ├── select_browser.rb │ └── env.rb ├── sample.feature └── step_definitions │ └── watircuke_steps.rb ├── script ├── plugin ├── runner ├── server ├── console ├── destroy ├── generate ├── dbconsole ├── performance │ ├── profiler │ └── benchmarker └── about ├── .gitignore ├── doc └── README_FOR_APP ├── config ├── locales │ └── en.yml ├── initializers │ ├── mime_types.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── cookie_verification_secret.rb │ ├── session_store.rb │ └── new_rails_defaults.rb ├── config.yml_example ├── database.yml ├── config.yml ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── routes.rb ├── environment.rb └── boot.rb ├── test ├── performance │ └── browsing_test.rb └── test_helper.rb ├── Rakefile ├── app ├── helpers │ └── application_helper.rb └── controllers │ └── application_controller.rb ├── Gemfile ├── lib ├── popup_killer_ie.rb └── run_watircuke_setup.rb ├── LICENCE ├── watircuke.rb ├── Gemfile.lock ├── -f └── README /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db/development.sqlite3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db/production.sqlite3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 0.0.1 first release -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ree-1.8.7-2012.02 2 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/tmp/.gitignore: -------------------------------------------------------------------------------- 1 | repo 2 | repo/**/* -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/some_ruby_file.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/rails/init.rb: -------------------------------------------------------------------------------- 1 | require 'cucumber_feature_manager' -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/subdir/subdir/fifth.feature: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'cucumber_feature_manager' -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/README_DEV.rdoc: -------------------------------------------------------------------------------- 1 | 2 | # RCOV report 3 | rcov lib/*.rb -o tmp/rcov -------------------------------------------------------------------------------- /public/images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/public/images/play.png -------------------------------------------------------------------------------- /public/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/public/images/rails.png -------------------------------------------------------------------------------- /features/fixtures/test_data.yml: -------------------------------------------------------------------------------- 1 | data_example: 2 | id: 1 3 | name: foo 4 | job: bar 5 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/spec.opts: -------------------------------------------------------------------------------- 1 | --colour 2 | --format nested 3 | --loadby mtime 4 | --reverse -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .idea/* 3 | .idea/**/* 4 | log/* 5 | tmp/**/* 6 | coverage 7 | -------------------------------------------------------------------------------- /script/plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/plugin' 4 | -------------------------------------------------------------------------------- /script/runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/runner' 4 | -------------------------------------------------------------------------------- /script/server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/server' 4 | -------------------------------------------------------------------------------- /script/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/console' 4 | -------------------------------------------------------------------------------- /script/destroy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/destroy' 4 | -------------------------------------------------------------------------------- /script/generate: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/generate' 4 | -------------------------------------------------------------------------------- /script/dbconsole: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | require 'commands/dbconsole' 4 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/cvs/git.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module Cvs 3 | class Git 4 | 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /script/performance/profiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../../config/boot', __FILE__) 3 | require 'commands/performance/profiler' 4 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/comment_module/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::CommentModule::Comment do 4 | end -------------------------------------------------------------------------------- /script/performance/benchmarker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../../config/boot', __FILE__) 3 | require 'commands/performance/benchmarker' 4 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/icons/shared.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/icons/shared.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/bg_body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/bg_body.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/bt_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/bt_green.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/magnify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/magnify.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/toggler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/toggler.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/sproutcore-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/sproutcore-logo.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/frame_head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/frame_head.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/table_thead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/table_thead.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/menu_business.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/menu_business.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/menu_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/menu_results.png -------------------------------------------------------------------------------- /script/about: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.expand_path('../../config/boot', __FILE__) 3 | $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" 4 | require 'commands/about' 5 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/step.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Step 4 | #Code here 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/menu_development.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/menu_development.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/menu_statistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/menu_statistic.png -------------------------------------------------------------------------------- /public/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // Place your application-specific JavaScript functions and classes here 2 | // This file is automatically included by javascript_include_tag :defaults 3 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/comment_module/comment.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module CommentModule 3 | class Comment 4 | #Code here 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/example.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Example 4 | #Code here 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/frame_head_actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/frame_head_actions.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/stylesheets/fonts/Titillium_600.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/stylesheets/fonts/Titillium_600.otf -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/stylesheets/fonts/Titillium_800.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/stylesheets/fonts/Titillium_800.otf -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/narrative.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Narrative 4 | #Code here 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/errors.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | class InvalidGitRepositoryError < StandardError 3 | end 4 | 5 | class NoSuchPathError < StandardError 6 | end 7 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/frame_head_actions_lb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/frame_head_actions_lb.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/frame_content_twocolumns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/frame_content_twocolumns.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/example_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Example do 4 | # it "should map attributes with values" 5 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/lines.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/bespin-s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/bespin-s.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/images/layout/frame_content_twocolumns_wider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/images/layout/frame_content_twocolumns_wider.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/subdir/third.feature: -------------------------------------------------------------------------------- 1 | @m1 2 | Feature: Edit feature content 3 | To update requirement for project 4 | product owner 5 | should be able to change feature content -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-up.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test_results/* 2 | log/* 3 | db/* 4 | public/test_results/* 5 | config/* 6 | features/* 7 | bin/* 8 | .rvmrc 9 | qype.rb 10 | tags 11 | tmp/* 12 | watircuke_qype.rb 13 | 14 | .DS_Store 15 | .bundle/ 16 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-down.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-left.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/scroll-right.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/check-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/check-selected.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/radio-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/radio-selected.png -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/check-unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/check-unselected.png -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/radio-unselected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/watircukefm/master/vendor/plugins/cucumber_fm/public/bespin/resources/screen_theme/images/radio-unselected.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/ruby1.9.rb: -------------------------------------------------------------------------------- 1 | class String 2 | if ((defined? RUBY_VERSION) && (RUBY_VERSION[0..2] == "1.9")) 3 | def getord(offset); self[offset].ord; end 4 | else 5 | alias :getord :[] 6 | end 7 | end -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/subdir/second.feature: -------------------------------------------------------------------------------- 1 | @m1 2 | Feature: Edit feature content 3 | To update requirement for project 4 | product owner 5 | should be able to change feature content 6 | 7 | Scenario: Some scenario -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/narrative_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Narrative do 4 | # it "should parse cause of intruducting feature" 5 | # it "should find subject" 6 | # it "should find activity" 7 | end -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'performance_test_help' 3 | 4 | # Profiling results for each test method are written to tmp/performance. 5 | class BrowsingTest < ActionController::PerformanceTest 6 | def test_homepage 7 | get '/' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_all_tags_to_scenario_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "Moving all tags from feature to scenarios" do 4 | # TODO: 5 | # it "should move all tags from feature to scenario" 6 | # it "should preserve single acceptance tags from overwriting" 7 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/step_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Step do 4 | # it "should separate type from value" 5 | # it "should be able to find definition of step" 6 | # it "should be able to find definition of sub step" 7 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/editor/comments_clickable_links.feature: -------------------------------------------------------------------------------- 1 | @editor 2 | Feature: Editor - comments click able links 3 | To make clicking links easiest 4 | as developer and product owner 5 | I want to be able to clikc attach links 6 | 7 | @_todo @m2 @i5 8 | Scenario: click wireframe link -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/cucumber_f_m/feature/first.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit feature content 2 | To update requirement for project 3 | product owner 4 | should be able to change feature content 5 | 6 | Scenario: Inserting Background 7 | 8 | Scenario: Inserting Scenario when cursor on text field 9 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/comment.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Comment < Struct.new(:ancestors, :raw) 4 | 5 | 6 | private 7 | 8 | def is_it_link 9 | raw =~ /^#:::[^:]+:::/ 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /features/support/create_screenshot_folder.rb: -------------------------------------------------------------------------------- 1 | require 'fileutils' 2 | 3 | def create_screenshot_folder(folder, t) 4 | begin 5 | FileUtils.mkpath("public/test_results/#{folder}_#{t}/screenshots") 6 | rescue Exception => ex 7 | puts "#{ex}".red 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/subdir_2/forth.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit feature content 2 | To update requirement for project 3 | product owner 4 | should be able to change feature content 5 | 6 | Scenario: Inserting Background 7 | 8 | @2.75 @m1 @mc 9 | Scenario: Inserting Scenario when cursor on text field -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/support/changelog.feature: -------------------------------------------------------------------------------- 1 | Feature: Support - changelog 2 | In order to track changelog without much work 3 | As and developer 4 | I want to be able generate changelog based on filter criteria 5 | (like milestone, iterations, developer) 6 | 7 | @_backlog @m0 8 | Scenario: Generating change log as text -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/data/feature_manager/one_feature.feature: -------------------------------------------------------------------------------- 1 | Feature: Edit feature content 2 | To update requirement for project 3 | product owner 4 | should be able to change feature content 5 | 6 | @5 @m1 7 | Scenario: Inserting Background 8 | 9 | @7.5 @m1 10 | Scenario: Inserting Scenario when cursor on text field -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require(File.join(File.dirname(__FILE__), 'config', 'boot')) 5 | 6 | require 'rake' 7 | require 'rake/testtask' 8 | require 'rake/rdoctask' 9 | 10 | require 'tasks/rails' 11 | -------------------------------------------------------------------------------- /db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }]) 7 | # Major.create(:name => 'Daley', :city => cities.first) 8 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | # Methods added to this helper will be available to all templates in the application. 2 | module ApplicationHelper 3 | 4 | def asset_link(path) 5 | "/documentation/assets/#{path}" 6 | end 7 | 8 | def highlight(name) 9 | (@highlight == name) ? ' highlighted' : nil 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/background.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Background < Struct.new(:feature, :raw) 4 | PATTERN = /((^.*#+.*\n)+\n?)?^[ \t]*Background:.*\n?(^.*\S+.*\n?)*/ 5 | 6 | include CucumberFM::FeatureElement::Component::Title 7 | include CucumberFM::FeatureElement::Component::Comments 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | gem 'chronic' 3 | gem 'watir-webdriver' 4 | gem 'cucumber' 5 | gem 'ruby-debug' 6 | gem 'colorize' 7 | gem 'rspec' 8 | gem 'nokogiri' 9 | gem 'httparty' 10 | gem 'rails', "2.3.14" 11 | gem "sqlite3" 12 | gem "mime-types" 13 | gem "syntax" 14 | gem "sys-proctable" 15 | gem "headless" 16 | 17 | # uncomment below gems if windows 18 | # gem "win32-process" 19 | # gem "win32-open3" 20 | -------------------------------------------------------------------------------- /config/config.yml_example: -------------------------------------------------------------------------------- 1 | config: 2 | #browser can be -> firefox, ie, chrome, safari 3 | browser: firefox 4 | #fixtures are languages.yml files 5 | fixtures: test_data 6 | #true/false = check if there are missing translations on scenario end 7 | check_translation: true 8 | #this is a regexp template for validation on page for missing translations 9 | translation_tag: "@[0-9a-zA-Z]+_[0-9a-zA-Z]+" -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/component/information/component.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | module Component 4 | module Information 5 | module Component 6 | COMPONENT_PATTERN = /@[a-z]\S{3,}\z/ 7 | PATTERN[:component] = COMPONENT_PATTERN 8 | 9 | def component 10 | 11 | end 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /features/sample.feature: -------------------------------------------------------------------------------- 1 | Feature: Sample 2 | 3 | @_done @m0 @_deprecated 4 | Scenario: Check google results for Ruby 5 | Given I go to "http://www.google.de/firefox?client=firefox-a&rls=org.mozilla:en-GB:official" 6 | And I fill in the text field "sf" with "ruby" 7 | And I take a screenshot 8 | And I click the "Google-Suche" button 9 | And I click the "Die Programmiersprache Ruby" link 10 | Then I should see the text "This text is not on Ruby page" -------------------------------------------------------------------------------- /features/support/read_config.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | def read_config 3 | begin 4 | config_file = YAML.load_file("#{Dir.pwd}/config/config.yml") 5 | @browser = config_file['config']['browser'] 6 | @translation_tag = config_file['config']['translation_tag'] 7 | @check_translation = config_file['config']['check_translation'] 8 | @fixtures = config_file['config']['fixtures'].split(" ") 9 | rescue Exception => e 10 | puts "#{e}".red 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/info.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Info < Struct.new(:feature, :raw) 4 | 5 | PATTERN = /((^.*#+.*\n)+\n?)?(^.*@+.*\n)?^[ \t]*Feature:.*\n?(^.*\S+.*\n?)*/ 6 | 7 | include CucumberFM::FeatureElement::Component::Tags 8 | include CucumberFM::FeatureElement::Component::Title 9 | include CucumberFM::FeatureElement::Component::Comments 10 | 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # Filters added to this controller apply to all controllers in the application. 2 | # Likewise, all the methods added will be available for all controllers. 3 | 4 | class ApplicationController < ActionController::Base 5 | helper :all # include all helpers, all the time 6 | protect_from_forgery # See ActionController::RequestForgeryProtection for details 7 | 8 | # Scrub sensitive parameters from your log 9 | # filter_parameter_logging :password 10 | end 11 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/tag.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Tag < Ref 4 | def self.find_all(repo, options = {}) 5 | refs = repo.git.refs(options, prefix) 6 | refs.split("\n").map do |ref| 7 | name, id = *ref.split(' ') 8 | cid = repo.git.commit_from_sha(id) 9 | raise "Unknown object type." if cid == '' 10 | commit = Commit.create(repo, :id => cid) 11 | self.new(name, commit) 12 | end 13 | end 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/business_overview/burndown_graph.feature: -------------------------------------------------------------------------------- 1 | # Will use API to draw graph in extrenal tool 2 | Feature: Burndown graph 3 | In order to measure progres of work 4 | as project manager, developer 5 | I want to be able to define burndow chart that would be redraw every day 6 | 7 | @m0 @_deprecated 8 | Scenario: Defining burndow chart 9 | 10 | @m0 @_deprecated 11 | Scenario: Browsing burndow charts 12 | 13 | @m0 @_deprecated 14 | Scenario: Viewing burndow chart 15 | 16 | -------------------------------------------------------------------------------- /lib/popup_killer_ie.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'win32ole' 3 | 4 | begin 5 | autoit = WIN32OLE.new('AutoItX3.Control') 6 | loop do 7 | autoit.ControlClick("Windows Internet Explorer","", "OK") 8 | autoit.ControlClick("Security Information","", "&Yes") 9 | autoit.ControlClick("Security Alert","", "&Yes") 10 | autoit.ControlClick("Security Warning","", "Yes") 11 | autoit.ControlClick("Message from webpage","", "OK") 12 | sleep 1 13 | end 14 | rescue Exception => e 15 | puts e 16 | end 17 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/layouts/mini.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | <%= yield %> 10 | 11 | -------------------------------------------------------------------------------- /config/initializers/cookie_verification_secret.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.cookie_verifier_secret = '2e50f39363b0b6a48b75ef4a1f148cb94199084aa9b524c53240566bface23ff08f516a39651094f8cb94fac6299f61a3c3235ae80dc2defffeae6918a849a2e'; 8 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/scenario.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class Scenario < Struct.new(:feature, :raw) 4 | PATTERN = /((^.*#+.*\n)+\n?)?(^.*@+.*\n)?^[ \t]*Scenario:.*\n?(^.*\S+.*\n?)*/ 5 | 6 | include CucumberFM::FeatureElement::Component::Tags 7 | include CucumberFM::FeatureElement::Component::Title 8 | include CucumberFM::FeatureElement::Component::Comments 9 | 10 | def second_tags_source 11 | feature.info 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/cvs_integration/pushing_date_to_git_remote_branch.feature: -------------------------------------------------------------------------------- 1 | Feature: Pushing date to git remote branch 2 | In order to synchronize changes made in feature files 3 | developer 4 | should be able to push data to remote branch 5 | 6 | @_backlog @m0 7 | Scenario: Setting local branch configuration 8 | 9 | @_backlog @m0 10 | Scenario: Setting remote branch configuration 11 | 12 | @_backlog @m0 13 | Scenario: Setting push policy 14 | 15 | @_done @m1 @i2 @p4 16 | Scenario: Pushing changes to remote branch 17 | 18 | 19 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/component/comments.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | module Component 4 | module Comments 5 | LINE_PATTERN = /^\s*#+.*$/ 6 | 7 | def comments 8 | @comments ||= fetch_comments 9 | end 10 | 11 | private 12 | 13 | def fetch_comments 14 | raw.scan(LINE_PATTERN).collect do |comment_raw| 15 | CucumberFM::FeatureElement::Comment.new(self, comment_raw) 16 | end 17 | end 18 | end 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/statistics/dashboard.feature: -------------------------------------------------------------------------------- 1 | #:::wireframe::: http://selleo.justproto.com/21b93bb57b408347fa1450ebcd0efbc73f756882/13468 2 | @statistics @m2 @i3 3 | Feature: Statistics - Dashboard 4 | 5 | @_done 6 | Scenario: Overal stats 7 | 8 | @_done 9 | Scenario: Component stats 10 | 11 | @_done 12 | Scenario: Iteration stats 13 | 14 | @_done 15 | Scenario: Bucket stats 16 | 17 | @_done 18 | Scenario: Status stats 19 | 20 | @_done 21 | Scenario: Developer stats 22 | 23 | @_done 24 | Scenario: Various stats 25 | 26 | @_done @i4 27 | Scenario: Something todo stats -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/support/filter_storage.feature: -------------------------------------------------------------------------------- 1 | Feature: Filter storing 2 | In order to have fast access to common group of information 3 | as project manager, developer 4 | I want to be able to save and restore filter 5 | 6 | @_backlog @m0 7 | Scenario: Creating filter scope 8 | 9 | @_backlog @m0 10 | Scenario: Selecting filter scope as active 11 | 12 | @_done @m1 @i1 13 | Scenario: Moving between pages store current scope 14 | When I fill in with config settings 15 | And I press "Refresh" 16 | And I visit dashboard page 17 | Then I should see config values saved as it was before -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/kanban/dashboard.feature: -------------------------------------------------------------------------------- 1 | #:::mockup: http://cs3b-cucumber-fm.s3.amazonaws.com/kanban.png 2 | Feature: Kanban - dashboard 3 | In order to see status of work on project or part 4 | as project manager, developer 5 | I want to be able to browse scenarios aggregated by status 6 | 7 | @_backlog @m0 8 | Scenario: Viewing Kanban 9 | 10 | @_backlog @m0 11 | Scenario: Hiding/Viewing features with scenarios for specific status 12 | 13 | @_backlog @m0 14 | Scenario: Hiding/Showing scenarios for particular feature 15 | 16 | @_backlog @m0 17 | Scenario: Filtering Scenarios by tags and module 18 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3-ruby (not necessary on OS X Leopard) 3 | development: 4 | adapter: sqlite3 5 | database: db/development.sqlite3 6 | pool: 5 7 | timeout: 5000 8 | 9 | # Warning: The database defined as "test" will be erased and 10 | # re-generated from your development database when you run "rake". 11 | # Do not set this db to the same as development or production. 12 | test: 13 | adapter: sqlite3 14 | database: db/test.sqlite3 15 | pool: 5 16 | timeout: 5000 17 | 18 | production: 19 | adapter: sqlite3 20 | database: db/production.sqlite3 21 | pool: 5 22 | timeout: 5000 23 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/watircuke/runme.html.erb: -------------------------------------------------------------------------------- 1 |
2 | Please wait while test is being processed.... 3 | 4 | 21 | 22 |
23 | -------------------------------------------------------------------------------- /config/config.yml: -------------------------------------------------------------------------------- 1 | config: 2 | #browser can be -> firefox, ie, chrome, safari 3 | browser: firefox 4 | #fixtures are languages.yml files 5 | fixtures: sanity_check_pl 6 | #test urls 7 | server_lang: staging home pl 8 | server_login_lang: staging login pl 9 | mybusiness_url: staging.qype.pl/mybusiness/ 10 | admin_login: admin staging login 11 | #true/false = check if there are missing translations on scenario end 12 | check_translation: true 13 | #this is a regexp template for validation on page for missing translations 14 | translation_tag: "@[0-9a-zA-Z]+_[0-9a-zA-Z]+" 15 | 16 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/component/title.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | module Component 4 | module Title 5 | 6 | def title 7 | @title ||= fetch_title 8 | end 9 | 10 | private 11 | 12 | def title_line_pattern 13 | /^\s*[A-Z][a-z]+:\s.*$/ 14 | end 15 | 16 | def fetch_title 17 | if tag_line = title_line_pattern.match(raw) 18 | tag_line[0].gsub(/^[^:]*:/,'').strip 19 | else 20 | '--- no title found' 21 | end 22 | end 23 | end 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/support/filter_basics.feature: -------------------------------------------------------------------------------- 1 | @filter 2 | Feature: Filter basics 3 | In order to fetch only scenarios that i want 4 | as project manager, developer 5 | I want to be able to build filter 6 | 7 | @_done @m1 @i1 @p3 8 | Scenario: Filtering by one tag 9 | 10 | @_done @m1 @i1 @p4 11 | Scenario: Filtering by two tags ( using and ) 12 | 13 | 14 | @_done @m2 @i1 15 | Scenario: Filtering by group of tags ( using or - coma ) 16 | 17 | @_done @m2 @i1 18 | Scenario: Filtering by negation (~) 19 | 20 | @_done @m1 @i1 @p6 21 | Scenario: Agregating by one dimension 22 | 23 | @_done @m1 @i1 24 | Scenario: Agregating by two dimension 25 | 26 | 27 | -------------------------------------------------------------------------------- /features/support/paths.rb_example: -------------------------------------------------------------------------------- 1 | module Paths 2 | def path_to(page_name) 3 | case page_name 4 | # @environment comes from env.rb where it is set to "http://" 5 | #Test any external site 6 | 7 | when /the google home page/i 8 | @environment + "google.com" 9 | #Test any of your local apps 10 | when /the localhost page/i 11 | @environment + "localhost:3000" 12 | 13 | when /the youtube page/i 14 | @environment + "youtube.com" 15 | 16 | else 17 | raise "Can't find mapping from \"#{page_name}\" to a path.\n" + 18 | "Now, go and add a mapping in #{__FILE__}" 19 | end 20 | end 21 | end 22 | 23 | World(Paths) 24 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Comment do 4 | 5 | { 6 | " #:::wireframe::: http://somelink" => :wireframe, 7 | "#:::mockup::: ftp://something" => :mockup, 8 | " #:::doc::: redmine.selleo.com/doc/124.pdf" => :doc 9 | 10 | }.each_pair do |raw, type| 11 | @comment = CucumberFM::FeatureElement::Comment.new("nil", raw) 12 | 13 | it "should be treated as link" do 14 | pending 15 | @comment.send(:is_it_link?).should be_true 16 | end 17 | 18 | it "should recognize type: #{type}" do 19 | pending 20 | @comment.type.should == type 21 | end 22 | end 23 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/editor/comments_notation.feature: -------------------------------------------------------------------------------- 1 | Feature: Editor - comments notations 2 | To keep all information in feature files 3 | as developer and product owner 4 | I want to be able to attach links for source of knowledge 5 | 6 | @_backlog @m0 7 | Scenario: attaching link to wireframe 8 | 9 | @_backlog @m0 10 | Scenario: attaching link to mockup 11 | 12 | @_backlog @m0 13 | Scenario: attaching link with information for developer 14 | 15 | # look for comment scenario below 16 | @_backlog @m0 17 | Scenario: attaching link to question 18 | 19 | # meybe comments would be better than links 20 | #[mc] this is idea for definining dialogs 21 | #[amc] yes looks good :) 22 | @_backlog @m0 23 | Scenario: attaching link to answer 24 | 25 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/scenario_outline.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | class ScenarioOutline < Struct.new(:feature, :raw) 4 | 5 | # TODO requires more specs and some improvements 6 | PATTERN = /((^.*#+.*\n)+\n?)?(^.*@+.*\n)?^[ \t]*Scenario Outline:.*\n?((^.*\S+.*\n?)*\n?)?(^[ \t]*Examples:.*\n(^.*\S+.*\n?)*)?/ 7 | 8 | include CucumberFM::FeatureElement::Component::Tags 9 | include CucumberFM::FeatureElement::Component::Title 10 | include CucumberFM::FeatureElement::Component::Comments 11 | 12 | def second_tags_source 13 | feature.info 14 | end 15 | 16 | private 17 | 18 | def title_line_pattern 19 | /^\s*Scenario Outline:\s.*$/ 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # In the development environment your application's code is reloaded on 4 | # every request. This slows down response time but is perfect for development 5 | # since you don't have to restart the webserver when you make code changes. 6 | config.cache_classes = false 7 | 8 | # Log error messages when you accidentally call methods on nil. 9 | config.whiny_nils = true 10 | 11 | # Show full error reports and disable caching 12 | config.action_controller.consider_all_requests_local = true 13 | config.action_view.debug_rjs = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying cookie session data integrity. 4 | # If you change this key, all old sessions will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.session = { 8 | :key => '_WatirCukeFM_session', 9 | :secret => '11ae7f36eb486ac9e09b53a97c9c27397fc4b1494278c5a0d69eeb813ad9f62b545da6ad60358e74820fb19ac3ce0f18aa39ec5ab4a1415ebfecbd0ec2f938e1' 10 | } 11 | 12 | # Use the database for sessions instead of the cookie-based default, 13 | # which shouldn't be used to store highly confidential information 14 | # (create the session table with "rake db:sessions:create") 15 | # ActionController::Base.session_store = :active_record_store 16 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/statistic.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | class Statistic < Struct.new(:cfm) 3 | 4 | def overal 5 | cfm 6 | end 7 | 8 | def various 9 | @various ||= CucumberFM::Aggregator.new(cfm, nil, CucumberFM::FeatureElement::Component::Tags::TECHNICAL).collection 10 | end 11 | 12 | private 13 | 14 | def method_missing(m, * args, & block) 15 | if CucumberFM::FeatureElement::Component::Tags::PATTERN.has_key?(m.to_sym) 16 | report(m) 17 | else 18 | super 19 | end 20 | end 21 | 22 | def report(aggregate_by) 23 | CucumberFM::Aggregator.new(cfm, (aggregate_by.is_a?(Regexp) ? aggregate_by : patterns(aggregate_by))).collection 24 | end 25 | 26 | def patterns(label) 27 | [CucumberFM::FeatureElement::Component::Tags::PATTERN[label]] 28 | end 29 | 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_file_manipulation_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | #describe CucumberFeatureManager do 4 | # before(:all) do 5 | # `cp -r "spec/data tmp/` 6 | # end 7 | # 8 | # after(:all) do 9 | ## `rm -rf tmp/data` 10 | # end 11 | # 12 | # context "moving file to other directory" do 13 | # before(:each) do 14 | # @path = "tmp/data/feature_manager/subdir/second.feature" 15 | # @path_new = "tmp/data/feature_manager/subdir_2/second.feature" 16 | # @feature = CucumberFM::Feature.new(@path) 17 | ## @feature.file_move_to("tmp/data/feature_manager/subdir_2") 18 | # end 19 | # 20 | # it "should not be file in dir subdir" do 21 | # File.exist?(@path).should be_false 22 | # end 23 | # 24 | # it "should be file in dir subdir_2" do 25 | # File.exist?(@path_new).should be_true 26 | # end 27 | # end 28 | # 29 | #end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/lazy.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # Allows attributes to be declared as lazy, meaning that they won't be 3 | # computed until they are asked for. 4 | # 5 | # Works by delegating each lazy_reader to a cached lazy_source method. 6 | # 7 | # class Person 8 | # lazy_reader :eyes 9 | # 10 | # def lazy_source 11 | # OpenStruct.new(:eyes => 2) 12 | # end 13 | # end 14 | # 15 | # >> Person.new.eyes 16 | # => 2 17 | # 18 | module Lazy 19 | def lazy_reader(*args) 20 | args.each do |arg| 21 | ivar = "@#{arg}" 22 | define_method(arg) do 23 | if instance_variable_defined?(ivar) 24 | val = instance_variable_get(ivar) 25 | return val if val 26 | end 27 | instance_variable_set(ivar, (@lazy_source ||= lazy_source).send(arg)) 28 | end 29 | end 30 | end 31 | end 32 | 33 | Object.extend Lazy unless Object.ancestors.include? Lazy 34 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::Config do 4 | context "default values for" do 5 | before(:each) do 6 | @config = CucumberFM::Config.new 7 | end 8 | {:dir => '', :cvs_commit => '1', :cvs_push => '1'}.each_pair do |attribute, value| 9 | it "#{attribute} should be '#{value}'" do 10 | @config.send(attribute).should == value 11 | end 12 | end 13 | end 14 | 15 | context "saving config" do 16 | before(:each) do 17 | @config = CucumberFM::Config.new('cvs_push' => '0', :aggregate => ['developer']) 18 | end 19 | {:dir => '', :cvs_commit => '1', 20 | :cvs_push => '0', :aggregate => ['developer']}.each_pair do |attribute, value| 21 | it "#{attribute} should be '#{value}'" do 22 | @config.send(attribute).should == value 23 | end 24 | end 25 | end 26 | 27 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/actor.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Actor 4 | attr_reader :name 5 | attr_reader :email 6 | 7 | def initialize(name, email) 8 | @name = name 9 | @email = email 10 | end 11 | alias_method :to_s, :name 12 | 13 | # Create an Actor from a string. 14 | # +str+ is the string, which is expected to be in regular git format 15 | # 16 | # Format 17 | # John Doe 18 | # 19 | # Returns Actor 20 | def self.from_string(str) 21 | case str 22 | when /<.+>/ 23 | m, name, email = *str.match(/(.*) <(.+?)>/) 24 | return self.new(name, email) 25 | else 26 | return self.new(str, nil) 27 | end 28 | end 29 | 30 | # Pretty object inspection 31 | def inspect 32 | %Q{#">} 33 | end 34 | end # Actor 35 | 36 | end # Grit 37 | -------------------------------------------------------------------------------- /features/support/check_for_images.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require "httparty" 3 | require "nokogiri" 4 | require "ruby-debug" 5 | require "rspec" 6 | 7 | Debugger.settings[:autolist] = 1 8 | Debugger.settings[:autoeval] = true 9 | 10 | class Fetcher 11 | include HTTParty 12 | end 13 | 14 | 15 | Given /^I fetch "([^"]*)"$/ do |url| 16 | @url = url 17 | @response = Fetcher.get(url) 18 | end 19 | 20 | Then /^all images should be found$/ do 21 | doc = Nokogiri::HTML(@response.body) 22 | doc.search("img").each do |img| 23 | src = img["src"] 24 | image_path = if src.match(/^\//) 25 | @url + src 26 | elsif src.match(/^http/) 27 | src 28 | end 29 | @checked_images ||= Array.new 30 | next if @checked_images.include?(image_path) 31 | if Fetcher.head(image_path).code != 200 32 | violated "image #{src} not found" 33 | else 34 | @checked_images << image_path 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /features/support/check_missing_translations.rb: -------------------------------------------------------------------------------- 1 | def check_missing_translations 2 | #create a hash and reads the url page content looking for given translation's missing template 3 | h = Hash.new 4 | if doc = Nokogiri.HTML(open(@browser.url)) 5 | doc.text.each_line { |line| 6 | words = line.split 7 | words.each { |w| 8 | if w.match(TRANSLATION_TAG) 9 | if h.has_key?(w) 10 | h[w] = h[w] + 1 11 | else 12 | h[w] = 1 13 | end 14 | end 15 | } 16 | } 17 | 18 | # sort the hash by value, and then print it in this sorted order 19 | h.sort{|a,b| a[1]<=>b[1]}.each { |elem| 20 | puts "Missing translation: #{elem[0]} has #{elem[1]} occurrences on #{@browser.url.to_s}" 21 | } 22 | else 23 | return {} 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # These settings change the behavior of Rails 2 apps and will be defaults 4 | # for Rails 3. You can remove this initializer when Rails 3 is released. 5 | 6 | if defined?(ActiveRecord) 7 | # Include Active Record class name as root for JSON serialized output. 8 | ActiveRecord::Base.include_root_in_json = true 9 | 10 | # Store the full class name (including module namespace) in STI type column. 11 | ActiveRecord::Base.store_full_sti_class = true 12 | end 13 | 14 | ActionController::Routing.generate_best_match = false 15 | 16 | # Use ISO 8601 format for JSON serialized times and dates. 17 | ActiveSupport.use_standard_json_time_format = true 18 | 19 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 20 | # if you're including raw json in an HTML page. 21 | ActiveSupport.escape_html_entities_in_json = false -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/editor/basics.feature: -------------------------------------------------------------------------------- 1 | #:::mockup: http://cs3b-cucumber-fm.s3.amazonaws.com/editor.png 2 | @editor 3 | Feature: Editor - Basics 4 | To update requirement for project 5 | product owner 6 | should be able to change feature content 7 | 8 | @_done @m1 @i2 @p2 9 | Scenario: Viewing editor 10 | 11 | @_done @m1 @i2 @p3 12 | Scenario: Updating feature contennt 13 | 14 | @_done @m2 @i2 15 | Scenario: Moving feature to other directory 16 | 17 | @_done @m2 @i2 18 | Scenario: Renaming filename 19 | 20 | @_done @m2 @i2 21 | Scenario: Deleting feature 22 | 23 | @_done @m1 @i4 24 | Scenario: Navigating between scenarios 25 | 26 | @_done @m2 @i4 27 | Scenario: Showing estimation for each scenario in navigation list 28 | 29 | @_done @m2 @i4 30 | Scenario: Showing tags for each scenario in navigation list 31 | 32 | @_done @m2 @i4 33 | Scenario: Simple filter and search on navigation list 34 | 35 | 36 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/config.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Config 4 | def initialize(repo) 5 | @repo = repo 6 | end 7 | 8 | def []=(key, value) 9 | @repo.git.config({}, key, value) 10 | @data = nil 11 | end 12 | 13 | def [](key) 14 | data[key] 15 | end 16 | 17 | def fetch(key, default = nil) 18 | data[key] || default || raise(IndexError.new("key not found")) 19 | end 20 | 21 | def keys 22 | data.keys 23 | end 24 | 25 | protected 26 | def data 27 | @data ||= load_config 28 | end 29 | 30 | def load_config 31 | hash = {} 32 | config_lines.map do |line| 33 | key, value = line.split(/=/, 2) 34 | hash[key] = value 35 | end 36 | hash 37 | end 38 | 39 | def config_lines 40 | @repo.git.config(:list => true).split(/\n/) 41 | end 42 | end # Config 43 | 44 | end # Grit -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/git-ruby/internal/raw_object.rb: -------------------------------------------------------------------------------- 1 | # 2 | # converted from the gitrb project 3 | # 4 | # authors: 5 | # Matthias Lederhofer 6 | # Simon 'corecode' Schubert 7 | # 8 | # provides native ruby access to git objects and pack files 9 | # 10 | 11 | require 'digest/sha1' 12 | 13 | module Grit 14 | module GitRuby 15 | module Internal 16 | OBJ_NONE = 0 17 | OBJ_COMMIT = 1 18 | OBJ_TREE = 2 19 | OBJ_BLOB = 3 20 | OBJ_TAG = 4 21 | 22 | OBJ_TYPES = [nil, :commit, :tree, :blob, :tag].freeze 23 | 24 | class RawObject 25 | attr_accessor :type, :content 26 | def initialize(type, content) 27 | @type = type 28 | @content = content 29 | end 30 | 31 | def sha1 32 | Digest::SHA1.digest("%s %d\0" % [@type, @content.length] + @content) 33 | end 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/editor/advance.feature: -------------------------------------------------------------------------------- 1 | @editor 2 | Feature: Editor - advance 3 | In order to have better - in real time - collaboration 4 | As a manager and product owner 5 | I want to have editor that have no delay when more then one person working on the same feature content, 6 | also with syntax highlighting and shortcuts, live validation 7 | 8 | @_backlog @m0 9 | Scenario: Two people can collaborate on this same feature 10 | Given Tom is logged in 11 | And he is editing feature "Business overview - dashboard" 12 | And Greg is also loggoed in 13 | And he is editing feature "Business overview - dashboard" 14 | When Tom put focus below last scenario and he write "Scen" 15 | Then Greg should imediately see "Scen" within editor in his browser 16 | When Greg write "ario: " 17 | Then Tome should imediately see "Scenario: " within editor in his browser 18 | 19 | @_done @m2 @i5 20 | Scenario: Syntax highlighting 21 | 22 | @_backlog @m0 23 | Scenario: Keyboard Shortcuts -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/open3_detach.rb: -------------------------------------------------------------------------------- 1 | module Open3 2 | extend self 3 | 4 | def popen3(*cmd) 5 | pw = IO::pipe # pipe[0] for read, pipe[1] for write 6 | pr = IO::pipe 7 | pe = IO::pipe 8 | 9 | pid = fork{ 10 | # child 11 | fork{ 12 | # grandchild 13 | pw[1].close 14 | STDIN.reopen(pw[0]) 15 | pw[0].close 16 | 17 | pr[0].close 18 | STDOUT.reopen(pr[1]) 19 | pr[1].close 20 | 21 | pe[0].close 22 | STDERR.reopen(pe[1]) 23 | pe[1].close 24 | 25 | exec(*cmd) 26 | } 27 | exit!(0) 28 | } 29 | 30 | pw[0].close 31 | pr[1].close 32 | pe[1].close 33 | Process.waitpid(pid) 34 | pi = [pw[1], pr[0], pe[0]] 35 | pw[1].sync = true 36 | if defined? yield 37 | begin 38 | return yield(*pi) 39 | ensure 40 | Process.detach(pid) if pid 41 | pi.each { |p| p.close unless p.closed? } 42 | end 43 | end 44 | pi 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The change you wanted was rejected (422) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The change you wanted was rejected.

27 |

Maybe you tried to change something you didn't have access to.

28 |
29 | 30 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/javascripts/BespinSyntaxGherkin.js: -------------------------------------------------------------------------------- 1 | "define metadata"; 2 | ({ 3 | "description" : "Gherkin syntax highlighter", 4 | "dependencies" : { "standard_syntax" : "0.0.0" }, 5 | "environments": { "worker": true }, 6 | "provides": 7 | [ 8 | { 9 | "ep": "syntax", 10 | "name": "gherkin", 11 | "pointer": "#GherkinSyntax", 12 | "fileexts": ["feature"] 13 | }, 14 | { 15 | "ep": "themestyles", 16 | "url": [ 17 | "gherkin.less" 18 | ] 19 | } 20 | 21 | ] 22 | }); 23 | "end"; 24 | 25 | //var StandardSyntax = require('standard_syntax').StandardSyntax; 26 | 27 | var states = {} 28 | 29 | states['topic_keywords'] = [ 30 | { 31 | regex: /(Feature:|Scenario:|Scenario Outline:)/, 32 | tag: 'topic_keyword' 33 | }, 34 | { 35 | regex: /^\s*#.*$/, 36 | tag: 'comment' 37 | }, 38 | ] 39 | 40 | exports.GherkinSyntax = new StandardSyntax.create(states, ['js']); 41 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The page you were looking for doesn't exist (404) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The page you were looking for doesn't exist.

27 |

You may have mistyped the address or the page may have moved.

28 |
29 | 30 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/controllers/documentation/assets_controller.rb: -------------------------------------------------------------------------------- 1 | class Documentation::AssetsController < Documentation::ApplicationController 2 | 3 | # TODO in future use xsend_file for apache or X-ACCEELL for nginx 4 | def get 5 | if File.exist?(full_path) 6 | send_file(full_path, {:type => file_content_type}) 7 | else 8 | render :text => "file not found", :status => 404 9 | end 10 | end 11 | 12 | private 13 | 14 | def full_path 15 | Rails.root.join('vendor', 'plugins', 'cucumber_fm', 'public', file_path) 16 | end 17 | 18 | def file_path 19 | params[:path] 20 | end 21 | 22 | def file_extension 23 | File.basename(file_path).split(".").last 24 | end 25 | 26 | # definitely there exist some library for that 27 | def file_content_type 28 | case file_path 29 | when /js$/ 30 | "application/x-javascript" 31 | when /(css|less|otf)$/ 32 | "text/css" 33 | when /(jpg|png)$/ 34 | "image/#{file_extension}" 35 | else 36 | "text" 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/editor/settings_cvs.feature: -------------------------------------------------------------------------------- 1 | Feature: Editor - Settings CVS 2 | To make possible to edit files but skip git commit or push - when this behaviour is not desirable 3 | developer 4 | should be able to turn off cvs facilities in editor view 5 | 6 | Background: In edit page 7 | Given I'm on the editor page for feature 'test.feature' 8 | 9 | @_done @m1 @i6 10 | Scenario: By default all ticks should checked 11 | 12 | @_done @m1 @i6 13 | Scenario: Skip push 14 | When I uncheck "push" 15 | And I make some change in content 16 | And I press save 17 | Then content of file should be saved 18 | And commit to local branch should be done 19 | But remote branch should not be updated 20 | 21 | @_done @m1 @i6 22 | Scenario: Skip commit and push 23 | When I uncheck "commit" 24 | And I make some change in content 25 | And I press save 26 | Then content of file should be saved 27 | But commit to local branch should not be done 28 | And remote branch should not be updated 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/info_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Info do 4 | before(:all) do 5 | raw = < 3 | 4 | 5 | 6 | 7 | 8 | We're sorry, but something went wrong (500) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

We're sorry, but something went wrong.

27 |

We've been notified about this issue and we'll take a look at it shortly.

28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/config.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | class Config 3 | attr_accessor :dir, :tags, :aggregate, :sort, :display_as, :cvs_commit, :cvs_push 4 | 5 | def initialize(params={}) 6 | set_default_values 7 | update(params) 8 | end 9 | 10 | def aggregate_options 11 | [''] + CucumberFM::FeatureElement::Component::Tags::PATTERN.keys.map(& :to_s).sort 12 | end 13 | 14 | private 15 | 16 | def set_default_values 17 | update( 18 | { 19 | :dir => '', 20 | :tags => '', 21 | :aggregate => [], 22 | :sort => '', 23 | :display_as => 'list', 24 | :cvs_commit => '0', 25 | :cvs_push => '0' 26 | }) 27 | 28 | end 29 | 30 | def update(params) 31 | params.each_pair do |attribute, value| 32 | setter_method_name = "#{attribute}=" 33 | send(setter_method_name, value) if respond_to? setter_method_name 34 | end 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /features/support/select_browser.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | def select_browser(browser) 3 | case browser 4 | when "safari" 5 | require 'safariwatir' 6 | Watir::Safari.new 7 | #Browser.set_fast_speed = true 8 | 9 | when "firefox", "ff" 10 | require 'watir-webdriver' 11 | Watir::Browser.new :firefox 12 | 13 | when "chrome" 14 | require 'watir-webdriver' 15 | Watir::Browser.new :chrome 16 | 17 | when "ie", "internet explorer" 18 | # require 'watir' 19 | # require 'watir/ie' 20 | # require 'win32ole' 21 | # require 'win32/process' 22 | # ie = Watir::IE.new 23 | # ie.speed = :zippy #browser speed :fast / :zippy 24 | # return ie 25 | 26 | #works OK after update to newest gems 27 | 28 | require 'watir-webdriver' 29 | Watir::Browser.new :ie 30 | 31 | when "celerity" 32 | require 'celerity' 33 | Celerity::Browser.new 34 | 35 | when "headless" 36 | require 'headless' 37 | Headless.new 38 | else 39 | raise "This platform is not supported (#{PLATFORM})" 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The production environment is meant for finished, "live" apps. 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.action_controller.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | config.action_view.cache_template_loading = true 11 | 12 | # See everything in the log (default is :info) 13 | # config.log_level = :debug 14 | 15 | # Use a different logger for distributed setups 16 | # config.logger = SyslogLogger.new 17 | 18 | # Use a different cache store in production 19 | # config.cache_store = :mem_cache_store 20 | 21 | # Enable serving of images, stylesheets, and javascripts from an asset server 22 | # config.action_controller.asset_host = "http://assets.example.com" 23 | 24 | # Disable delivery errors, bad email addresses will be ignored 25 | # config.action_mailer.raise_delivery_errors = false 26 | 27 | # Enable threaded mode 28 | # config.threadsafe! -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Grzegorz Smajdor 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /lib/run_watircuke_setup.rb: -------------------------------------------------------------------------------- 1 | module RunWatirCukeSetup 2 | require 'rubygems' 3 | require 'cucumber' 4 | require 'colorize' 5 | 6 | require "#{Dir.pwd}/features/support/create_screenshot_folder" 7 | 8 | def setup(folder) 9 | t=Time.now.strftime("%y%m%d%H%M") 10 | create_screenshot_folder("#{folder}", t) 11 | end 12 | 13 | def validate_browser(bro) 14 | all_browsers.include?(bro) 15 | end 16 | 17 | def name_the_test(test) 18 | test.gsub(/\w+\_/,"") 19 | end 20 | 21 | def default_run 22 | puts "Did not found the test.".red 23 | puts 24 | puts "You could run me with:" 25 | puts "./watircuke.rb @tag output".green 26 | puts "or" 27 | puts "./watircuke.rb features/my_test.feature output".green 28 | puts " " 29 | end 30 | 31 | def finishit(folder, test, is_cmd=nil) 32 | # if is_cmd 33 | puts 34 | puts "Copy the path to browser to view results" 35 | puts "#{Dir.pwd}/#{folder.gsub('screenshots','')}#{test}.html".green 36 | # end 37 | end 38 | 39 | def all_browsers 40 | %w/ie ff chrome safari headless/ 41 | end 42 | 43 | end 44 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/merge.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Merge 4 | 5 | STATUS_BOTH = 'both' 6 | STATUS_OURS = 'ours' 7 | STATUS_THEIRS = 'theirs' 8 | 9 | attr_reader :conflicts, :text, :sections 10 | 11 | def initialize(str) 12 | status = STATUS_BOTH 13 | 14 | section = 1 15 | @conflicts = 0 16 | @text = {} 17 | 18 | lines = str.split("\n") 19 | lines.each do |line| 20 | if /^<<<<<<< (.*?)/.match(line) 21 | status = STATUS_OURS 22 | @conflicts += 1 23 | section += 1 24 | elsif line == '=======' 25 | status = STATUS_THEIRS 26 | elsif /^>>>>>>> (.*?)/.match(line) 27 | status = STATUS_BOTH 28 | section += 1 29 | else 30 | @text[section] ||= {} 31 | @text[section][status] ||= [] 32 | @text[section][status] << line 33 | end 34 | end 35 | @text = @text.values 36 | @sections = @text.size 37 | end 38 | 39 | # Pretty object inspection 40 | def inspect 41 | %Q{# 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /watircuke.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'lib/run_watircuke_setup' 3 | include RunWatirCukeSetup 4 | 5 | class RunMe 6 | 7 | def initialize 8 | start(ARGV[0], ARGV[1], ARGV[2], ARGV[3]) 9 | end 10 | 11 | def start(test, out, browser, web) 12 | run_with_browser = "BROWSER=#{browser}" if RunWatirCukeSetup::validate_browser(browser) 13 | is_cmd = "CMD=true" unless web 14 | if ("#{test}" =~/\@/) 15 | folder = RunWatirCukeSetup::setup(out ||= test.gsub("\@","").gsub("\,","_")) 16 | result = "#{folder}/../#{out}.html" 17 | system "cucumber #{is_cmd}" + "#{run_with_browser}" + " --guess -t #{test} -f html > #{result}" 18 | RunWatirCukeSetup::finishit(folder, out, is_cmd) 19 | elsif ("#{test}" =~/features/) 20 | folder = RunWatirCukeSetup::setup(out ||= test.gsub(/\w+\//,"").gsub(/\.\w+/,"")) 21 | result = "#{folder}/../#{out}.html" 22 | system "cucumber #{is_cmd} " + "#{run_with_browser}" + " --guess #{test} -f html > #{result}" 23 | RunWatirCukeSetup::finishit(folder, out, is_cmd) 24 | else 25 | RunWatirCukeSetup::default_run 26 | end 27 | end 28 | end 29 | 30 | RunMe.new 31 | 32 | 33 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/models/watircuke.rb: -------------------------------------------------------------------------------- 1 | class Watircuke 2 | 3 | def self.browsers 4 | Watircuke.is_windows? ? %w/ff ie chrome safari/ : %w/ff chrome safari/ 5 | end 6 | 7 | def self.find_test_folder 8 | Dir["public/test_results/*"].select{|x| File.directory?(x)}.map{|x| [File.ctime(x), x]}.sort_by{|x| x.first}.last.last 9 | end 10 | 11 | def self.start_process(runme) 12 | if Watircuke.is_windows? 13 | system("start \"WatirCuke\" #{runme}") 14 | else 15 | Process.fork { system(runme) } 16 | end 17 | end 18 | 19 | def self.find_process 20 | proc = [] 21 | if Watircuke.is_windows? 22 | Sys::ProcTable.ps.each do |pr| 23 | proc << pr.pid if pr.cmdline =~ /cucumber/i 24 | end 25 | else 26 | temp = IO.popen("ps -ef | grep cucumber | awk '{print $2}'") 27 | proc = temp.to_a 28 | temp.close 29 | end 30 | return proc if proc.length > 0 31 | end 32 | 33 | def self.is_windows? 34 | RUBY_PLATFORM.downcase.match(/mswin|i386-mingw32/) 35 | end 36 | 37 | 38 | end 39 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/business_overview/create_new_feature.feature: -------------------------------------------------------------------------------- 1 | Feature: Business Overview - Create New Feature 2 | To track information about new requirements 3 | product owner 4 | should be able to add new feature 5 | 6 | @_done @m1 @i3 @p2 7 | Scenario: Creating new feature file 8 | Given I am on the business overview page 9 | When I fill in "name" with "Editor - advance" 10 | And I press "Add" 11 | Then I should be redirected to edit page for feature 'editor___advance.feature' 12 | 13 | @_done @m1 @i4 @p7 14 | Scenario: Creating new feature file with name that already exist 15 | Given feature with name 'awesome_tagging.feature' exists 16 | And I am on the business overview page 17 | When I fill in "name" with "Awesome Tagging" 18 | And I press "Add" 19 | Then I should be redirected to edit page for feature 'awesome_tagging.feature' 20 | 21 | @_done @m1 @i4 @p4 22 | Scenario: Creating new feature file with too short name 23 | Given I am on the business overview page 24 | When I fill in "name" with "Abc" 25 | And I press "Add" 26 | Then I should see error notice "Filename is too short" 27 | 28 | 29 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2007-2009 Tom Preston-Werner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/features/business_overview/dashboard.feature: -------------------------------------------------------------------------------- 1 | #:::mockup::: http://cs3b-cucumber-fm.s3.amazonaws.com/business.overview.png 2 | @business-dashboard 3 | Feature: Business Overview - dashboard 4 | In order to view stuff to do and see cost and value 5 | As project manager, product owner 6 | I want to see estimation based on active scope and filter 7 | 8 | @_done @m1 @i1 9 | Scenario: Viewing dashobard 10 | When I visit documentation page 11 | Then I should see: 12 | |list of features | 13 | |total quantity of features, scenarios and estimation | 14 | |per feature total quantity of scenarios and estimation | 15 | 16 | @_done @m1 @i1 17 | Scenario: Filtering By tag and folder 18 | 19 | @_done @m1 @i1 20 | Scenario: Agregating by tag type 21 | 22 | @_done @m1 @i2 23 | Scenario: Going to feature editing 24 | 25 | @_done @m1 @i2 26 | Scenario: Agregating based on tag type 27 | 28 | @_done @m2 @i3 29 | Scenario: Sort tags that are use to aggregate 30 | 31 | @_done @m2 @i5 32 | Scenario: Clicking on scenario 33 | Then I should be on feature page 34 | And I editor should be focus on the scenario line -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/background_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::Background do 4 | before(:each) do 5 | raw = < { :id => /.*[^(\/(edit|statistic))]/}, :conditions => { :method => :get }, 4 | :controller => 'features', 5 | :action => 'show' 6 | doc.feature_update 'features/:id', :requirements => { :id => /.*[^(\/edit)]/}, :conditions => { :method => :post }, 7 | :controller => 'features', 8 | :action => 'update' 9 | doc.feature_run 'features/:id', :conditions => {:method => "post"}, 10 | :controller => 'features', 11 | :action => 'runme' 12 | 13 | doc.watircuke_results 'watircuke/results', :controller => 'watircuke', :action => 'results' 14 | 15 | # doc.resources :watircuke, :member => [:delete] 16 | 17 | doc.resources :features, :member => [:rename, :delete, :move], :collection => [:statistic] 18 | doc.resource :kanban, :controller => 'kanban' 19 | doc.connect "assets/:path", :controller => 'assets', :action => 'get', 20 | :requirements => { :path => /.*/ } 21 | 22 | end 23 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ */ 2 | /* v1.0 | 20080212 */ 3 | 4 | html, body, div, span, applet, object, iframe, 5 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 6 | a, abbr, acronym, address, big, cite, code, 7 | del, dfn, em, font, img, ins, kbd, q, s, samp, 8 | small, strike, strong, sub, sup, tt, var, 9 | b, u, i, center, 10 | dl, dt, dd, ol, ul, li, 11 | fieldset, form, label, legend, 12 | table, caption, tbody, tfoot, thead, tr, th, td { 13 | margin: 0; 14 | padding: 0; 15 | border: 0; 16 | outline: 0; 17 | font-size: 100%; 18 | vertical-align: baseline; 19 | background: transparent; 20 | } 21 | body { 22 | line-height: 1; 23 | } 24 | ol, ul { 25 | list-style: none; 26 | } 27 | blockquote, q { 28 | quotes: none; 29 | } 30 | blockquote:before, blockquote:after, 31 | q:before, q:after { 32 | content: ''; 33 | content: none; 34 | } 35 | 36 | /* remember to define focus styles! */ 37 | :focus { 38 | outline: 0; 39 | } 40 | 41 | /* remember to highlight inserts somehow! */ 42 | ins { 43 | text-decoration: none; 44 | } 45 | del { 46 | text-decoration: line-through; 47 | } 48 | 49 | /* tables still need 'cellspacing="0"' in the markup */ 50 | table { 51 | border-collapse: collapse; 52 | border-spacing: 0; 53 | } -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/stylesheets/device_width.css: -------------------------------------------------------------------------------- 1 | @media all and (min-width: 1601px) 2 | { 3 | #container 4 | { 5 | width: 1400px; 6 | } 7 | 8 | 9 | .frame .content .left 10 | { 11 | width: 1140px; 12 | } 13 | 14 | } 15 | 16 | 17 | @media all and (max-width: 1600px) and (min-width: 1251px) 18 | { 19 | #container 20 | { 21 | width: 1200px; 22 | } 23 | 24 | .frame .content .left 25 | { 26 | width: 940px; 27 | } 28 | } 29 | 30 | 31 | 32 | @media all and (min-width: 1251px) 33 | { 34 | .frame .head .actions 35 | { 36 | width: 260px; 37 | } 38 | 39 | 40 | .frame .two_columns 41 | { 42 | background: url(/documentation/assets/images//layout/frame_content_twocolumns_wider.png) repeat-y right top #fff; 43 | } 44 | 45 | 46 | .frame .content .right 47 | { 48 | width: 257px; 49 | } 50 | 51 | .inputs ol li.string input, 52 | .inputs ol li.password input 53 | { 54 | /*width: 170px;*/ 55 | width: 230px; 56 | } 57 | 58 | .inputs ol li.select select 59 | { 60 | /*width: 178px;*/ 61 | width: 238px; 62 | margin-bottom: 3px; 63 | } 64 | 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/cvs/git_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # test is too expensive to run it each time 4 | 5 | #describe CucumberFM::Cvs::Git do 6 | # before(:all) do 7 | # @remote_repo = 'git@github.com:cs3b/cucumber_fm_test_repo.git' 8 | # @base_repo_path = Dir.getwd + '/tmp/repo_base' 9 | # @repo_path = '/tmp/repo' 10 | # `git clone #{@base_repo_path} #{@repo_path}` 11 | # @cfm = CucumberFeatureManager.new(@repo_path+'/features', @repo_path) 12 | # @repo = @cfm.send(:repo) 13 | # `cd #{@repo_path} && git remote rm origin` 14 | # @repo.remote_add('origin', @remote_repo) 15 | ## @repo.git.push({}, '--force', 'origin', 'master:master') 16 | # end 17 | # 18 | # after(:all) do 19 | # `rm -rf #{@repo_path}` 20 | # # remove all remotes except master 21 | # end 22 | # 23 | # it "should be able to add changes to stash" do 24 | # f = @cfm.features.first 25 | # f.raw = 'Hello' 26 | # f.save 27 | # commit = @cfm.commit_change_on(f) 28 | # commit.should =~ /1 files changed/ 29 | # end 30 | # 31 | # it "should detect that there is no changes" 32 | # 33 | # it "should be able to commit changes to local branch" 34 | # 35 | # it "should be able to push changes to remote branch" do 36 | # @cfm.send_to_remote 37 | # end 38 | # it "should handle when remote branch is not fast forward" 39 | # 40 | #end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/README.rdoc: -------------------------------------------------------------------------------- 1 | = Cucumber Feature Manager 2 | 3 | tool that supports scope management using cucumber features as specification 4 | 5 | = DEMO 6 | 7 | http://demo.cucumber.fm 8 | 9 | = INFO 10 | 11 | http://cucumber.fm 12 | 13 | For now it only works when: 14 | 15 | * you are using rails version 2.3.8 or 3.0.0 16 | * you have features directory inside your rails app 17 | 18 | Any feedback would be valuable ( use github issue ) 19 | always provide information as: 20 | * os 21 | * ruby version 22 | * rails version 23 | * backtrace 24 | 25 | == Requirements 26 | 27 | you are using rails 28 | * 2.3.8 and higher 29 | * 3.0 and higher 30 | 31 | on rails 3.0 there some deprecation warning - would be fixed soon 32 | 33 | == Installation 34 | 35 | === rails 2 36 | 37 | script/plugin install git://github.com/cs3b/cucumber_fm.git 38 | 39 | inside config/environment.rb 40 | 41 | config.gem 'diff-lcs', :lib => false 42 | 43 | install gem 44 | 45 | gem install diff-lcs 46 | 47 | === rails 3 48 | 49 | rails plugin install git://github.com/cs3b/cucumber_fm.git 50 | 51 | inside Gemfile 52 | 53 | gem 'diff-lcs', :require => false 54 | 55 | install gem 56 | 57 | bundle install 58 | 59 | 60 | == Usage 61 | 62 | start rails application and go to path in your browser: 63 | 64 | /documentation/features 65 | 66 | == Documentation 67 | 68 | http://cucumber.fm 69 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/component/total_estimation.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | module Component 4 | module TotalEstimation 5 | def estimation 6 | scenarios.inject(0.0) { |sum, scenario| sum + scenario.estimation } 7 | end 8 | 9 | def estimation_done 10 | scenarios.inject(0.0) do |sum, scenario| 11 | estimation_done_filter.pass?(scenario.tags) ? 12 | sum + scenario.estimation : 13 | sum 14 | end 15 | end 16 | 17 | def estimation_done_percentage 18 | estimation > 0 ? ( estimation_done.to_f / estimation * 100 ).round : 0 19 | end 20 | 21 | def scenarios_done 22 | scenarios.inject(0) do |sum, scenario| 23 | estimation_done_filter.pass?(scenario.tags) ? 24 | sum + 1 : 25 | sum 26 | end 27 | end 28 | 29 | def scenarios_done_percentage 30 | !scenarios.empty? ? ( scenarios_done.to_f / scenarios.size * 100 ).round : 0 31 | end 32 | 33 | private 34 | 35 | def estimation_done_filter 36 | tags = CucumberFM::FeatureElement::Component::Tags::STATUS_COMPLETE 37 | @estimation_done_filter = CucumberFM::TagFilter.new(tags.join(',')) 38 | end 39 | end 40 | end 41 | end 42 | end -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | config.cache_classes = true 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.action_controller.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | config.action_view.cache_template_loading = true 16 | 17 | # Disable request forgery protection in test environment 18 | config.action_controller.allow_forgery_protection = false 19 | 20 | # Tell Action Mailer not to deliver emails to the real world. 21 | # The :test delivery method accumulates sent emails in the 22 | # ActionMailer::Base.deliveries array. 23 | config.action_mailer.delivery_method = :test 24 | 25 | # Use SQL instead of Active Record's schema dumper when creating the test database. 26 | # This is necessary if your schema can't be completely dumped by the schema dumper, 27 | # like if you have constraints or database-specific column types 28 | # config.active_record.schema_format = :sql -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/controllers/documentation/application_controller.rb: -------------------------------------------------------------------------------- 1 | class Documentation::ApplicationController < ActionController::Base 2 | 3 | require 'win32/process' if Watircuke.is_windows? 4 | require 'sys/proctable' 5 | 6 | layout '/documentation/layouts/cucumber_fm' 7 | 8 | helper :all 9 | 10 | before_filter :save_config 11 | 12 | helper_method :list_of_dirs 13 | 14 | private 15 | 16 | def feature_dir_path 17 | git_dir_path.join('features') 18 | end 19 | 20 | def results_dir_path 21 | Rails.root.join('public/test_results') 22 | end 23 | 24 | def git_dir_path 25 | Rails.root 26 | end 27 | 28 | def dir_that_should_be_skippped 29 | %w(_step_definitions support machines . ..) 30 | end 31 | 32 | def list_of_dirs 33 | [""] + 34 | (Dir.entries(feature_dir_path) - dir_that_should_be_skippped).collect { |name| 35 | name if File.directory?(File.join(feature_dir_path, name)) }.compact.sort 36 | end 37 | 38 | def save_config 39 | if params.has_key?(:config) 40 | cookies[:config] = params[:config].to_json 41 | elsif cookies[:config].nil? 42 | cookies[:config] = {'dir' => ''}.to_json 43 | elsif !read_config.has_key?('dir') 44 | p = read_config 45 | p['dir'] = '' 46 | cookies[:config] = p.to_json 47 | end 48 | end 49 | 50 | def read_config 51 | JSON.parse(cookies[:config]) 52 | end 53 | 54 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/scenario_outline_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFM::FeatureElement::ScenarioOutline do 4 | before(:each) do 5 | raw = %Q{#{@comment = "## wireframe::http://somelink"} 6 | #{@comment1 = "# some text comment"} 7 | 8 | @_todo @2 @hash @wow 9 | Scenario Outline: #{@title = "Creating filter scope"} 10 | When I follow "New system user" 11 | And I fill in "password" for "Password Confirmation" 12 | 13 | Examples: 14 | |id |email |roles | 15 | |5 |some@oo.com |admin |} 16 | @feature = CucumberFM::Feature.new('fake_path') 17 | @scenario = CucumberFM::FeatureElement::ScenarioOutline.new(@feature, raw) 18 | @scenario.stub!(:parent_tags).and_return([]) 19 | end 20 | it "should have access to feature" do 21 | @scenario.feature.should == @feature 22 | end 23 | it "should parse tags" do 24 | @scenario.tags.should == %w(@_todo @2 @hash @wow) 25 | end 26 | it "should parse estimation" do 27 | @scenario.estimation.should == 2.0 28 | end 29 | it "should parse comments lines" do 30 | CucumberFM::FeatureElement::Comment.should_receive(:new).with(@scenario, @comment) 31 | CucumberFM::FeatureElement::Comment.should_receive(:new).with(@scenario, @comment1) 32 | @scenario.should have(2).comments 33 | end 34 | it "should parse title" do 35 | @scenario.title.should == @title 36 | end 37 | # it "should parse steps" 38 | # it "should parse example outline" 39 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/git-ruby/internal/file_window.rb: -------------------------------------------------------------------------------- 1 | # 2 | # converted from the gitrb project 3 | # 4 | # authors: 5 | # Matthias Lederhofer 6 | # Simon 'corecode' Schubert 7 | # Scott Chacon 8 | # 9 | # provides native ruby access to git objects and pack files 10 | # 11 | 12 | module Grit 13 | module GitRuby 14 | module Internal 15 | class FileWindow 16 | def initialize(file, version = 1) 17 | @file = file 18 | @offset = nil 19 | if version == 2 20 | @global_offset = 8 21 | else 22 | @global_offset = 0 23 | end 24 | end 25 | 26 | def unmap 27 | @file = nil 28 | end 29 | 30 | def [](*idx) 31 | idx = idx[0] if idx.length == 1 32 | case idx 33 | when Range 34 | offset = idx.first 35 | len = idx.last - idx.first + idx.exclude_end? ? 0 : 1 36 | when Fixnum 37 | offset = idx 38 | len = nil 39 | when Array 40 | offset, len = idx 41 | else 42 | raise RuntimeError, "invalid index param: #{idx.class}" 43 | end 44 | if @offset != offset 45 | @file.seek(offset + @global_offset) 46 | end 47 | @offset = offset + len ? len : 1 48 | if not len 49 | @file.read(1).getord(0) 50 | else 51 | @file.read(len) 52 | end 53 | end 54 | end 55 | end 56 | end 57 | end 58 | 59 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/blame.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Blame 4 | 5 | attr_reader :lines 6 | 7 | def initialize(repo, file, commit) 8 | @repo = repo 9 | @file = file 10 | @commit = commit 11 | @lines = [] 12 | load_blame 13 | end 14 | 15 | def load_blame 16 | output = @repo.git.blame({'p' => true}, @commit, '--', @file) 17 | process_raw_blame(output) 18 | end 19 | 20 | def process_raw_blame(output) 21 | lines, final = [], [] 22 | info, commits = {}, {} 23 | 24 | # process the output 25 | output.split("\n").each do |line| 26 | if line[0, 1] == "\t" 27 | lines << line[1, line.size] 28 | elsif m = /^(\w{40}) (\d+) (\d+)/.match(line) 29 | if !commits[m[1]] 30 | commits[m[1]] = @repo.commit(m[1]) 31 | end 32 | info[m[3].to_i] = [commits[m[1]], m[2].to_i] 33 | end 34 | end 35 | 36 | # get it together 37 | info.sort.each do |lineno, commit| 38 | final << BlameLine.new(lineno, commit[1], commit[0], lines[lineno - 1]) 39 | end 40 | 41 | @lines = final 42 | end 43 | 44 | # Pretty object inspection 45 | def inspect 46 | %Q{#">} 47 | end 48 | 49 | class BlameLine 50 | attr_accessor :lineno, :oldlineno, :commit, :line 51 | def initialize(lineno, oldlineno, commit, line) 52 | @lineno = lineno 53 | @oldlineno = oldlineno 54 | @commit = commit 55 | @line = line 56 | end 57 | end 58 | 59 | end # Blame 60 | 61 | end # Grit -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/git-ruby/commit_db.rb: -------------------------------------------------------------------------------- 1 | begin 2 | require 'sequel' 3 | 4 | module Grit 5 | 6 | class CommitDb 7 | 8 | SCHEMA_VERSION = 1 9 | 10 | attr_accessor :db, :git 11 | 12 | def initialize(git_obj, index_location = nil) 13 | @git = git_obj 14 | db_file = File.join(index_location || @git.git_dir, 'commit_db') 15 | if !File.exists?(db_file) 16 | @db = Sequel.open "sqlite:///#{db_file}" 17 | setup_tables 18 | else 19 | @db = Sequel.open "sqlite:///#{db_file}" 20 | end 21 | end 22 | 23 | def rev_list(branch, options) 24 | end 25 | 26 | def update_db(branch = nil) 27 | # find all refs/heads, for each 28 | # add branch if not there 29 | # go though all commits in branch 30 | # add new commit_branches a 31 | # and commit_nodes for each new one 32 | # stop if reach commit that already has branch and node links 33 | end 34 | 35 | def setup_tables 36 | @db << "create table meta (meta_key text, meta_value text)" 37 | @db[:meta] << {:meta_key => 'schema', :meta_value => SCHEMA_VERSION} 38 | 39 | @db << "create table commits (id integer, sha text, author_date integer)" 40 | @db << "create table nodes (id integer, path text, type text)" 41 | @db << "create table branches (id integer, ref text, commit_id integer)" 42 | 43 | @db << "create table commit_branches (commit_id integer, branch_id integer)" 44 | @db << "create table commit_nodes (commit_id integer, node_id integer, node_sha string)" 45 | end 46 | 47 | end 48 | end 49 | 50 | rescue LoadError 51 | # no commit db 52 | end 53 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/parser/feature.tt: -------------------------------------------------------------------------------- 1 | grammar Feature 2 | rule document 3 | feature 4 | end 5 | 6 | rule feature 7 | comments? 8 | white? 9 | tags_line? 10 | feature_info 11 | end 12 | 13 | rule feature_info 14 | feature_header 15 | feature_narration? 16 | end 17 | 18 | rule feature_header 19 | space* 'Feature:' [^\n]+ eol { 20 | def title 21 | text_value.gsub(/(^.*Feature:\s*|\n)/, '') 22 | end 23 | } 24 | end 25 | 26 | rule feature_narration 27 | non_empty_line* 28 | end 29 | 30 | rule tags_line 31 | space* '@' [^\n]+ eol { 32 | def tags 33 | text_value.scan(/@[^\s\n]+/) 34 | end 35 | } 36 | end 37 | 38 | rule comments 39 | (comment_line)* { 40 | def list 41 | elements.collect {|element| element.text_value } 42 | end 43 | } 44 | end 45 | 46 | rule comment_line 47 | space* '#' [^\n]+ eol 48 | end 49 | 50 | rule white 51 | (space / eol)* 52 | end 53 | 54 | rule non_empty_line 55 | [\s]* [A-Za-z0-9] [^\n]+ eol 56 | end 57 | 58 | rule eol 59 | "\n" 60 | end 61 | 62 | rule space 63 | ' ' 64 | end 65 | 66 | end 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | #require 'rubygems' 81 | #require 'treetop' 82 | #require 'polyglot' 83 | #require 'tmp/comment' 84 | # 85 | # 86 | #p = CommentParser.new() 87 | #p.consume_all_input = false 88 | # 89 | #text = < 2 | <% form_for 'watircuke_test', :url => { :controller => 'watircuke', :action => 'runme' }, :html=>{ :id => 'watircuke_test', :target => "_blank" }do |f| -%> 3 | Select Browser: 4 | <%= f.select :browser_name, options_for_select(Watircuke.browsers) %> 5 | <%= hidden_field_tag :test_name, @feature.relative_path %> 6 | <%= button_to_function "Run", "runtest();" %> 7 | <% end -%> 8 | 9 | 14 | 15 | 58 | 59 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") 3 | require 'test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Transactional fixtures accelerate your tests by wrapping each test method 7 | # in a transaction that's rolled back on completion. This ensures that the 8 | # test database remains unchanged so your fixtures don't have to be reloaded 9 | # between every test method. Fewer database queries means faster tests. 10 | # 11 | # Read Mike Clark's excellent walkthrough at 12 | # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting 13 | # 14 | # Every Active Record database supports transactions except MyISAM tables 15 | # in MySQL. Turn off transactional fixtures in this case; however, if you 16 | # don't care one way or the other, switching from MyISAM to InnoDB tables 17 | # is recommended. 18 | # 19 | # The only drawback to using transactional fixtures is when you actually 20 | # need to test transactions. Since your test is bracketed by a transaction, 21 | # any transactions started in your code will be automatically rolled back. 22 | self.use_transactional_fixtures = true 23 | 24 | # Instantiated fixtures are slow, but give you @david where otherwise you 25 | # would need people(:david). If you don't want to migrate your existing 26 | # test cases which use the @david style and don't mind the speed hit (each 27 | # instantiated fixtures translates to a database query per test method), 28 | # then set this back to true. 29 | self.use_instantiated_fixtures = false 30 | 31 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 32 | # 33 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 34 | # -- they do not yet inherit this setting 35 | fixtures :all 36 | 37 | # Add more helper methods to be used by all tests here... 38 | end 39 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit.rb: -------------------------------------------------------------------------------- 1 | $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed 2 | 3 | # core 4 | require 'fileutils' 5 | require 'time' 6 | 7 | # stdlib 8 | require 'timeout' 9 | require 'logger' 10 | require 'digest/sha1' 11 | 12 | 13 | if defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby' 14 | require 'open3' 15 | elsif RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/ 16 | require 'win32/open3' 17 | else 18 | require 'open3_detach' 19 | end 20 | 21 | # third party 22 | require 'rubygems' 23 | begin 24 | gem "mime-types", ">=0" 25 | require 'mime/types' 26 | rescue Gem::LoadError => e 27 | puts "WARNING: Gem LoadError: #{e.message}" 28 | end 29 | 30 | # ruby 1.9 compatibility 31 | require 'grit/ruby1.9' 32 | 33 | # internal requires 34 | require 'grit/lazy' 35 | require 'grit/errors' 36 | require 'grit/git-ruby' 37 | require 'grit/git' unless defined? Grit::Git 38 | require 'grit/ref' 39 | require 'grit/tag' 40 | require 'grit/commit' 41 | require 'grit/commit_stats' 42 | require 'grit/tree' 43 | require 'grit/blob' 44 | require 'grit/actor' 45 | require 'grit/diff' 46 | require 'grit/config' 47 | require 'grit/repo' 48 | require 'grit/index' 49 | require 'grit/status' 50 | require 'grit/submodule' 51 | require 'grit/blame' 52 | require 'grit/merge' 53 | 54 | 55 | module Grit 56 | class << self 57 | # Set +debug+ to true to log all git calls and responses 58 | attr_accessor :debug 59 | attr_accessor :use_git_ruby 60 | # The standard +logger+ for debugging git calls - this defaults to a plain STDOUT logger 61 | attr_accessor :logger 62 | def log(str) 63 | logger.debug { str } 64 | end 65 | end 66 | self.debug = false 67 | self.use_git_ruby = true 68 | 69 | @logger ||= ::Logger.new(STDOUT) 70 | 71 | def self.version 72 | yml = YAML.load(File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION.yml]))) 73 | "#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}" 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/features/statistic.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Actions

5 |
6 |

Showing: <%= @statistic.cfm.config.tags %>

7 |
8 |
9 |
10 | 11 | <% [:overal, :iteration, :bucket, :developer, :something_todo, :component, :various, :status].each do |type| %> 12 | <%= raw statistic_table(type, @statistic) %> 13 | <% end %> 14 | 15 |
16 | 17 |
18 | 19 | <% form_tag '', :method => :get do %> 20 | 21 |

Scope by

22 | 23 |
24 | 25 |
26 | <%= hidden_field_tag 'config[cvs_commit]', @cfm.config.cvs_commit %> 27 | <%= hidden_field_tag 'config[cvs_push]', @cfm.config.cvs_push %> 28 | <%= hidden_field_tag 'config[aggregate][]', @cfm.config.aggregate.first %> 29 | <%= hidden_field_tag 'config[aggregate][]', @cfm.config.aggregate.last %> 30 |
    31 |
  1. 32 | <%= label_tag 'config[dir]', "Directory:" %> 33 | <%= select_tag 'config[dir]', options_for_select(list_of_dirs, :selected => @cfm.config.dir) %> 34 |
  2. 35 |
  3. 36 | <%= label_tag 'config[tags]', "Tags:" %> 37 | <%= text_field_tag 'config[tags]', @cfm.config.tags %> 38 |
  4. 39 |
  5. 40 |
    41 | <%= submit_tag "Filter" %> 42 |
    43 |
  6. 44 |
45 |
46 | 47 |
48 | 49 | <% end %> 50 |
51 | 52 |
53 | 54 | 55 |
56 |
57 | 58 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_feature_manager_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe CucumberFeatureManager do 4 | context "files scaning" do 5 | before(:all) do 6 | @cfm = CucumberFeatureManager.new("spec/data/feature_manager") 7 | end 8 | it "should store path for features" do 9 | @cfm.prefix.should == 'spec/data/feature_manager' 10 | end 11 | it "should scan files in specific directory" do 12 | @cfm.should have(5).features 13 | end 14 | it "should return list of all scenarios" do 15 | @cfm.should have(5).scenarios 16 | end 17 | it "should compute correct total estimation value" do 18 | @cfm.estimation.should == 15.25 19 | end 20 | end 21 | 22 | context "features filtering by one tag" do 23 | before(:all) do 24 | @cfm = CucumberFeatureManager.new("spec/data/feature_manager", "spec/data", {'tags' => '@m1'}) 25 | end 26 | it "should scan files that have one tag" do 27 | @cfm.should have(3).features 28 | end 29 | it "should return list of all scenarios that have this tag" do 30 | @cfm.should have(4).scenarios 31 | end 32 | end 33 | 34 | 35 | context "features filtering by one multiple tags" do 36 | before(:all) do 37 | @cfm = CucumberFeatureManager.new("spec/data/feature_manager", "spec/data", {'tags' => '@m1 @mc'}) 38 | end 39 | it "should scan files that have every one tag" do 40 | @cfm.should have(1).features 41 | end 42 | it "should return list of all scenarios that have both tag" do 43 | @cfm.should have(1).scenarios 44 | end 45 | end 46 | 47 | context "dir scoping" do 48 | before(:all) do 49 | @cfm = CucumberFeatureManager.new("spec/data/feature_manager", "spec/data", {'dir' => 'subdir'}) 50 | end 51 | it "should scan files in specific directory" do 52 | @cfm.should have(3).features 53 | end 54 | it "should return list of all scenarios" do 55 | @cfm.should have(1).scenarios 56 | end 57 | end 58 | 59 | end -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | ActionController::Routing::Routes.draw do |map| 2 | # The priority is based upon order of creation: first created -> highest priority. 3 | 4 | # Sample of regular route: 5 | # map.connect 'products/:id', :controller => 'catalog', :action => 'view' 6 | # Keep in mind you can assign values other than :controller and :action 7 | 8 | # Sample of named route: 9 | # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase' 10 | # This route can be invoked with purchase_url(:id => product.id) 11 | 12 | # Sample resource route (maps HTTP verbs to controller actions automatically): 13 | # map.resources :products 14 | 15 | # Sample resource route with options: 16 | # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get } 17 | 18 | # Sample resource route with sub-resources: 19 | # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller 20 | 21 | # Sample resource route with more complex sub-resources 22 | # map.resources :products do |products| 23 | # products.resources :comments 24 | # products.resources :sales, :collection => { :recent => :get } 25 | # end 26 | 27 | # Sample resource route within a namespace: 28 | # map.namespace :admin do |admin| 29 | # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) 30 | # admin.resources :products 31 | # end 32 | 33 | # You can have the root of your site routed with map.root -- just remember to delete public/index.html. 34 | # map.root :controller => "welcome" 35 | 36 | # See how all your routes lay out with "rake routes" 37 | 38 | # Install the default routes as the lowest priority. 39 | # Note: These default routes make all actions in every controller accessible via GET requests. You should 40 | # consider removing or commenting them out if you're using named routes and resources. 41 | map.connect ':controller/:action/:id' 42 | map.connect ':controller/:action/:id.:format' 43 | end 44 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/ref.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Ref 4 | 5 | class << self 6 | 7 | # Find all Refs 8 | # +repo+ is the Repo 9 | # +options+ is a Hash of options 10 | # 11 | # Returns Grit::Ref[] (baked) 12 | def find_all(repo, options = {}) 13 | refs = repo.git.refs(options, prefix) 14 | refs.split("\n").map do |ref| 15 | name, id = *ref.split(' ') 16 | commit = Commit.create(repo, :id => id) 17 | self.new(name, commit) 18 | end 19 | end 20 | 21 | protected 22 | 23 | def prefix 24 | "refs/#{name.to_s.gsub(/^.*::/, '').downcase}s" 25 | end 26 | 27 | end 28 | 29 | attr_reader :name 30 | attr_reader :commit 31 | 32 | # Instantiate a new Head 33 | # +name+ is the name of the head 34 | # +commit+ is the Commit that the head points to 35 | # 36 | # Returns Grit::Head (baked) 37 | def initialize(name, commit) 38 | @name = name 39 | @commit = commit 40 | end 41 | 42 | # Pretty object inspection 43 | def inspect 44 | %Q{#<#{self.class.name} "#{@name}">} 45 | end 46 | end # Ref 47 | 48 | # A Head is a named reference to a Commit. Every Head instance contains a name 49 | # and a Commit object. 50 | # 51 | # r = Grit::Repo.new("/path/to/repo") 52 | # h = r.heads.first 53 | # h.name # => "master" 54 | # h.commit # => # 55 | # h.commit.id # => "1c09f116cbc2cb4100fb6935bb162daa4723f455" 56 | class Head < Ref 57 | 58 | # Get the HEAD revision of the repo. 59 | # +repo+ is the Repo 60 | # +options+ is a Hash of options 61 | # 62 | # Returns Grit::Head (baked) 63 | def self.current(repo, options = {}) 64 | head = repo.git.fs_read('HEAD').chomp 65 | if /ref: refs\/heads\/(.*)/.match(head) 66 | self.new($1, repo.git.rev_parse(options, 'HEAD')) 67 | end 68 | end 69 | 70 | end # Head 71 | 72 | class Remote < Ref; end 73 | 74 | end # Grit 75 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file 2 | 3 | # Specifies gem version of Rails to use when vendor/rails is not present 4 | RAILS_GEM_VERSION = '2.3.14' unless defined? RAILS_GEM_VERSION 5 | 6 | # Bootstrap the Rails environment, frameworks, and default configuration 7 | require File.join(File.dirname(__FILE__), 'boot') 8 | 9 | Rails::Initializer.run do |config| 10 | # Settings in config/environments/* take precedence over those specified here. 11 | # Application configuration should go into files in config/initializers 12 | # -- all .rb files in that directory are automatically loaded. 13 | 14 | # Add additional load paths for your own custom dirs 15 | # config.load_paths += %W( #{RAILS_ROOT}/extras ) 16 | 17 | # Specify gems that this application depends on and have them installed with rake gems:install 18 | # config.gem "bj" 19 | # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" 20 | # config.gem "sqlite3-ruby", :lib => "sqlite3" 21 | # config.gem "aws-s3", :lib => "aws/s3" 22 | 23 | # Only load the plugins named here, in the order given (default is alphabetical). 24 | # :all can be used as a placeholder for all plugins not explicitly named 25 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 26 | 27 | # Skip frameworks you're not going to use. To use Rails without a database, 28 | # you must remove the Active Record framework. 29 | # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] 30 | 31 | # Activate observers that should always be running 32 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 33 | 34 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 35 | # Run "rake -D time" for a list of tasks for finding time zone names. 36 | config.time_zone = 'UTC' 37 | 38 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 39 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] 40 | # config.i18n.default_locale = :de 41 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/aggregator.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | class Aggregator 3 | def initialize(cfm, aggregator, multiple = false) 4 | if multiple 5 | @collection = Collection.nested_hash(0) 6 | multiple.each do |tag| 7 | cfm.scenarios.each do |scenario| 8 | @collection[tag].push scenario if scenario.tags.include?(tag) 9 | end 10 | end 11 | else 12 | @collection = Collection.nested_hash(aggregator.size) 13 | if aggregator.size == 2 14 | cfm.scenarios.each do |scenario| 15 | @collection[label(aggregator.first, scenario.tags_without_technical)][label(aggregator.last, scenario.tags_without_technical)][scenario.feature].push scenario 16 | end 17 | else 18 | @collection = Collection.nested_hash(1) 19 | cfm.scenarios.each do |scenario| 20 | @collection[label(aggregator.first, scenario.tags_without_technical)][scenario.feature].push scenario 21 | end 22 | end 23 | end 24 | end 25 | 26 | def collection 27 | @collection 28 | end 29 | 30 | private 31 | 32 | def label(aggregate, tags) 33 | tags.find { |tag| tag =~ aggregate } || '_undefined_' 34 | end 35 | 36 | class Collection < Hash 37 | 38 | include CucumberFM::FeatureElement::Component::TotalEstimation 39 | 40 | def features 41 | keys.collect { |key| 42 | self[key].is_a?(Array) ? key : self[key].features 43 | }.flatten.uniq 44 | end 45 | 46 | def scenarios 47 | values.collect { |value| 48 | value.is_a?(Array) ? value : value.scenarios 49 | }.flatten 50 | end 51 | 52 | def Collection.nested_hash (level=1) 53 | new do |hash, key| 54 | hash[key]= (level > 0 ? nested_hash(level-1) : ScenarioCollection.new) 55 | end 56 | end 57 | end 58 | class ScenarioCollection < Array 59 | 60 | include CucumberFM::FeatureElement::Component::TotalEstimation 61 | 62 | alias_method :scenarios, :entries 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/layouts/cucumber_fm.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Fork me on GitHub 16 |
17 | 26 | <%= content_tag('div', flash[:error], :class => 'error') if flash[:error] %> 27 | <%= content_tag('div', flash[:notice], :class => 'notice') if flash[:notice] %> 28 |
29 | <%= yield %> 30 |
31 | 34 |
35 | 36 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/watircuke/results.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 |
6 |

Results: <%#= @statistic.cfm.config.tags %>

7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <% if @result.empty? %> 18 | 19 | 20 | 21 | <% else %> 22 | <% @result.each do |result| %> 23 | <% result_name = result.gsub("public/test_results/", "")%> 24 | 25 | 26 | 27 | 28 | <% end %> 29 | <% end %> 30 | 31 |
Test result Action
No results
<%= link_to "#{result_name}", {:controller => 'watircuke', :action => "show_result", :id => result }, :target => "_blank" %> <%= link_to "Delete", {:controller => 'watircuke', :action => 'delete', :id => result}, :confirm => "Do you really want to remove this result?" %>
32 |
33 | 34 |
35 | 36 | <% form_tag '', :method => :get do %> 37 | 38 |

 

39 | 40 |
41 | 42 |
43 |
    44 |
  1. 45 |
  2. 46 |
  3. 47 |
  4. 48 |
  5. 49 |
    50 |
    51 |
  6. 52 |
53 | 54 |
55 |
56 | 57 | <% end %> 58 |
59 | 60 |
61 | 62 | 63 |
64 |
65 | 66 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/controllers/documentation/watircuke_controller.rb: -------------------------------------------------------------------------------- 1 | class Documentation::WatircukeController < Documentation::ApplicationController 2 | 3 | layout '/documentation/layouts/mini' 4 | 5 | def runme 6 | @@testname = params[:test_name].split(".")[0] 7 | browser = params[:watircuke_test][:browser_name].chomp 8 | runme_params = "ruby #{Dir.pwd}/watircuke.rb features/#{params[:test_name].downcase} #{@@testname} #{browser} web" 9 | Watircuke.start_process(runme_params) 10 | end 11 | 12 | def checkme 13 | pid = Watircuke.find_process 14 | if Watircuke.is_windows? && pid 15 | render :nothing => true 16 | elsif !Watircuke.is_windows? && pid.length > 2 17 | render :nothing => true 18 | else 19 | render :file => "#{Watircuke.find_test_folder}/#{@@testname}.html" 20 | end 21 | end 22 | 23 | def stopme 24 | begin 25 | Watircuke.find_process.each do |pr| 26 | Process::kill 9, pr.chomp.to_i 27 | end 28 | rescue Exception => e 29 | end 30 | redirect_to :back 31 | end 32 | 33 | def results 34 | @highlight = 'results' 35 | @result = list_results 36 | render :layout => '/documentation/layouts/cucumber_fm' 37 | end 38 | 39 | 40 | def show_result 41 | path = params[:id] 42 | f = find_file_result_in_folder(Rails.root.join(path)) 43 | if f.empty? 44 | redirect_to :action => "results" 45 | flash[:notice] = "Could not show results...no html file found" 46 | else 47 | render :file => f.to_s 48 | end 49 | end 50 | 51 | def delete 52 | path = params[:id] 53 | remove_folder(path) 54 | flash[:notice]= "Folder was removed" 55 | redirect_to :action => "results" 56 | end 57 | 58 | private 59 | 60 | def list_results 61 | Dir.glob("public/test_results/*") 62 | end 63 | 64 | def find_file_result_in_folder(folder) 65 | Dir.glob("#{folder}/*.html") 66 | end 67 | 68 | def remove_folder(folder) 69 | FileUtils.remove_dir("#{Dir.pwd}/#{folder}") 70 | end 71 | 72 | end 73 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/resources/whitetheme/theme.less: -------------------------------------------------------------------------------- 1 | /* ***** BEGIN LICENSE BLOCK ***** 2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 | * 4 | * The contents of this file are subject to the Mozilla Public License Version 5 | * 1.1 (the "License"); you may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * http://www.mozilla.org/MPL/ 8 | * 9 | * Software distributed under the License is distributed on an "AS IS" basis, 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 | * for the specific language governing rights and limitations under the 12 | * License. 13 | * 14 | * The Original Code is Bespin. 15 | * 16 | * The Initial Developer of the Original Code is 17 | * Mozilla. 18 | * Portions created by the Initial Developer are Copyright (C) 2009 19 | * the Initial Developer. All Rights Reserved. 20 | * 21 | * Contributor(s): 22 | * Bespin Team (bespin@mozilla.com) 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * either the GNU General Public License Version 2 or later (the "GPL"), or 26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 27 | * in which case the provisions of the GPL or the LGPL are applicable instead 28 | * of those above. If you wish to allow use of your version of this file only 29 | * under the terms of either the GPL or the LGPL, and not to allow others to 30 | * use your version of this file under the terms of the MPL, indicate your 31 | * decision by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL or the LGPL. If you do not delete 33 | * the provisions above, a recipient may use your version of this file under 34 | * the terms of any one of the MPL, the GPL or the LGPL. 35 | * 36 | * ***** END LICENSE BLOCK ***** */ 37 | 38 | .bespin .cmd_typed { 39 | background: transparent -webkit-gradient( 40 | linear, 41 | left top, 42 | left bottom, 43 | color-stop(0.07, rgb(235,235,235)), 44 | color-stop(1, rgb(209,209,209)) 45 | ); 46 | background: transparent -moz-linear-gradient( 47 | center top, 48 | rgb(235,235,235) 7%, 49 | rgb(209,209,209) 100% 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/diff.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Diff 4 | attr_reader :a_path, :b_path 5 | attr_reader :a_blob, :b_blob 6 | attr_reader :a_mode, :b_mode 7 | attr_reader :new_file, :deleted_file 8 | attr_reader :diff 9 | 10 | def initialize(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff) 11 | @repo = repo 12 | @a_path = a_path 13 | @b_path = b_path 14 | @a_blob = a_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => a_blob) 15 | @b_blob = b_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => b_blob) 16 | @a_mode = a_mode 17 | @b_mode = b_mode 18 | @new_file = new_file || @a_blob.nil? 19 | @deleted_file = deleted_file || @b_blob.nil? 20 | @diff = diff 21 | end 22 | 23 | def self.list_from_string(repo, text) 24 | lines = text.split("\n") 25 | 26 | diffs = [] 27 | 28 | while !lines.empty? 29 | m, a_path, b_path = *lines.shift.match(%r{^diff --git a/(.+?) b/(.+)$}) 30 | 31 | if lines.first =~ /^old mode/ 32 | m, a_mode = *lines.shift.match(/^old mode (\d+)/) 33 | m, b_mode = *lines.shift.match(/^new mode (\d+)/) 34 | end 35 | 36 | if lines.empty? || lines.first =~ /^diff --git/ 37 | diffs << Diff.new(repo, a_path, b_path, nil, nil, a_mode, b_mode, false, false, nil) 38 | next 39 | end 40 | 41 | new_file = false 42 | deleted_file = false 43 | 44 | if lines.first =~ /^new file/ 45 | m, b_mode = lines.shift.match(/^new file mode (.+)$/) 46 | a_mode = nil 47 | new_file = true 48 | elsif lines.first =~ /^deleted file/ 49 | m, a_mode = lines.shift.match(/^deleted file mode (.+)$/) 50 | b_mode = nil 51 | deleted_file = true 52 | end 53 | 54 | m, a_blob, b_blob, b_mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$}) 55 | b_mode.strip! if b_mode 56 | 57 | diff_lines = [] 58 | while lines.first && lines.first !~ /^diff/ 59 | diff_lines << lines.shift 60 | end 61 | diff = diff_lines.join("\n") 62 | 63 | diffs << Diff.new(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff) 64 | end 65 | 66 | diffs 67 | end 68 | end # Diff 69 | 70 | end # Grit 71 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | actionmailer (2.3.14) 5 | actionpack (= 2.3.14) 6 | actionpack (2.3.14) 7 | activesupport (= 2.3.14) 8 | rack (~> 1.1.0) 9 | activerecord (2.3.14) 10 | activesupport (= 2.3.14) 11 | activeresource (2.3.14) 12 | activesupport (= 2.3.14) 13 | activesupport (2.3.14) 14 | addressable (2.2.8) 15 | builder (3.0.0) 16 | childprocess (0.3.2) 17 | ffi (~> 1.0.6) 18 | chronic (0.6.7) 19 | colorize (0.5.8) 20 | columnize (0.3.6) 21 | cucumber (1.2.0) 22 | builder (>= 2.1.2) 23 | diff-lcs (>= 1.1.3) 24 | gherkin (~> 2.10.0) 25 | json (>= 1.4.6) 26 | diff-lcs (1.1.3) 27 | ffi (1.0.11) 28 | gherkin (2.10.0) 29 | json (>= 1.4.6) 30 | headless (0.3.1) 31 | httparty (0.8.3) 32 | multi_json (~> 1.0) 33 | multi_xml 34 | json (1.7.3) 35 | libwebsocket (0.1.3) 36 | addressable 37 | linecache (0.46) 38 | rbx-require-relative (> 0.0.4) 39 | mime-types (1.18) 40 | multi_json (1.3.6) 41 | multi_xml (0.5.1) 42 | nokogiri (1.5.2) 43 | rack (1.1.3) 44 | rails (2.3.14) 45 | actionmailer (= 2.3.14) 46 | actionpack (= 2.3.14) 47 | activerecord (= 2.3.14) 48 | activeresource (= 2.3.14) 49 | activesupport (= 2.3.14) 50 | rake (>= 0.8.3) 51 | rake (0.9.2.2) 52 | rbx-require-relative (0.0.9) 53 | rspec (2.10.0) 54 | rspec-core (~> 2.10.0) 55 | rspec-expectations (~> 2.10.0) 56 | rspec-mocks (~> 2.10.0) 57 | rspec-core (2.10.1) 58 | rspec-expectations (2.10.0) 59 | diff-lcs (~> 1.1.3) 60 | rspec-mocks (2.10.1) 61 | ruby-debug (0.10.4) 62 | columnize (>= 0.1) 63 | ruby-debug-base (~> 0.10.4.0) 64 | ruby-debug-base (0.10.4) 65 | linecache (>= 0.3) 66 | rubyzip (0.9.8) 67 | selenium-webdriver (2.22.0) 68 | childprocess (>= 0.2.5) 69 | ffi (~> 1.0) 70 | libwebsocket (~> 0.1.3) 71 | multi_json (~> 1.0) 72 | rubyzip 73 | sqlite3 (1.3.6) 74 | syntax (1.0.0) 75 | sys-proctable (0.9.1) 76 | watir-webdriver (0.6.1) 77 | selenium-webdriver (>= 2.18.0) 78 | 79 | PLATFORMS 80 | ruby 81 | 82 | DEPENDENCIES 83 | chronic 84 | colorize 85 | cucumber 86 | headless 87 | httparty 88 | mime-types 89 | nokogiri 90 | rails (= 2.3.14) 91 | rspec 92 | ruby-debug 93 | sqlite3 94 | syntax 95 | sys-proctable 96 | watir-webdriver 97 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/submodule.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Submodule 4 | attr_reader :id 5 | attr_reader :mode 6 | attr_reader :name 7 | 8 | # Create a Submodule containing just the specified attributes 9 | # +repo+ is the Repo 10 | # +atts+ is a Hash of instance variable data 11 | # 12 | # Returns Grit::Submodule (unbaked) 13 | def self.create(repo, atts) 14 | self.allocate.create_initialize(repo, atts) 15 | end 16 | 17 | # Initializer for Submodule.create 18 | # +repo+ is the Repo 19 | # +atts+ is a Hash of instance variable data 20 | # 21 | # Returns Grit::Submodule 22 | def create_initialize(repo, atts) 23 | @repo = repo 24 | atts.each do |k, v| 25 | instance_variable_set("@#{k}".to_sym, v) 26 | end 27 | self 28 | end 29 | 30 | # The url of this submodule 31 | # +ref+ is the committish that should be used to look up the url 32 | # 33 | # Returns String 34 | def url(ref) 35 | config = self.class.config(@repo, ref) 36 | 37 | lookup = config.keys.inject({}) do |acc, key| 38 | id = config[key]['id'] 39 | acc[id] = config[key]['url'] 40 | acc 41 | end 42 | 43 | lookup[@id] 44 | end 45 | 46 | # The configuration information for the given +repo+ 47 | # +repo+ is the Repo 48 | # +ref+ is the committish (defaults to 'master') 49 | # 50 | # Returns a Hash of { => { 'url' => , 'id' => } } 51 | # Returns {} if no .gitmodules file was found 52 | def self.config(repo, ref = "master") 53 | commit = repo.commit(ref) 54 | blob = commit.tree/'.gitmodules' 55 | return {} unless blob 56 | 57 | lines = blob.data.gsub(/\r\n?/, "\n" ).split("\n") 58 | 59 | config = {} 60 | current = nil 61 | 62 | lines.each do |line| 63 | if line =~ /^\[submodule "(.+)"\]$/ 64 | current = $1 65 | config[current] = {} 66 | config[current]['id'] = (commit.tree/current).id 67 | elsif line =~ /^\t(\w+) = (.+)$/ 68 | config[current][$1] = $2 69 | config[current]['id'] = (commit.tree/$2).id if $1 == 'path' 70 | else 71 | # ignore 72 | end 73 | end 74 | 75 | config 76 | end 77 | 78 | def basename 79 | File.basename(name) 80 | end 81 | 82 | # Pretty object inspection 83 | def inspect 84 | %Q{#} 85 | end 86 | end # Submodule 87 | 88 | end # Grit -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/tag_filter.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | class TagFilter < Struct.new(:expression) 3 | 4 | TAG_PATTERN = CucumberFM::FeatureElement::Component::Tags::TAG_PATTERN 5 | AND_PATTERN = /\s+/ 6 | OR_PATTERN = /\s?,\s?/ 7 | NOT_PATTERN = /~/ 8 | 9 | TOKEN = Regexp.union(TAG_PATTERN, 10 | OR_PATTERN, 11 | AND_PATTERN, 12 | NOT_PATTERN) 13 | 14 | def pass?(tags) 15 | if expression.nil? or expression.empty? 16 | true 17 | else 18 | evaluate_expression(tags) 19 | end 20 | end 21 | 22 | private 23 | 24 | 25 | # TODO - refactoring 26 | 27 | def evaluate_expression(tags) 28 | buffer = nil 29 | buffer_array = [] 30 | buffer_negation = nil 31 | 32 | text = expression.gsub(/\s+/, ' ') 33 | while token = text.match(TOKEN) 34 | case token[0] 35 | when TAG_PATTERN 36 | throw "Error at #{expression} | token: #{token[0]} | last token: #{buffer}" unless buffer.nil? 37 | buffer = token[0] 38 | when NOT_PATTERN 39 | buffer_negation = true 40 | when OR_PATTERN 41 | buffer_array.push buffer 42 | buffer = nil 43 | when AND_PATTERN 44 | if buffer_array.empty? and buffer 45 | return(false) unless (!buffer_negation == tags.include?(buffer)) 46 | buffer = nil 47 | buffer_negation = nil 48 | true 49 | elsif !buffer_array.empty? 50 | if buffer 51 | buffer_array.push(buffer) 52 | buffer = nil 53 | end 54 | return(false) unless (!buffer_negation == buffer_array.any? { |tag| tags.include? tag }) 55 | buffer_array = [] 56 | buffer_negation = nil 57 | true 58 | else 59 | true 60 | end 61 | end 62 | 63 | text = token.post_match 64 | end 65 | 66 | if buffer_array.empty? and buffer 67 | return(false) unless (!buffer_negation == tags.include?(buffer)) 68 | buffer = nil 69 | buffer_negation = nil 70 | true 71 | elsif !buffer_array.empty? 72 | if buffer 73 | buffer_array.push(buffer) 74 | buffer = nil 75 | end 76 | return(false) unless (!buffer_negation == buffer_array.any? { |tag| tags.include? tag }) 77 | buffer_array = [] 78 | buffer_negation = nil 79 | true 80 | else 81 | true 82 | end 83 | end 84 | end 85 | end -------------------------------------------------------------------------------- /-f: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'colorize' 3 | require 'fileutils' 4 | require 'ruby-debug' 5 | require 'chronic' 6 | require 'rspec' 7 | require 'nokogiri' 8 | require 'open-uri' 9 | require 'openssl' 10 | require 'active_support/inflector' 11 | require 'test/unit/assertions' 12 | require 'features/support/read_config' 13 | require 'features/support/create_screenshot_folder' 14 | require 'features/support/screenshot' 15 | require 'features/support/check_missing_translations' 16 | require 'cucumber/formatter/unicode' 17 | require 'features/support/select_browser' 18 | require 'vendor/plugins/cucumber_fm/app/models/watircuke' 19 | include Test::Unit::Assertions 20 | OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 21 | 22 | begin 23 | #read the config.yml file found in config/config.yml 24 | ##-------------------------------------------------- 25 | read_config 26 | BROWSER = ENV['BROWSER'].nil? ? 27 | (Watircuke.is_windows? ? select_browser("ie") : select_browser("firefox")) : 28 | select_browser(ENV['BROWSER']) 29 | 30 | CHECK_TRANSLATIONS = @check_translation 31 | TRANSLATION_TAG = @translation_tag 32 | 33 | LANGUAGES = @fixtures if ENV['DEF_TEST'] 34 | 35 | ##------------------------------------------------- 36 | 37 | folder_prefix = "public/test_results" 38 | 39 | if Dir["#{folder_prefix}/*"].select{|x| File.directory?(x)}.map{|x| [File.ctime(x), x]}.sort_by{|x| x.first}.last 40 | screenshot_path = (Dir["#{folder_prefix}/*"].select{|x| File.directory?(x)}.map{|x| [File.ctime(x), x]}.sort_by{|x| x.first}.last.last.inspect + "/screenshots/").gsub!("\"","") 41 | else 42 | screenshot_path = "#{folder_prefix}/screenshots/" 43 | end 44 | 45 | browser = BROWSER 46 | # "before all" 47 | Before do 48 | @table = {} 49 | @screenshot_path = screenshot_path 50 | @browser = browser 51 | LANGUAGES.each { |table| @table.merge! YAML.load_file("features/fixtures/#{table}.yml") } if ENV['DEF_TEST'] 52 | @table.merge! YAML.load_file("config/config.yml") 53 | @environment = "http://" 54 | @time = Time.now 55 | end 56 | 57 | #after each scenario: checking for missing translation on page, count scenario time, makes screenshot if failed 58 | After do |scenario| 59 | check_missing_translations if CHECK_TRANSLATIONS 60 | create_screenshot(ENV['DEF_TEST'] || ENV['CMD']) if scenario.failed? 61 | scenario_time(@time) 62 | end 63 | 64 | # after each step which is called '@new_feature' make a screenshot 65 | AfterStep('@new_feature') do 66 | create_screenshot(ENV['DEF_TEST'] || ENV['CMD']) 67 | end 68 | 69 | at_exit do 70 | browser.close 71 | end 72 | 73 | rescue Exception => ex 74 | puts "#{ex}".red 75 | end 76 | 77 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'colorize' 3 | require 'fileutils' 4 | require 'ruby-debug' 5 | require 'chronic' 6 | require 'rspec' 7 | require 'nokogiri' 8 | require 'open-uri' 9 | require 'openssl' 10 | require 'active_support/inflector' 11 | require 'test/unit/assertions' 12 | require 'features/support/read_config' 13 | require 'features/support/create_screenshot_folder' 14 | require 'features/support/check_missing_translations' 15 | require 'cucumber/formatter/unicode' 16 | require 'features/support/select_browser' 17 | require 'vendor/plugins/cucumber_fm/app/models/watircuke' 18 | include Test::Unit::Assertions 19 | OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 20 | 21 | begin 22 | #read the config.yml file found in config/config.yml 23 | ##-------------------------------------------------- 24 | read_config 25 | BROWSER = ENV['BROWSER'].nil? ? 26 | (Watircuke.is_windows? ? select_browser("ie") : select_browser("firefox")) : 27 | select_browser(ENV['BROWSER']) 28 | 29 | CHECK_TRANSLATIONS = @check_translation 30 | TRANSLATION_TAG = @translation_tag 31 | 32 | LANGUAGES = @fixtures if ENV['DEF_TEST'] 33 | 34 | ##------------------------------------------------- 35 | 36 | folder_prefix = "public/test_results" 37 | 38 | if Dir["#{folder_prefix}/*"].select{|x| File.directory?(x)}.map{|x| [File.ctime(x), x]}.sort_by{|x| x.first}.last 39 | screenshot_path = (Dir["#{folder_prefix}/*"].select{|x| File.directory?(x)}.map{|x| [File.ctime(x), x]}.sort_by{|x| x.first}.last.last.inspect + "/screenshots/").gsub!("\"","") 40 | else 41 | screenshot_path = "#{folder_prefix}/screenshots/" 42 | end 43 | 44 | browser = BROWSER 45 | # "before all" 46 | Before do 47 | @table = {} 48 | @screenshot_path = screenshot_path 49 | @browser = browser 50 | LANGUAGES.each { |table| @table.merge! YAML.load_file("features/fixtures/#{table}.yml") } if ENV['DEF_TEST'] 51 | @table.merge! YAML.load_file("config/config.yml") 52 | @environment = "http://" 53 | @time = Time.now 54 | end 55 | 56 | #after each scenario: checking for missing translation on page, count scenario time, makes screenshot if failed 57 | After do |scenario| 58 | @scenario_id = scenario.raw_steps.first.dom_id 59 | check_missing_translations if CHECK_TRANSLATIONS 60 | create_screenshot(ENV['DEF_TEST'] || ENV['CMD']) if scenario.failed? 61 | scenario_time(@time) 62 | end 63 | 64 | # after each step which is called '@new_feature' make a screenshot 65 | AfterStep('@new_feature') do 66 | create_screenshot(ENV['DEF_TEST'] || ENV['CMD']) 67 | end 68 | 69 | at_exit do 70 | browser.close 71 | end 72 | 73 | rescue Exception => ex 74 | puts "#{ex}".red 75 | end 76 | 77 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature_element/component/tags.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | module FeatureElement 3 | module Component 4 | module Tags 5 | LINE_PATTERN = /^\s*@\S.*$/ 6 | TAG_PATTERN = /@[^,\s]+/ 7 | 8 | PATTERN = { 9 | :component => /@[a-z]\S{3,}\z/, 10 | :milestone => /@m\d.?\z/, 11 | :iteration => /@i\d+\z/, 12 | :priority => /@p\d+\z/, 13 | :status => /@_[a-z]\S+\z/, 14 | :developer => /@[a-z]{2,3}\z/, 15 | :bucket => /@__[^\s\d]+/, 16 | :effort => /@\d/, 17 | :benefit => /@_\d/, 18 | :something_todo => /@:::[a-z]{2,3}\z/, 19 | :role => /@\$_[a-z_]+/ 20 | } 21 | 22 | TECHNICAL = [ 23 | '@javascript', 24 | '@selenium', 25 | '@sellenium', 26 | '@celerity', 27 | '@culerity', 28 | '@mongo', 29 | '@allow-rescue', 30 | '@needs_wireframe', 31 | '@tested_elsewhere', 32 | '@added', 33 | '@nontestable', 34 | '@additional-test' 35 | ] 36 | 37 | STATUS_COMPLETE = %w(@_done @_qa @_tested @_accepted) 38 | 39 | def tags 40 | @tags ||= fetch_tags 41 | end 42 | 43 | def tags= tags 44 | @tags = tags 45 | end 46 | 47 | def tags_without_technical 48 | tags - TECHNICAL 49 | end 50 | 51 | def done? 52 | STATUS_COMPLETE.include?(status) 53 | end 54 | 55 | 56 | def estimation 57 | effort ? effort.gsub('@', '').to_f : 0.0 58 | end 59 | 60 | def value 61 | benefit ? benefit.gsub('@_', '').to_i : 0 62 | end 63 | 64 | private 65 | 66 | def fetch_tags 67 | this_tags + parent_tags_without_duplicates 68 | end 69 | 70 | def this_tags 71 | if tag_line = LINE_PATTERN.match(raw) 72 | tag_line[0].scan(TAG_PATTERN) 73 | else 74 | [] 75 | end 76 | end 77 | 78 | def parent_tags 79 | respond_to?(:second_tags_source) ? second_tags_source.tags : [] 80 | end 81 | 82 | def parent_tags_without_duplicates 83 | parent_tags.collect { |p_tag| (type = detect_type(p_tag) and find(type, this_tags)) ? nil : p_tag }.compact 84 | end 85 | 86 | def find type, collection = tags 87 | collection.detect do |tag| 88 | !TECHNICAL.include?(tag) and tag =~ PATTERN[type] 89 | end 90 | end 91 | 92 | def detect_type tag 93 | PATTERN.invert.each_pair do |pattern, type| 94 | return(type) if tag =~ pattern 95 | end 96 | end 97 | 98 | def method_missing(m, *args, &block) 99 | if PATTERN.has_key?(m.to_sym) 100 | find(m.to_sym) 101 | else 102 | super 103 | end 104 | end 105 | end 106 | end 107 | end 108 | end -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | # Don't change this file! 2 | # Configure your app in config/environment.rb and config/environments/*.rb 3 | 4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) 5 | 6 | module Rails 7 | class << self 8 | def boot! 9 | unless booted? 10 | preinitialize 11 | pick_boot.run 12 | end 13 | end 14 | 15 | def booted? 16 | defined? Rails::Initializer 17 | end 18 | 19 | def pick_boot 20 | (vendor_rails? ? VendorBoot : GemBoot).new 21 | end 22 | 23 | def vendor_rails? 24 | File.exist?("#{RAILS_ROOT}/vendor/rails") 25 | end 26 | 27 | def preinitialize 28 | load(preinitializer_path) if File.exist?(preinitializer_path) 29 | end 30 | 31 | def preinitializer_path 32 | "#{RAILS_ROOT}/config/preinitializer.rb" 33 | end 34 | end 35 | 36 | class Boot 37 | def run 38 | load_initializer 39 | Rails::Initializer.run(:set_load_path) 40 | end 41 | end 42 | 43 | class VendorBoot < Boot 44 | def load_initializer 45 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" 46 | Rails::Initializer.run(:install_gem_spec_stubs) 47 | Rails::GemDependency.add_frozen_gem_path 48 | end 49 | end 50 | 51 | class GemBoot < Boot 52 | def load_initializer 53 | self.class.load_rubygems 54 | load_rails_gem 55 | require 'initializer' 56 | end 57 | 58 | def load_rails_gem 59 | if version = self.class.gem_version 60 | gem 'rails', version 61 | else 62 | gem 'rails' 63 | end 64 | rescue Gem::LoadError => load_error 65 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) 66 | exit 1 67 | end 68 | 69 | class << self 70 | def rubygems_version 71 | Gem::RubyGemsVersion rescue nil 72 | end 73 | 74 | def gem_version 75 | if defined? RAILS_GEM_VERSION 76 | RAILS_GEM_VERSION 77 | elsif ENV.include?('RAILS_GEM_VERSION') 78 | ENV['RAILS_GEM_VERSION'] 79 | else 80 | parse_gem_version(read_environment_rb) 81 | end 82 | end 83 | 84 | def load_rubygems 85 | min_version = '1.3.2' 86 | require 'rubygems' 87 | unless rubygems_version >= min_version 88 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) 89 | exit 1 90 | end 91 | 92 | rescue LoadError 93 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) 94 | exit 1 95 | end 96 | 97 | def parse_gem_version(text) 98 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ 99 | end 100 | 101 | private 102 | def read_environment_rb 103 | File.read("#{RAILS_ROOT}/config/environment.rb") 104 | end 105 | end 106 | end 107 | end 108 | 109 | # All that for this: 110 | Rails.boot! 111 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/spec/cucumber_f_m/feature_module/tag_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe "Cucumber::FeatureElement::Component::Tags" do 4 | before(:all) do 5 | class TagTesting 6 | include CucumberFM::FeatureElement::Component::Tags 7 | end 8 | end 9 | before(:each) do 10 | @test = TagTesting.new 11 | end 12 | it "should find all tags without duplication" do 13 | @test.stub!(:raw).and_return("@aa @bb @24343 @dd") 14 | @test.stub!(:parent_tags).and_return(['@mc', '@_done', '@component', '@4.5']) 15 | @test.tags.should == %w(@aa @bb @24343 @dd @_done @component ) 16 | end 17 | 18 | context "without need to look in feature" do 19 | before(:each) do 20 | @test.stub!(:raw).and_return("@user @m2 @_done @__forums @5 @_3 @mc @i1 @p4 @$_admin") 21 | @test.stub!(:parent_tags).and_return(['@tb', '@_wip', '@m2b', '@4.5', 22 | '@__knowledge_base', '@_8', '@knowledge_base']) 23 | end 24 | { 25 | :component => '@user', 26 | :milestone => '@m2', 27 | :status => '@_done', 28 | :bucket => '@__forums', 29 | :estimation => 5.0, 30 | :value => 3, 31 | :developer => '@mc', 32 | :iteration => '@i1', 33 | :priority => '@p4', 34 | :role => '@$_admin' 35 | }.each do |tag, value| 36 | it "should scan #{tag} with #{value}" do 37 | @test.send(tag).should == value 38 | end 39 | end 40 | end 41 | 42 | # TODO it should removes duplication - tags from the same type if they are present in scenario 43 | context "from feature" do 44 | before(:each) do 45 | @test.stub!(:raw).and_return("@javascript @mongo") 46 | @test.stub!(:parent_tags).and_return(['@tb', '@_wip', '@m2b', '@4.5', 47 | '@__knowledge_base', '@_8', '@knowledge_base']) 48 | end 49 | { 50 | :component => '@knowledge_base', 51 | :milestone => '@m2b', 52 | :status => '@_wip', 53 | :bucket => '@__knowledge_base', 54 | :estimation => 4.5, 55 | :value => 8, 56 | :developer => '@tb' 57 | }.each do |tag, value| 58 | it "should scan #{tag} with #{value}" do 59 | @test.send(tag).should == value 60 | end 61 | end 62 | it { @test.done?.should be_false } 63 | end 64 | 65 | context "scenario tags without duplicates" do 66 | 67 | before(:each) do 68 | @test.stub!(:raw).and_return("@mc @m2 @__ads @p1 @i2") 69 | @test.stub!(:parent_tags).and_return(['@tb', '@_done', '@m2b', '@4.5', 70 | '@__knowledge_base', '@_8', '@knowledge_base']) 71 | end 72 | ['@tb', '@m2b', '@__knowledge_base'].each do |tag| 73 | it "should not include tag: #{tag}" do 74 | @test.tags.should_not include(tag) 75 | end 76 | end 77 | it "should return 9 tags" do 78 | @test.should have(9).tags 79 | end 80 | it { @test.done?.should be_true } 81 | end 82 | 83 | context "tag detecting" 84 | 85 | context "tags without technical" do 86 | before(:each) do 87 | @test.stub!(:raw).and_return("@aa @selenium @bb @24343 @dd @nontestable") 88 | 89 | end 90 | it "should clean up all technical tags" do 91 | %w(@selenium @nontestable).each do |tag| 92 | @test.tags_without_technical.should_not include(tag) 93 | end 94 | end 95 | end 96 | end -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == WatirCukeFM == 2 | 3 | Webdriver + Cucumber + Feature Manager 4 | 5 | Web Application which allows to managed cucumber features written in cucumber and runs them throughout browser. 6 | 7 | Rails application and interface is cloned from https://github.com/cs3b/cucumber_fm/, and it has been extended with functionality of WatirCuke (https://github.com/gs/watircuke/) 8 | 9 | Demo can be viewed on http://www.vimeo.com/17840436 10 | 11 | == How to make it work? 12 | 13 | 1) Just clone the repo from "https://github.com/gs/watircukefm/" 14 | 15 | 2) install bundler (gem install bundle) 16 | 17 | 3) install all gems : bundle install 18 | 19 | 4) run server (./script/server) 20 | 21 | 5) go to your browser and type url: http://localhost:3000/documentation/features 22 | 23 | 24 | Application is divided for 3 parts: 25 | 26 | - Business overview - contains list of available features, can be group by, search by tag and create new feature 27 | 28 | - After clicking on feature user can edit, save, manage file, navigate and run test in chosen browser. Started test, can be stopped in any time. 29 | 30 | - Running test will open new tab where test results will be shown (results are stored in "public/test_results" folder) 31 | 32 | - Statistics - useful information about status of feature, estimation, state 33 | 34 | - Results - lists all test results, by clicking on its name user can view results or remove it if they are not needed anymore 35 | 36 | 37 | IMPORTANT: 38 | 39 | - All features are stored in "features" folder ( cucumber http://cukes.info ) 40 | 41 | - To get familiar with syntax just check "watircuke_step.rb" file or visit https://github.com/gs/WatirCuke-Bundles. You can clone https://github.com/gs/WatirCuke-Bundles and drop it into TextMate or Redcar for snippet support. 42 | 43 | - Application makes screenshots if some step will fail. 44 | 45 | - Can check for missing translation - just goto config/config.yml file and enter regexp for translation_tag and set check_translation to true 46 | 47 | - Application supports Fixtures/Language files. They have to be dropped into : 'features/fixtures' path. 48 | 49 | They need to be in YML format like: 50 | 51 | login.yml: 52 | 53 | login: 54 | login_button: Sign up 55 | 56 | Then you need type in your feature: 57 | 58 | Background: 59 | Given I load "login" fixture 60 | 61 | And then in scenario to use its content: 62 | 63 | I click the ":login.login_button" button 64 | 65 | - Before run go to "feaures/support" folder and rename "paths.rb_example" to "paths.rb" 66 | 67 | 68 | 69 | RUNNING: 70 | 71 | Application can be run in different ways: 72 | 73 | 1) start server and run the test by clicking 74 | 75 | 2) when in folder type in terminal: ruby watircuke.rb -- this will display help and info about how to run it from console 76 | 77 | 78 | 79 | KNOWN ISSUES: 80 | 81 | Problem: 82 | Some time when starting tests browser starts and hangs, page does not load. 83 | 84 | Solution: 85 | Just kill the browser and test and starts once again. 86 | 87 | 88 | Problem: 89 | Missing SYS-PROCTABLE gem 90 | 91 | Solution 92 | To install sys-proctable platform (x86-mswin32-60 ,x86-freebsd-7 ,x86-linux ,x86-darwin-8 ,x86-solaris-2.10) need to specify : 93 | 94 | Windows: 95 | gem install sys-proctable --platform="x86-mswin32-60" 96 | 97 | MacOsx 98 | gem install sys-proctable --platform="x86-darwin-8" 99 | 100 | License: MIT 101 | 102 | Have fun and contact me any time at grzegorz.smajdor[at]gmail.com 103 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/public/bespin/BespinEmbedded.css: -------------------------------------------------------------------------------- 1 | .bespin-completion-panel { 2 | font-family: Helvetica, Arial, sans-serif; 3 | position: absolute; 4 | cursor: default; 5 | line-height: normal; 6 | -moz-user-select: none; 7 | -webkit-user-select: none; 8 | } 9 | 10 | .bespin-completion-pointer { 11 | position: absolute; 12 | z-index: 2; 13 | height: 21px; 14 | width: 21px; 15 | } 16 | 17 | .bespin-completion-pointer-up { 18 | top: 1px; 19 | border-top: solid #555 1px; 20 | border-left: solid #555 1px; 21 | background-image: -moz-linear-gradient(top left, #333333, #333333 50%, transparent 50%, transparent); 22 | background-image: -webkit-gradient(linear, left top, right bottom, from(#333333), color-stop(0.5, #333333), color-stop(0.5, transparent), to(transparent)); 23 | -moz-transform: rotate(45deg); 24 | -webkit-transform: rotate(45deg); 25 | } 26 | 27 | .bespin-completion-pointer-down { 28 | bottom: 1px; 29 | border-top: solid #000 1px; 30 | border-left: solid #000 1px; 31 | background-image: -moz-linear-gradient(top left, #000, #000 50%, transparent 50%, transparent); 32 | background-image: -webkit-gradient(linear, left top, right bottom, from(#000), color-stop(0.5, #000), color-stop(0.5, transparent), to(transparent)); 33 | -moz-transform: rotate(225deg); 34 | -webkit-transform: rotate(225deg); 35 | } 36 | 37 | .bespin-completion-bubble-outer { 38 | position: relative; 39 | z-index: 1; 40 | margin: 11px 0px 11px 0px; 41 | border-top: solid #555 1px; 42 | -moz-border-radius: 8px; 43 | -webkit-border-radius: 8px; 44 | } 45 | 46 | .bespin-completion-bubble-inner { 47 | position: relative; 48 | z-index: 3; 49 | padding: 6px; 50 | background: -moz-linear-gradient(top, #333333, #000000); 51 | background: -webkit-gradient(linear, center top, center bottom, from(#333333), to(#000000)); 52 | color: #ffffff; 53 | font-size: 10.5pt; 54 | -moz-border-radius: 8px; 55 | -webkit-border-radius: 8px; 56 | -moz-box-shadow: 0px 6px 16px 2px rgba(0, 0, 0, 0.5); 57 | -webkit-box-shadow: 0px 6px 16px 2px rgba(0, 0, 0, 0.5); 58 | } 59 | 60 | .bespin-completion-panel ul { 61 | list-style: none; 62 | margin: 0px; 63 | padding: 0px; 64 | } 65 | 66 | .bespin-completion-panel li { 67 | text-indent: 0px; 68 | margin: 0px; 69 | padding: 6px 16px; 70 | } 71 | 72 | .bespin-completion-highlight { 73 | position: absolute; 74 | z-index: -1; 75 | background-image: -moz-linear-gradient(top, #3e59be, #312d80); 76 | background-image: -webkit-gradient(linear, center top, center bottom, from(#3e59be), to(#312d80)); 77 | border: solid rgba(37, 34, 91, 1.0) 1px; 78 | -moz-border-radius: 6px; 79 | -webkit-border-radius: 6px; 80 | } 81 | 82 | .bespin-completion-kind { 83 | display: block; 84 | float: left; 85 | top: 0px; 86 | left: 0px; 87 | width: 8px; 88 | height: 8px; 89 | padding: 2px; 90 | margin: 0px 5px 0px 0px; 91 | font-size: 6.5pt; 92 | font-weight: bold; 93 | text-transform: uppercase; 94 | text-align: center; 95 | -moz-border-radius: 3px; 96 | -webkit-border-radius: 3px; 97 | } 98 | 99 | .bespin-completion-kind-m { 100 | background-color: maroon; 101 | } 102 | 103 | .bespin-completion-kind-f { 104 | background-color: green; 105 | } 106 | 107 | .bespin-completion-top-row { 108 | position: relative; 109 | } 110 | 111 | .bespin-completion-second-row { 112 | margin: 6px 0px 0px 17px; 113 | display: none; 114 | } 115 | 116 | .bespin-completion-ident { 117 | font-weight: bold; 118 | } 119 | 120 | .bespin-completion-container { 121 | color: #a0a0a0; 122 | } 123 | 124 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_f_m/feature.rb: -------------------------------------------------------------------------------- 1 | module CucumberFM 2 | class Feature < Struct.new(:path, :cfm) 3 | 4 | include FeatureElement::Component::TotalEstimation 5 | 6 | def id 7 | Base64.encode64(relative_path) 8 | end 9 | 10 | def relative_path 11 | path.gsub(/^#{cfm.path}\//, '') 12 | end 13 | 14 | def raw 15 | @raw ||= read_content_from_file 16 | end 17 | 18 | def raw= content 19 | @raw = content 20 | end 21 | 22 | def info 23 | @info ||= FeatureElement::Info.new(self, scan_for_feature_info_from_raw) 24 | end 25 | 26 | def background 27 | @background ||= FeatureElement::Background.new(self, scan_for_background_from_raw) 28 | end 29 | 30 | def scenarios 31 | @scenarios ||= fetch_scenarios 32 | end 33 | 34 | def tags 35 | info.tags 36 | end 37 | 38 | def tags_all 39 | scenarios.collect{|scenario| scenario.tags }.flatten.uniq 40 | end 41 | 42 | def save 43 | write_content_to_file 44 | commit 45 | push 46 | true 47 | end 48 | 49 | def destroy 50 | File.delete(path) 51 | remove_file_from_repo 52 | push 53 | end 54 | 55 | def filename 56 | File.basename(path) 57 | end 58 | 59 | def filename_without_extension 60 | File.basename(path, '.feature') 61 | end 62 | 63 | def <=>(_f) 64 | info.title <=> _f.info.title 65 | end 66 | 67 | private 68 | 69 | def read_content_from_file 70 | File.open(path, 'r') { |stream| stream.read } 71 | end 72 | 73 | def write_content_to_file 74 | File.open(path, 'w') { |stream| stream.write raw } 75 | end 76 | 77 | 78 | # TODO we need to detect it in more clever way 79 | def commit 80 | cfm.commit_change_on(self) if do_commit? 81 | end 82 | 83 | # TODO we need to detect it in more clever way 84 | def push 85 | cfm.send_to_remote if do_push? 86 | end 87 | 88 | def remove_file_from_repo 89 | cfm.remove_file_from_repo(relative_path) if do_commit? 90 | end 91 | 92 | def do_push? 93 | cfm && cfm.respond_to?(:send_to_remote) && cfm.config.cvs_commit=='1' && cfm.config.cvs_push=='1' 94 | end 95 | 96 | def do_commit? 97 | cfm && cfm.respond_to?(:commit_change_on) && cfm.config.cvs_commit=='1' 98 | end 99 | 100 | def fetch_scenarios 101 | scenarios = [] 102 | text = raw 103 | while match = scan_for_scenarios_and_scenario_outline_from(text) 104 | scenario = case match[0] 105 | when FeatureElement::Scenario::PATTERN 106 | FeatureElement::Scenario.new(self, match[0]) 107 | when FeatureElement::ScenarioOutline::PATTERN 108 | FeatureElement::ScenarioOutline.new(self, match[0]) 109 | end 110 | scenarios.push(scenario) if cfm.filter.pass?(scenario.tags) 111 | text = match.post_match 112 | end 113 | scenarios 114 | end 115 | 116 | def scan_for_feature_info_from_raw 117 | if match = FeatureElement::Info::PATTERN.match(raw) 118 | match[0] 119 | else 120 | '' 121 | end 122 | end 123 | 124 | def scan_for_background_from_raw 125 | if match = FeatureElement::Background::PATTERN.match(raw) 126 | match[0] 127 | else 128 | '' 129 | end 130 | end 131 | 132 | def scan_for_scenarios_and_scenario_outline_from(string) 133 | scenario_or_scenario_outline.match(string) 134 | end 135 | 136 | def scenario_or_scenario_outline 137 | Regexp.union(FeatureElement::Scenario::PATTERN, 138 | FeatureElement::ScenarioOutline::PATTERN) 139 | end 140 | end 141 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/controllers/documentation/features_controller.rb: -------------------------------------------------------------------------------- 1 | class Documentation::FeaturesController < Documentation::ApplicationController 2 | 3 | before_filter :fetch_feature, :only => [:show, :edit, :update, :delete, :rename, :move] 4 | before_filter :cleanup_raw, :only => [:update] 5 | 6 | def index 7 | @highlight = 'business_overview' 8 | cfm 9 | end 10 | 11 | def show 12 | end 13 | 14 | def statistic 15 | @highlight = 'statistic' 16 | @statistic = CucumberFM::Statistic.new(cfm) 17 | end 18 | 19 | def edit 20 | end 21 | 22 | def create 23 | if filename_invalid? 24 | redirect_to :action => 'index' 25 | elsif File.exists?(new_file_path) 26 | feature = CucumberFM::Feature.new(new_file_path, cfm) 27 | redirect_to edit_documentation_feature_path(feature.id) 28 | else 29 | feature = CucumberFM::Feature.new(new_file_path, cfm) 30 | feature.raw=(new_feature_raw) 31 | feature.save 32 | redirect_to edit_documentation_feature_path(feature.id) 33 | end 34 | end 35 | 36 | def update 37 | @feature.raw=(params[:raw]) 38 | @feature.save 39 | redirect_to :action => :edit 40 | end 41 | 42 | def delete 43 | @feature.destroy 44 | flash[:notice]= "File: #{@feature.filename} was removed" 45 | redirect_to :action => :index 46 | end 47 | 48 | def rename 49 | if filename_invalid? 50 | redirect_to edit_documentation_feature_path(@feature.id) 51 | flash[:notice] = 'filename is invalid' 52 | elsif File.exists?(new_file_path) 53 | flash[:notice] = 'file with this name exist' 54 | redirect_to edit_documentation_feature_path(@feature.id) 55 | else 56 | feature = CucumberFM::Feature.new(new_file_path, cfm) 57 | feature.raw=(@feature.raw) 58 | feature.save && @feature.destroy 59 | redirect_to edit_documentation_feature_path(feature.id) 60 | end 61 | end 62 | 63 | def move 64 | move_to_path = new_file_path(params[:dir], @feature.filename_without_extension) 65 | if File.exists?(move_to_path) 66 | flash[:notice] = 'file with this name exist' 67 | redirect_to edit_documentation_feature_path(@feature.id) 68 | else 69 | feature = CucumberFM::Feature.new(move_to_path, cfm) 70 | feature.raw=(@feature.raw) 71 | feature.save && @feature.destroy 72 | redirect_to edit_documentation_feature_path(feature.id) 73 | end 74 | end 75 | 76 | private 77 | 78 | # TODO create method find in Feature and remove method path 79 | def fetch_feature 80 | @feature = CucumberFM::Feature.new(path, cfm) 81 | end 82 | 83 | def path 84 | File.join(cfm.path, Base64.decode64(params[:id])) 85 | end 86 | 87 | def cfm 88 | @cfm ||= CucumberFeatureManager.new(feature_dir_path, git_dir_path, read_config) 89 | end 90 | 91 | # TODO move this to save method in feature 92 | 93 | def cleanup_raw 94 | params[:raw].gsub!(/\r/, '') 95 | end 96 | 97 | def new_file_path(dir = read_config['dir'], filename = new_file_name) 98 | File.join(feature_dir_path, dir, "#{filename}.feature") 99 | end 100 | 101 | # TODO move this methods to feature 102 | 103 | def new_file_name 104 | params[:name].gsub(/[^a-zA-Z0-9]/, '_') 105 | end 106 | 107 | def new_file_feature_name 108 | params[:name].gsub(/(_|\.feature)/, ' ') 109 | end 110 | 111 | def new_feature_raw 112 | %{Feature: #{new_file_feature_name}} 113 | end 114 | 115 | # TODO put to class feature 116 | 117 | def filename_invalid? 118 | (params[:name].blank? or params[:name].size < 4) ? 119 | flash[:error] = 'File name too short, at least 4 alphanumeric characters' : 120 | false 121 | end 122 | 123 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/tree.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Tree 4 | lazy_reader :contents 5 | attr_reader :id 6 | attr_reader :mode 7 | attr_reader :name 8 | 9 | # Construct the contents of the tree 10 | # +repo+ is the Repo 11 | # +treeish+ is the reference 12 | # +paths+ is an optional Array of directory paths to restrict the tree 13 | # 14 | # Returns Grit::Tree (baked) 15 | def self.construct(repo, treeish, paths = []) 16 | output = repo.git.ls_tree({}, treeish, *paths) 17 | self.allocate.construct_initialize(repo, treeish, output) 18 | end 19 | 20 | def construct_initialize(repo, id, text) 21 | @repo = repo 22 | @id = id 23 | @contents = [] 24 | 25 | text.split("\n").each do |line| 26 | @contents << content_from_string(repo, line) 27 | end 28 | @contents.compact! 29 | 30 | self 31 | end 32 | 33 | def lazy_source 34 | Tree.construct(@repo, @id, []) 35 | end 36 | 37 | # Create an unbaked Tree containing just the specified attributes 38 | # +repo+ is the Repo 39 | # +atts+ is a Hash of instance variable data 40 | # 41 | # Returns Grit::Tree (unbaked) 42 | def self.create(repo, atts) 43 | self.allocate.create_initialize(repo, atts) 44 | end 45 | 46 | # Initializer for Tree.create 47 | # +repo+ is the Repo 48 | # +atts+ is a Hash of instance variable data 49 | # 50 | # Returns Grit::Tree (unbaked) 51 | def create_initialize(repo, atts) 52 | @repo = repo 53 | 54 | atts.each do |k, v| 55 | instance_variable_set("@#{k}", v) 56 | end 57 | self 58 | end 59 | 60 | # Parse a content item and create the appropriate object 61 | # +repo+ is the Repo 62 | # +text+ is the single line containing the items data in `git ls-tree` format 63 | # 64 | # Returns Grit::Blob or Grit::Tree 65 | def content_from_string(repo, text) 66 | mode, type, id, name = text.split(" ", 4) 67 | case type 68 | when "tree" 69 | Tree.create(repo, :id => id, :mode => mode, :name => name) 70 | when "blob" 71 | Blob.create(repo, :id => id, :mode => mode, :name => name) 72 | when "link" 73 | Blob.create(repo, :id => id, :mode => mode, :name => name) 74 | when "commit" 75 | Submodule.create(repo, :id => id, :mode => mode, :name => name) 76 | else 77 | raise "Invalid type: #{type}" 78 | end 79 | end 80 | 81 | # Find the named object in this tree's contents 82 | # 83 | # Examples 84 | # Repo.new('/path/to/grit').tree/'lib' 85 | # # => # 86 | # Repo.new('/path/to/grit').tree/'README.txt' 87 | # # => # 88 | # 89 | # Returns Grit::Blob or Grit::Tree or nil if not found 90 | def /(file) 91 | if file =~ /\// 92 | file.split("/").inject(self) { |acc, x| acc/x } rescue nil 93 | else 94 | self.contents.find { |c| c.name == file } 95 | end 96 | end 97 | 98 | def basename 99 | File.basename(name) 100 | end 101 | 102 | # Pretty object inspection 103 | def inspect 104 | %Q{#} 105 | end 106 | 107 | # Find only Tree objects from contents 108 | def trees 109 | contents.select {|v| v.kind_of? Tree} 110 | end 111 | 112 | # Find only Blob objects from contents 113 | def blobs 114 | contents.select {|v| v.kind_of? Blob} 115 | end 116 | 117 | # Compares trees by name 118 | def <=>(other) 119 | name <=> other.name 120 | end 121 | end # Tree 122 | 123 | end # Grit 124 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/app/views/documentation/features/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Actions

5 |
6 |

Feature

7 |
8 |
9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | <%= raw draw_report_rows(@cfm) %> 22 | 23 |
Features <%= @cfm.features.size %>Scenarios <%= @cfm.scenarios.size %>Estimation <%= @cfm.estimation %>
24 |
25 | 26 |
27 | <% form_tag '', :method => :get do %> 28 | 29 |

Scope by

30 | 31 |
32 | 33 |
34 | <%= hidden_field_tag 'config[cvs_commit]', @cfm.config.cvs_commit %> 35 | <%= hidden_field_tag 'config[cvs_push]', @cfm.config.cvs_push %> 36 |
    37 |
  1. 38 | <%= label_tag 'config[dir]', "Directory:" %> 39 | <%= select_tag 'config[dir]', options_for_select(list_of_dirs, :selected => @cfm.config.dir) %> 40 |
  2. 41 |
  3. 42 | <%= label_tag 'config[tags]', "Tags:" %> 43 | <%= text_field_tag 'config[tags]', @cfm.config.tags %> 44 |
  4. 45 |
46 |
47 | 48 |
49 | 50 |

Presentation settings

51 | 52 |
53 | 54 |
55 |
    56 |
  1. 57 | 58 | <%= select_tag 'config[aggregate][]', options_for_select(@cfm.config.aggregate_options, :selected => @cfm.config.aggregate.first) %> 59 |
  2. 60 |
  3. 61 | <%= select_tag 'config[aggregate][]', options_for_select(@cfm.config.aggregate_options, :selected => @cfm.config.aggregate.last) %> 62 |
  4. 63 |
  5. 64 |
    65 | <%= submit_tag "Filter" %> 66 |
    67 |
  6. 68 | 69 |
70 |
71 | 72 |
73 | 74 |
75 | 76 |
77 | <% end %> 78 | 79 |
80 |

Add new feature

81 |
82 | 83 | 84 | 85 | <% form_tag documentation_features_path, :name => 'new_form', :method => 'post' do %> 86 | 87 |
88 | 89 |
90 |
    91 |
  1. 92 | 93 | <%= text_field_tag 'name' %> 94 |
  2. 95 |
  3. 96 |
    97 | <%= submit_tag "Add" %> 98 |
    99 |
  4. 100 |
101 |
102 | 103 |
104 | 105 | <% end %> 106 | 107 |
108 | 109 |
110 | 111 | 112 |
113 |
114 | 115 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/commit_stats.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class CommitStats 4 | 5 | attr_reader :id, :files, :additions, :deletions, :total 6 | 7 | # Instantiate a new CommitStats 8 | # +id+ is the id of the commit 9 | # +files+ is an array of : 10 | # [ [filename, adds, deletes, total], 11 | # [filename, adds, deletes, total], 12 | # [filename, adds, deletes, total] ] 13 | # 14 | # Returns Grit::CommitStats (baked) 15 | def initialize(repo, id, files) 16 | @repo = repo 17 | @id = id 18 | @files = files 19 | @additions = files.inject(0) { |total, a| total += a[1] } 20 | @deletions = files.inject(0) { |total, a| total += a[2] } 21 | @total = files.inject(0) { |total, a| total += a[3] } 22 | end 23 | 24 | # Find all commit stats matching the given criteria. 25 | # +repo+ is the Repo 26 | # +ref+ is the ref from which to begin (SHA1 or name) or nil for --all 27 | # +options+ is a Hash of optional arguments to git 28 | # :max_count is the maximum number of commits to fetch 29 | # :skip is the number of commits to skip 30 | # 31 | # Returns assoc array [sha, Grit::Commit[] (baked)] 32 | def self.find_all(repo, ref, options = {}) 33 | allowed_options = [:max_count, :skip, :since] 34 | 35 | default_options = {:numstat => true} 36 | actual_options = default_options.merge(options) 37 | 38 | if ref 39 | output = repo.git.log(actual_options, ref) 40 | else 41 | output = repo.git.log(actual_options.merge(:all => true)) 42 | end 43 | 44 | self.list_from_string(repo, output) 45 | end 46 | 47 | # Parse out commit information into an array of baked Commit objects 48 | # +repo+ is the Repo 49 | # +text+ is the text output from the git command (raw format) 50 | # 51 | # Returns assoc array [sha, Grit::Commit[] (baked)] 52 | def self.list_from_string(repo, text) 53 | lines = text.split("\n") 54 | 55 | commits = [] 56 | 57 | while !lines.empty? 58 | id = lines.shift.split.last 59 | 60 | lines.shift 61 | lines.shift 62 | lines.shift 63 | 64 | message_lines = [] 65 | message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/ || lines.first == '' 66 | 67 | lines.shift while lines.first && lines.first.empty? 68 | 69 | files = [] 70 | while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/ 71 | (additions, deletions, filename) = lines.shift.split 72 | additions = additions.to_i 73 | deletions = deletions.to_i 74 | total = additions + deletions 75 | files << [filename, additions, deletions, total] 76 | end 77 | 78 | lines.shift while lines.first && lines.first.empty? 79 | 80 | commits << [id, CommitStats.new(repo, id, files)] 81 | end 82 | 83 | commits 84 | end 85 | 86 | # Pretty object inspection 87 | def inspect 88 | %Q{#} 89 | end 90 | 91 | # Convert to an easy-to-traverse structure 92 | def to_diffstat 93 | files.map do |metadata| 94 | DiffStat.new(*metadata) 95 | end 96 | end 97 | 98 | # private 99 | 100 | def to_hash 101 | { 102 | 'id' => id, 103 | 'files' => files, 104 | 'additions' => additions, 105 | 'deletions' => deletions, 106 | 'total' => total 107 | } 108 | end 109 | 110 | end # CommitStats 111 | 112 | class DiffStat 113 | attr_reader :filename, :additions, :deletions 114 | 115 | def initialize(filename, additions, deletions, total=nil) 116 | @filename, @additions, @deletions = filename, additions, deletions 117 | end 118 | 119 | def net 120 | additions - deletions 121 | end 122 | 123 | def inspect 124 | "#{filename}: +#{additions} -#{deletions}" 125 | end 126 | end 127 | 128 | end # Grit 129 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/index.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Index 4 | attr_accessor :repo, :tree, :current_tree 5 | 6 | def initialize(repo) 7 | self.repo = repo 8 | self.tree = {} 9 | self.current_tree = nil 10 | end 11 | 12 | # Add a file to the index 13 | # +path+ is the path (including filename) 14 | # +data+ is the binary contents of the file 15 | # 16 | # Returns nothing 17 | def add(file_path, data) 18 | path = file_path.split('/') 19 | filename = path.pop 20 | 21 | current = self.tree 22 | 23 | path.each do |dir| 24 | current[dir] ||= {} 25 | node = current[dir] 26 | current = node 27 | end 28 | 29 | current[filename] = data 30 | end 31 | 32 | # Sets the current tree 33 | # +tree+ the branch/tag/sha... to use - a string 34 | # 35 | # Returns index (self) 36 | def read_tree(tree) 37 | self.current_tree = self.repo.tree(tree) 38 | end 39 | 40 | # Commit the contents of the index 41 | # +message+ is the commit message [nil] 42 | # +parents+ is one or more commits to attach this commit to to form a new head [nil] 43 | # +actor+ is the details of the user making the commit [nil] 44 | # +last_tree+ is a tree to compare with - to avoid making empty commits [nil] 45 | # +head+ is the branch to write this head to [master] 46 | # 47 | # Returns a String of the SHA1 of the commit 48 | def commit(message, parents = nil, actor = nil, last_tree = nil, head = 'master') 49 | tree_sha1 = write_tree(self.tree, self.current_tree) 50 | return false if tree_sha1 == last_tree # don't write identical commits 51 | 52 | contents = [] 53 | contents << ['tree', tree_sha1].join(' ') 54 | parents.each do |p| 55 | contents << ['parent', p].join(' ') if p 56 | end if parents 57 | 58 | if actor 59 | name = actor.name 60 | email = actor.email 61 | else 62 | config = Config.new(self.repo) 63 | name = config['user.name'] 64 | email = config['user.email'] 65 | end 66 | 67 | author_string = "#{name} <#{email}> #{Time.now.to_i} -0700" # !! TODO : gotta fix this 68 | contents << ['author', author_string].join(' ') 69 | contents << ['committer', author_string].join(' ') 70 | contents << '' 71 | contents << message 72 | 73 | commit_sha1 = self.repo.git.put_raw_object(contents.join("\n"), 'commit') 74 | 75 | self.repo.update_ref(head, commit_sha1) 76 | end 77 | 78 | # Recursively write a tree to the index 79 | # +tree+ is the tree 80 | # 81 | # Returns the SHA1 String of the tree 82 | def write_tree(tree, now_tree = nil) 83 | tree_contents = {} 84 | 85 | # fill in original tree 86 | now_tree.contents.each do |obj| 87 | sha = [obj.id].pack("H*") 88 | k = obj.name 89 | k += '/' if (obj.class == Grit::Tree) 90 | tree_contents[k] = "%s %s\0%s" % [obj.mode.to_s, obj.name, sha] 91 | end if now_tree 92 | 93 | # overwrite with new tree contents 94 | tree.each do |k, v| 95 | case v 96 | when String 97 | sha = write_blob(v) 98 | sha = [sha].pack("H*") 99 | str = "%s %s\0%s" % ['100644', k, sha] 100 | tree_contents[k] = str 101 | when Hash 102 | ctree = now_tree/k if now_tree 103 | sha = write_tree(v, ctree) 104 | sha = [sha].pack("H*") 105 | str = "%s %s\0%s" % ['040000', k, sha] 106 | tree_contents[k + '/'] = str 107 | end 108 | end 109 | tr = tree_contents.sort.map { |k, v| v }.join('') 110 | self.repo.git.put_raw_object(tr, 'tree') 111 | end 112 | 113 | # Write the blob to the index 114 | # +data+ is the data to write 115 | # 116 | # Returns the SHA1 String of the blob 117 | def write_blob(data) 118 | self.repo.git.put_raw_object(data, 'blob') 119 | end 120 | end # Index 121 | 122 | end # Grit 123 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/blob.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Blob 4 | DEFAULT_MIME_TYPE = "text/plain" 5 | 6 | attr_reader :id 7 | attr_reader :mode 8 | attr_reader :name 9 | 10 | # Create an unbaked Blob containing just the specified attributes 11 | # +repo+ is the Repo 12 | # +atts+ is a Hash of instance variable data 13 | # 14 | # Returns Grit::Blob (unbaked) 15 | def self.create(repo, atts) 16 | self.allocate.create_initialize(repo, atts) 17 | end 18 | 19 | # Initializer for Blob.create 20 | # +repo+ is the Repo 21 | # +atts+ is a Hash of instance variable data 22 | # 23 | # Returns Grit::Blob (unbaked) 24 | def create_initialize(repo, atts) 25 | @repo = repo 26 | atts.each do |k, v| 27 | instance_variable_set("@#{k}".to_sym, v) 28 | end 29 | self 30 | end 31 | 32 | # The size of this blob in bytes 33 | # 34 | # Returns Integer 35 | def size 36 | @size ||= @repo.git.cat_file({:s => true}, id).chomp.to_i 37 | end 38 | 39 | # The binary contents of this blob. 40 | # 41 | # Returns String 42 | def data 43 | @data ||= @repo.git.cat_file({:p => true}, id) 44 | end 45 | 46 | # The mime type of this file (based on the filename) 47 | # 48 | # Returns String 49 | def mime_type 50 | guesses = MIME::Types.type_for(self.name) rescue [] 51 | guesses.first ? guesses.first.simplified : DEFAULT_MIME_TYPE 52 | end 53 | 54 | # The blame information for the given file at the given commit 55 | # 56 | # Returns Array: [Grit::Commit, Array: []] 57 | def self.blame(repo, commit, file) 58 | data = repo.git.blame({:p => true}, commit, '--', file) 59 | 60 | commits = {} 61 | blames = [] 62 | info = nil 63 | 64 | data.split("\n").each do |line| 65 | parts = line.split(/\s+/, 2) 66 | case parts.first 67 | when /^[0-9A-Fa-f]{40}$/ 68 | case line 69 | when /^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/ 70 | _, id, origin_line, final_line, group_lines = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+) (\d+)$/) 71 | info = {:id => id} 72 | blames << [nil, []] 73 | when /^([0-9A-Fa-f]{40}) (\d+) (\d+)$/ 74 | _, id, origin_line, final_line = *line.match(/^([0-9A-Fa-f]{40}) (\d+) (\d+)$/) 75 | info = {:id => id} 76 | end 77 | when /^(author|committer)/ 78 | case parts.first 79 | when /^(.+)-mail$/ 80 | info["#{$1}_email".intern] = parts.last 81 | when /^(.+)-time$/ 82 | info["#{$1}_date".intern] = Time.at(parts.last.to_i) 83 | when /^(author|committer)$/ 84 | info[$1.intern] = parts.last 85 | end 86 | when /^filename/ 87 | info[:filename] = parts.last 88 | when /^summary/ 89 | info[:summary] = parts.last 90 | when '' 91 | c = commits[info[:id]] 92 | unless c 93 | c = Commit.create(repo, :id => info[:id], 94 | :author => Actor.from_string(info[:author] + ' ' + info[:author_email]), 95 | :authored_date => info[:author_date], 96 | :committer => Actor.from_string(info[:committer] + ' ' + info[:committer_email]), 97 | :committed_date => info[:committer_date], 98 | :message => info[:summary]) 99 | commits[info[:id]] = c 100 | end 101 | _, text = *line.match(/^\t(.*)$/) 102 | blames.last[0] = c 103 | blames.last[1] << text 104 | info = nil 105 | end 106 | end 107 | 108 | blames 109 | end 110 | 111 | def basename 112 | File.basename(name) 113 | end 114 | 115 | # Pretty object inspection 116 | def inspect 117 | %Q{#} 118 | end 119 | 120 | # Compares blobs by name 121 | def <=>(other) 122 | name <=> other.name 123 | end 124 | end # Blob 125 | 126 | end # Grit -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/CHANGELOG: -------------------------------------------------------------------------------- 1 | * fix - when aggregating data skip technical tags 2 | * fix - drawing navigation in editor for scenario outline 3 | * fix - problem with parsing scenario outline 4 | * fix - explicit conversion to string for match param ( ruby 1.9.2 issue ) 5 | * fix - config.aggregate should by default array, instead of empty string 6 | * feature - orange highlighting scenario estimation if this scenario is in status @_todo 7 | * fix - status @_tested is treated also as done 8 | * feature - red highlighting scenario estimation if this scenario isn't done 9 | * fix - sorting group by context in business overview 10 | * feature - grouping by role (@$_) 11 | * fix - feature delete 12 | * fix - correct parsing scenario|feature|background title when in title appear ':' 13 | * fix - syntax highlighting ( Background:, Examples:, And, But ) 14 | * fix - & < > reverse_html_escape 15 | * fix - escaping ' and " for javascript strings 16 | * fix sorting directory names in business overview page 17 | * fix parsing estimation tag in scenarios navigator 18 | * custom build of Mozilla SkyWriter (aka Bespin) with gherkin syntax highlighting 19 | * editor page 20 | ** layout fixes 21 | ** scenario navigation 22 | *** including tags and estimation 23 | *** filtering functionality 24 | * scenario on business view clickable - direct access to scenario in editor 25 | * updating bespin ( new name SkyWriter ) to 0.9a2 26 | * Statistics and Aggregate by Something Todo 27 | 28 | 0.1.3 29 | * Statisctic- various 30 | * Statistic - overal, component, iteration, developer, bucket, status 31 | * Busines Overview - alphabetic sorting aggregated headers 32 | * Busines Overview - progress bars on aggregated results (skipped on status aggregation) 33 | * Percentage progress visualization by Rafał Bromirski from Selleo 34 | * Fluid Layout by Rafał Bromirski from Selleo 35 | * Layout Fixes ( browser compatibility ) by Rafał Bromirski from Selleo 36 | 37 | 0.1.2 38 | * Editor - Basic ::: Scenario: Moving feature 39 | * Editor - Basic ::: Scenario: Renaming feature 40 | * Editor - Basic ::: Scenario: Deleting feature 41 | 42 | 0.1.1 43 | * filter ::: Scenario: Filtering by negation (~) 44 | * filter ::: Scenario: Filtering by group of tags ( using or - coma ) 45 | * fix take only tags from feature that are not present in scenario 46 | * fix do not overwrite config git when using filter from business overview 47 | 48 | 0.1.0 49 | * fix do not overwrite config[aggragate] when saving files 50 | * align scenario to left (Github@Issue#6) 51 | * removing simply http auth - messing up with devise 52 | * changing default commit message 53 | * checkbox'es in editor that allows to skip commit and push 54 | * refactoring config and adding conditional push and commit to feature save 55 | 56 | 0.0.11 57 | * moving syntax highlighting to next milestone 58 | * adding some validation for create feature 59 | * fix navigator title regex 60 | * fix of listing only directories in dir scope 61 | * adding navigation to editor 62 | * updated bespin to 0.8.0 63 | 64 | 0.0.10 65 | * fix of saving edited file 66 | * add create new feature 67 | * menu items highlighting 68 | * in aggregate report also displaying scenarios 69 | * fix colspan spelling 70 | * fix correct paths to assests 71 | * fix assent handling (content_type) 72 | * graphic and design be Rafał Bromirski from Selleo 73 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.10.editor.jpg 74 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.10.dasboard.jpg 75 | 76 | 0.0.9 77 | * using bespin as editor 78 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.9.editor.jpg 79 | * internal assets serving 80 | * bugfix: wrong method name in cfm 81 | 82 | 0.0.8 83 | * git (with remotes) support 84 | * simply editor 85 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.8.editor.jpg 86 | * ugly styling in dashboard 87 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.8.dashboard.jpg 88 | * bugfix: spelling of collspan -> colspan 89 | 90 | 0.0.7 91 | * listing scenarios in dashboard 92 | * aggregator for based on two dimensions 93 | > Viewing dashboard 94 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.7.dashboard.jpg 95 | 96 | 0.0.6 97 | * basic tag filtering 98 | * keeping user setting in cookie 99 | 100 | 0.0.5 101 | Business Overview - dashboard 102 | > Viewing dashobard 103 | http://cs3b-cucumber-fm.s3.amazonaws.com/0.0.5.dashboard.jpg 104 | * scheduling features 105 | * features specyfication 106 | 107 | 0.0.4 108 | * core development -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/status.rb: -------------------------------------------------------------------------------- 1 | module Grit 2 | 3 | class Status 4 | include Enumerable 5 | 6 | @base = nil 7 | @files = nil 8 | 9 | def initialize(base) 10 | @base = base 11 | construct_status 12 | end 13 | 14 | def changed 15 | @files.select { |k, f| f.type == 'M' } 16 | end 17 | 18 | def added 19 | @files.select { |k, f| f.type == 'A' } 20 | end 21 | 22 | def deleted 23 | @files.select { |k, f| f.type == 'D' } 24 | end 25 | 26 | def untracked 27 | @files.select { |k, f| f.untracked } 28 | end 29 | 30 | def pretty 31 | out = '' 32 | self.each do |file| 33 | out << file.path 34 | out << "\n\tsha(r) " + file.sha_repo.to_s + ' ' + file.mode_repo.to_s 35 | out << "\n\tsha(i) " + file.sha_index.to_s + ' ' + file.mode_index.to_s 36 | out << "\n\ttype " + file.type.to_s 37 | out << "\n\tstage " + file.stage.to_s 38 | out << "\n\tuntrac " + file.untracked.to_s 39 | out << "\n" 40 | end 41 | out << "\n" 42 | out 43 | end 44 | 45 | # enumerable method 46 | 47 | def [](file) 48 | @files[file] 49 | end 50 | 51 | def each 52 | @files.each do |k, file| 53 | yield file 54 | end 55 | end 56 | 57 | class StatusFile 58 | attr_accessor :path, :type, :stage, :untracked 59 | attr_accessor :mode_index, :mode_repo 60 | attr_accessor :sha_index, :sha_repo 61 | 62 | @base = nil 63 | 64 | def initialize(base, hash) 65 | @base = base 66 | @path = hash[:path] 67 | @type = hash[:type] 68 | @stage = hash[:stage] 69 | @mode_index = hash[:mode_index] 70 | @mode_repo = hash[:mode_repo] 71 | @sha_index = hash[:sha_index] 72 | @sha_repo = hash[:sha_repo] 73 | @untracked = hash[:untracked] 74 | end 75 | 76 | def blob(type = :index) 77 | if type == :repo 78 | @base.object(@sha_repo) 79 | else 80 | @base.object(@sha_index) rescue @base.object(@sha_repo) 81 | end 82 | end 83 | 84 | end 85 | 86 | private 87 | 88 | def construct_status 89 | @files = ls_files 90 | 91 | Dir.chdir(@base.working_dir) do 92 | # find untracked in working dir 93 | Dir.glob('**/*') do |file| 94 | if !@files[file] 95 | @files[file] = {:path => file, :untracked => true} if !File.directory?(file) 96 | end 97 | end 98 | 99 | # find modified in tree 100 | diff_files.each do |path, data| 101 | @files[path] ? @files[path].merge!(data) : @files[path] = data 102 | end 103 | 104 | # find added but not committed - new files 105 | diff_index('HEAD').each do |path, data| 106 | @files[path] ? @files[path].merge!(data) : @files[path] = data 107 | end 108 | 109 | @files.each do |k, file_hash| 110 | @files[k] = StatusFile.new(@base, file_hash) 111 | end 112 | end 113 | end 114 | 115 | # compares the index and the working directory 116 | def diff_files 117 | hsh = {} 118 | @base.git.diff_files.split("\n").each do |line| 119 | (info, file) = line.split("\t") 120 | (mode_src, mode_dest, sha_src, sha_dest, type) = info.split 121 | hsh[file] = {:path => file, :mode_file => mode_src.to_s[1, 7], :mode_index => mode_dest, 122 | :sha_file => sha_src, :sha_index => sha_dest, :type => type} 123 | end 124 | hsh 125 | end 126 | 127 | # compares the index and the repository 128 | def diff_index(treeish) 129 | hsh = {} 130 | @base.git.diff_index({}, treeish).split("\n").each do |line| 131 | (info, file) = line.split("\t") 132 | (mode_src, mode_dest, sha_src, sha_dest, type) = info.split 133 | hsh[file] = {:path => file, :mode_repo => mode_src.to_s[1, 7], :mode_index => mode_dest, 134 | :sha_repo => sha_src, :sha_index => sha_dest, :type => type} 135 | end 136 | hsh 137 | end 138 | 139 | def ls_files 140 | hsh = {} 141 | lines = @base.git.ls_files({:stage => true}) 142 | lines.split("\n").each do |line| 143 | (info, file) = line.split("\t") 144 | (mode, sha, stage) = info.split 145 | hsh[file] = {:path => file, :mode_index => mode, :sha_index => sha, :stage => stage} 146 | end 147 | hsh 148 | end 149 | end 150 | 151 | end -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/grit/lib/grit/git-ruby/internal/loose.rb: -------------------------------------------------------------------------------- 1 | # 2 | # converted from the gitrb project 3 | # 4 | # authors: 5 | # Matthias Lederhofer 6 | # Simon 'corecode' Schubert 7 | # Scott Chacon 8 | # 9 | # provides native ruby access to git objects and pack files 10 | # 11 | 12 | require 'zlib' 13 | require 'digest/sha1' 14 | require 'grit/git-ruby/internal/raw_object' 15 | 16 | module Grit 17 | module GitRuby 18 | module Internal 19 | class LooseObjectError < StandardError 20 | end 21 | 22 | class LooseStorage 23 | def initialize(directory) 24 | @directory = directory 25 | end 26 | 27 | def [](sha1) 28 | sha1 = sha1.unpack("H*")[0] 29 | begin 30 | return nil unless sha1[0...2] && sha1[2..39] 31 | path = @directory + '/' + sha1[0...2] + '/' + sha1[2..39] 32 | get_raw_object(File.read(path)) 33 | rescue Errno::ENOENT 34 | nil 35 | end 36 | end 37 | 38 | def get_raw_object(buf) 39 | if buf.length < 2 40 | raise LooseObjectError, "object file too small" 41 | end 42 | 43 | if legacy_loose_object?(buf) 44 | content = Zlib::Inflate.inflate(buf) 45 | header, content = content.split(/\0/, 2) 46 | if !header || !content 47 | raise LooseObjectError, "invalid object header" 48 | end 49 | type, size = header.split(/ /, 2) 50 | if !%w(blob tree commit tag).include?(type) || size !~ /^\d+$/ 51 | raise LooseObjectError, "invalid object header" 52 | end 53 | type = type.to_sym 54 | size = size.to_i 55 | else 56 | type, size, used = unpack_object_header_gently(buf) 57 | content = Zlib::Inflate.inflate(buf[used..-1]) 58 | end 59 | raise LooseObjectError, "size mismatch" if content.length != size 60 | return RawObject.new(type, content) 61 | end 62 | 63 | # currently, I'm using the legacy format because it's easier to do 64 | # this function takes content and a type and writes out the loose object and returns a sha 65 | def put_raw_object(content, type) 66 | size = content.length.to_s 67 | LooseStorage.verify_header(type, size) 68 | 69 | header = "#{type} #{size}\0" 70 | store = header + content 71 | 72 | sha1 = Digest::SHA1.hexdigest(store) 73 | path = @directory+'/'+sha1[0...2]+'/'+sha1[2..40] 74 | 75 | if !File.exists?(path) 76 | content = Zlib::Deflate.deflate(store) 77 | 78 | FileUtils.mkdir_p(@directory+'/'+sha1[0...2]) 79 | File.open(path, 'wb') do |f| 80 | f.write content 81 | end 82 | end 83 | return sha1 84 | end 85 | 86 | # simply figure out the sha 87 | def self.calculate_sha(content, type) 88 | size = content.length.to_s 89 | verify_header(type, size) 90 | header = "#{type} #{size}\0" 91 | store = header + content 92 | 93 | Digest::SHA1.hexdigest(store) 94 | end 95 | 96 | def self.verify_header(type, size) 97 | if !%w(blob tree commit tag).include?(type) || size !~ /^\d+$/ 98 | raise LooseObjectError, "invalid object header" 99 | end 100 | end 101 | 102 | # private 103 | def unpack_object_header_gently(buf) 104 | used = 0 105 | c = buf.getord(used) 106 | used += 1 107 | 108 | type = (c >> 4) & 7; 109 | size = c & 15; 110 | shift = 4; 111 | while c & 0x80 != 0 112 | if buf.length <= used 113 | raise LooseObjectError, "object file too short" 114 | end 115 | c = buf.getord(used) 116 | used += 1 117 | 118 | size += (c & 0x7f) << shift 119 | shift += 7 120 | end 121 | type = OBJ_TYPES[type] 122 | if ![:blob, :tree, :commit, :tag].include?(type) 123 | raise LooseObjectError, "invalid loose object type" 124 | end 125 | return [type, size, used] 126 | end 127 | private :unpack_object_header_gently 128 | 129 | def legacy_loose_object?(buf) 130 | word = (buf.getord(0) << 8) + buf.getord(1) 131 | buf.getord(0) == 0x78 && word % 31 == 0 132 | end 133 | private :legacy_loose_object? 134 | end 135 | end 136 | end 137 | end 138 | -------------------------------------------------------------------------------- /features/step_definitions/watircuke_steps.rb: -------------------------------------------------------------------------------- 1 | Given /I load "(.*)" fixture/ do |table| 2 | @table.merge! YAML.load_file("features/fixtures/#{table}.yml") 3 | end 4 | 5 | Transform /^\:\w*\.\w*$/ do |step_arg| 6 | what = parse_from_yaml(step_arg) if fixture?(step_arg) 7 | end 8 | 9 | Given /I click the "(.*)" button(.*)/ do |what, what2| 10 | if what2 == " with alert" 11 | click_alert_button_ok 12 | elsif what2 =~ /with index \d+/ 13 | index = what2.gsub(" with index ","") 14 | @browser.button(:id => what, :index => index.to_i).click 15 | else 16 | find_button(what) 17 | end 18 | end 19 | 20 | 21 | Given /I click the "(.*)" checkbox/ do |what| 22 | find_checkbox(what) 23 | end 24 | 25 | Given /I click the "(.*)" div/ do |what| 26 | find_div(what) 27 | end 28 | 29 | Given /I click the "(.*)" image/ do |what| 30 | find_image(what) 31 | end 32 | 33 | Given /I click the "(.*)" link(.*)/ do |what, what2| 34 | if what2 == " with alert" 35 | click_alert_button_ok 36 | find_link(what) 37 | elsif what2 =~ /with index \d+/ 38 | index = what2.gsub(" with index ","") 39 | if @browser.link(:text => what, :index => index.to_i).exists? 40 | @browser.link(:text => what, :index => index.to_i).click 41 | elsif @browser.link(:class => what, :index => index.to_i).exists? 42 | @browser.link(:class => what, :index => index.to_i).click 43 | end 44 | else 45 | find_link(what) 46 | end 47 | end 48 | 49 | Given /I onmouseover the "(.*)" link$/ do |what| 50 | @browser.link(:text, /#{what}/).exists? 51 | @browser.link(:text, /#{what}/).fire_event('onmouseover') 52 | end 53 | 54 | Given /I click the "(.*)" radio button/ do |what| 55 | find_radio_button(what) 56 | end 57 | 58 | Given /I click row "(.*)" in the "(.*)" table/ do |row, column, what| 59 | find_table(row, column, what) 60 | end 61 | 62 | Given /I select "(.*)" from "(.*)"/ do |with, what| 63 | find_select_list(with, what) 64 | end 65 | 66 | Given /I fill in the text field "(.*)" with "(.*)"/ do |tf_name, what| 67 | find_text_field(tf_name, what) 68 | end 69 | 70 | Given /I fill in the date field "(.*)" with "(.*)"/ do |tf_name, what| 71 | find_text_field(tf_name, calculate_date(what)) 72 | end 73 | 74 | Given /I click the "(.*)" element/ do |what| 75 | find_element(what) 76 | end 77 | 78 | 79 | Given /I fill in the file field "(.*)" with "(.*)"/ do |ff_name, what| 80 | find_file_field(ff_name, what) 81 | end 82 | 83 | Then /I refresh the page/ do 84 | @browser.refresh 85 | end 86 | 87 | Then /I should see the "(.*)" image/ do |what| 88 | assert(@browser.image(:src, /what/).height.to_i == 0) ? false : true 89 | end 90 | 91 | Then /I take a screenshot/ do 92 | t = Time.new.to_i 93 | create_screenshot(ENV['DEF_TEST'] || ENV['CMD']) 94 | end 95 | 96 | Then /I should see the span "(.*)" with "(.*)"/ do |span, what| 97 | find_span(span, what) 98 | end 99 | 100 | Then /^I should (NOT )?see the text "(.*)"$/ do |visibility, what| 101 | expected = (visibility.to_s.strip == 'NOT') ? @browser.text.include?(what.strip).should == false : @browser.text.include?(what.strip).should == true 102 | end 103 | 104 | Then /^I should (NOT )?contain the html "([^\"]*)"$/ do |visibility, what| 105 | expected = (visibility.to_s.strip == 'NOT') ? @browser.html.index(what).should == nil : @browser.html.index(what).should >= 0 106 | end 107 | 108 | Then /I click the "(.*)" link until I see the text "(.*)"/ do |click_link, what_to_see| 109 | find_link(click_link) 110 | while !@browser.text.index(what_to_see) do 111 | @browser.back 112 | sleep 5 113 | find_link(click_link) 114 | end 115 | @browser.text.index(what_to_see) != nil 116 | end 117 | 118 | Then /^I debug$/ do 119 | debugger 120 | end 121 | 122 | Given /I am redirected to "(.*)"/ do |what| 123 | url = @browser.url 124 | assert_equal(@environment + what, url) 125 | end 126 | 127 | Given /^I am on the "(.+)" page$/ do |page_name| 128 | @browser.goto(path_to(page_name)) #This step links up with the "path_to" method found in support/paths.rb 129 | end 130 | 131 | Given /^I go to "([^\"]*)"$/ do |url| 132 | @browser.goto(url) #Links to generic urls like "google.com" 133 | end 134 | 135 | Given /^I sleep for "([^\"]*)"$/ do |seconds| 136 | sleep seconds.to_i 137 | end 138 | Given /^I check all objects$/ do 139 | create_output 140 | end 141 | 142 | Then /^I sleep for (\d*) until I (NOT )?see the text "(.*)"/ do |seconds, visibility, what| 143 | 144 | visibility.to_s.strip == 'NOT' ? 145 | !(1.upto(seconds.to_i).each { |s| @browser.text[what.strip].nil? ? break : sleep(1) }) : 146 | !(1.upto(seconds.to_i).each { |s| @browser.text[what.strip] ? break : sleep(1) }) 147 | end 148 | 149 | Then /^I go back$/ do 150 | @browser.back 151 | end 152 | 153 | -------------------------------------------------------------------------------- /vendor/plugins/cucumber_fm/lib/cucumber_feature_manager.rb: -------------------------------------------------------------------------------- 1 | require 'cucumber_f_m/feature_element/component/tags' 2 | require 'cucumber_f_m/feature_element/component/title' 3 | require 'cucumber_f_m/feature_element/component/comments' 4 | require 'cucumber_f_m/feature_element/component/total_estimation' 5 | 6 | require 'cucumber_f_m/comment_module/comment' 7 | 8 | require 'cucumber_f_m/feature_element/info' 9 | require 'cucumber_f_m/feature_element/comment' 10 | require 'cucumber_f_m/feature_element/narrative' 11 | require 'cucumber_f_m/feature_element/background' 12 | require 'cucumber_f_m/feature_element/scenario' 13 | require 'cucumber_f_m/feature_element/scenario_outline' 14 | require 'cucumber_f_m/feature_element/example' 15 | require 'cucumber_f_m/feature_element/step' 16 | 17 | require 'cucumber_f_m/feature' 18 | require 'cucumber_f_m/tag_filter' 19 | require 'cucumber_f_m/config' 20 | require 'cucumber_f_m/aggregator' 21 | require 'cucumber_f_m/statistic' 22 | 23 | require 'cucumber_f_m/cvs/git' 24 | require 'grit/lib/grit' 25 | 26 | require 'base64' 27 | 28 | # TODO refactor, use repo full_path and feature not full path 29 | class CucumberFeatureManager < Struct.new(:path, :repo_path, :config_parameters) 30 | 31 | include Grit 32 | include CucumberFM::FeatureElement::Component::TotalEstimation 33 | 34 | attr_reader :info 35 | 36 | def features 37 | @features ||= scan_features 38 | end 39 | 40 | def scenarios 41 | (features.collect { |feature| feature.scenarios }).flatten 42 | end 43 | 44 | def config 45 | @config ||= CucumberFM::Config.new((config_parameters || {})) 46 | end 47 | 48 | def filter 49 | @filter ||= CucumberFM::TagFilter.new(config.tags) 50 | end 51 | 52 | def aggregate 53 | unless patterns_for_aggregator.empty? 54 | @raport ||= CucumberFM::Aggregator.new(self, patterns_for_aggregator).collection 55 | end 56 | end 57 | 58 | def prefix 59 | config.dir.empty? ? path : File.join(path, config.dir) 60 | end 61 | 62 | def commit_change_on(feature) 63 | # use info to notify user 64 | # @info = 'aaaa' 65 | add_to_index(feature) 66 | repo.commit_index("spec-update: #{feature.filename}") 67 | end 68 | 69 | def remove_file_from_repo(relative_path) 70 | `cd #{repo_path} && git rm #{relative_path}` 71 | end 72 | 73 | def send_to_remote 74 | push_to_remote 75 | end 76 | 77 | private 78 | 79 | def add_to_index(feature) 80 | # WTF - why this is not works 81 | # repo.add(feature.path) 82 | `cd #{repo_path} && git add #{feature.path}` 83 | end 84 | 85 | # TODO cleanup 86 | def push_to_remote 87 | # WTF - why this is not works 88 | # git.push({}, repo_remote_name, "#{repo_current_branch}:#{repo_remote_branch_name}") 89 | if capistrano_branch_name 90 | `cd #{repo_path} && git push #{repo_remote_name} #{repo_current_branch}:#{capistrano_branch_name}` 91 | elsif last_stories_branch_name 92 | begin 93 | response = `cd #{repo_path} && git push #{repo_remote_name} #{repo_current_branch}:#{last_stories_branch_name}` 94 | throw :not_fast_forward if response =~ /non\-fast\-forward/ 95 | rescue => e 96 | `cd #{repo_path} && git push #{repo_remote_name} #{repo_current_branch}:#{new_branch_name}` 97 | end 98 | else 99 | `cd #{repo_path} && git push #{repo_remote_name} #{repo_current_branch}:#{new_branch_name}` 100 | end 101 | end 102 | 103 | def scan_features 104 | all_features.collect { |feature| feature if filter.pass?(feature.tags_all)}.compact 105 | end 106 | 107 | def all_features 108 | @all_features ||= scan_all_features 109 | end 110 | 111 | def scan_all_features 112 | features = [] 113 | Dir.glob("#{prefix}/**/*.feature").each do |full_path| 114 | feature = CucumberFM::Feature.new(full_path, self) 115 | features.push(feature) 116 | end 117 | features 118 | end 119 | 120 | def repo_relative_path(path) 121 | path.gsub(repo_path, '').gsub(/^\//, '') 122 | end 123 | 124 | def repo 125 | @repo ||= Repo.new(repo_path) 126 | end 127 | 128 | def git 129 | repo.git 130 | end 131 | 132 | def repo_current_branch 133 | repo.head.name 134 | end 135 | 136 | def repo_remote_name 137 | repo.remote_list.first 138 | end 139 | 140 | def last_stories_branch_name 141 | repo.remotes.map(& :name).collect { |name| /stories_\d+/.match(name) }.compact.map(& :to_s).sort.last 142 | end 143 | 144 | def capistrano_branch_name 145 | "stories_#{timestamp_capistrano}" if timestamp_capistrano 146 | end 147 | 148 | def timestamp_capistrano 149 | pattern = /\d{14}$/ 150 | if defined?(Rails) 151 | pattern.match(Rails.root.to_s) 152 | end 153 | end 154 | 155 | def new_branch_name 156 | "stories_#{Time.now.strftime('%Y%m%d%H%M%S')}" 157 | end 158 | 159 | def patterns_for_aggregator 160 | config.aggregate.map { |label| 161 | CucumberFM::FeatureElement::Component::Tags::PATTERN[label.to_sym] unless label.blank? 162 | }.compact 163 | end 164 | end --------------------------------------------------------------------------------